Chuyển đến nội dung
MINH VO Ghi chép từ công việc
của một kỹ sư tại Việt Nam
Cơ bản9 phút đọc

Ngôn ngữ và hướng chữ cần được khai báo trong tài liệu

Khai báo ngôn ngữ và hướng chữ đúng, cô lập tên được chèn vào câu và kiểm tra dữ liệu tiếng Việt, tiếng Anh, tiếng Ả Rập mà không đảo chuỗi.

Các bố cục trình duyệt bằng giấy màu ô liu và be mô tả trang trên máy tính và trang hẹp trên điện thoại

Ngôn ngữ và hướng chữ trả lời hai câu hỏi khác nhau. Thẻ ngôn ngữ mô tả văn bản được viết bằng tiếng gì; hướng chữ xác lập hướng cơ sở để trình bày văn bản. Một giao diện tiếng Việt có thể chứa lời chào tiếng Anh và trích dẫn tiếng Ả Rập mà không cần đổi hướng của mọi điều khiển xung quanh.

Bài này dành cho người đã viết được một trang HTML nhỏ và muốn trang đó xử lý nội dung đa ngôn ngữ thực tế. Ta sẽ tách thông tin ngôn ngữ của tài liệu, hướng chữ cục bộ và giá trị do người dùng nhập, rồi kiểm tra dữ liệu biểu mẫu. Các thuộc tính này không dịch văn bản và cũng không suy ra ngôn ngữ một người muốn dùng từ tên của họ.

Mô tả đúng nội dung được xuất bản

Đặt ngôn ngữ chính trên phần tử html. Khai báo này bao phủ cả tiêu đề tài liệu lẫn phần thân, đồng thời được các phần tử con kế thừa nếu chúng không chỉ định ngôn ngữ khác. Vì vậy, đoạn văn không có thuộc tính lang riêng vẫn có thể có ngôn ngữ đã biết. Hướng dẫn khai báo ngôn ngữ của W3C khuyến nghị khai báo ở cấp tài liệu và thêm thuộc tính cục bộ quanh những đoạn viết bằng ngôn ngữ khác.

Thẻ ngôn ngữ tuân theo BCP 47. Dùng en cho tiếng Anh và vi cho tiếng Việt khi đó là mức phân biệt bạn biết chắc. Thẻ phụ chỉ vùng có ích khi mô tả đúng nội dung; vị trí của khách truy cập không chứng minh mọi câu đều dùng ngôn ngữ của vùng đó. Đừng đặt hai mã ngôn ngữ vào cùng một thuộc tính lang để mô tả đoạn văn pha trộn. Hãy đánh dấu các phần văn bản tương ứng.

Dưới đây là một tài liệu nhỏ hoàn chỉnh. Lời chào tiếng Anh có nghĩa là “Xin chào bạn đọc”; câu trích dẫn tiếng Ả Rập là ví dụ “Hello, world” quen thuộc. Đây đều là những đoạn do tác giả viết và biết rõ ngôn ngữ. Trường tên phía sau được chủ động xem là chưa biết ngôn ngữ.

<!doctype html>
<html lang="vi" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Ví dụ về ngôn ngữ và hướng chữ</title>
  </head>
  <body>
    <h1>Ghi chép kỹ thuật</h1>
    <p id="intro">Lời chào dành cho bạn đọc:</p>
    <p lang="en">Hello, readers.</p>
    <blockquote lang="ar" dir="rtl">
      <p>مرحبا بالعالم!</p>
    </blockquote>
    <p><bdi id="member-name" lang="">اسم المستخدم</bdi>: 3 bình luận</p>
    <form id="direction-demo">
      <label for="message">Lời nhắn một dòng</label>
      <input id="message" name="message" type="text"
        lang="" dir="auto" dirname="message.dir"
        value="مرحبا بالعالم">
    </form>
  </body>
</html>

Giá trị lang rỗng cho biết ngôn ngữ chưa xác định, thay vì kế thừa khai báo tiếng Việt xung quanh. Đây là ranh giới được chọn cho ví dụ tên và lời nhắn không giới hạn ngôn ngữ, không phải lời khuyên xóa thông tin ngôn ngữ của văn bản thông thường. Nếu ứng dụng biết ngôn ngữ của lời nhắn, hãy cung cấp thẻ đúng. MDN giải thích cả cơ chế kế thừa ngôn ngữ và giá trị rỗng.

Thẻ đúng có thể giúp phần mềm đọc chọn quy tắc phát âm và hỗ trợ những cách xử lý phụ thuộc ngôn ngữ khác. Nó không bảo đảm máy đã cài giọng đọc phù hợp, hay mọi cấu hình công nghệ hỗ trợ đều hoạt động giống nhau. Kiểm tra thuộc tính là một bước; nghe bằng trình đọc màn hình và các ngôn ngữ độc giả sử dụng là bước riêng.

Chỉ đổi hướng tại phần cần đổi

Tiếng Anh và tiếng Việt trong ví dụ đều được trình bày từ trái sang phải. Tiếng Ả Rập dùng hướng cơ sở từ phải sang trái, nên blockquote khai báo rtl còn phần còn lại của trang giữ ltr. Chỉ đặt lang=“ar” không làm đổi hướng. text-align: right cũng không thay thế được: căn lề dịch chuyển dòng trong hộp, còn hướng cơ sở giúp xác định cách sắp các đoạn chữ khác hướng, chữ số và dấu câu.

Hướng dẫn hướng chữ theo cấu trúc của W3C đặt thông tin này trong HTML. Nó vẫn tồn tại khi kiểu trình bày thay đổi. Nếu cả giao diện dùng tiếng Ả Rập, hãy đặt ngôn ngữ thích hợp và rtl trên tài liệu, rồi đánh dấu ngoại lệ tại từng phần. Mã phiên bản hoặc URL có thể cần ngữ cảnh từ trái sang phải riêng ngay trong giao diện đó.

Trang tiếng Việt có lời chào tiếng Anh từ trái sang phải, trích dẫn tiếng Ả Rập từ phải sang trái và tên chưa biết ngôn ngữ được cô lập riêngMở ảnh kích thước đầy đủ ↗

Các ranh giới lồng nhau mang thông tin khác nhau. Đổi ngôn ngữ cục bộ không tự đổi hướng chữ, và cô lập tên không xác định ngôn ngữ của tên đó.

Khoảng cách cũng có thể đi theo những ranh giới này. Quy tắc ngắt dòng còn giúp tiêu đề và tên dài vừa màn hình hẹp mà không đổi văn bản được lưu. Thêm CSS sau vào phần head của tài liệu, bên trong phần tử style:

body {
  overflow-wrap: anywhere;
}
blockquote {
  margin-inline: 0;
  padding-inline-start: 1rem;
  border-inline-start: 3px solid #74785b;
}
input {
  box-sizing: border-box;
  display: block;
  max-inline-size: 100%;
  font: inherit;
}

Với chế độ viết ngang của ví dụ, trích dẫn có khoảng đệm và đường viền bên phải. Đổi dir của nó sang ltr thì cả hai chuyển sang trái. Tài liệu padding-inline-start giải thích rằng cách ánh xạ này còn phụ thuộc chế độ viết. “Đầu trục nội tuyến” không phải tên cố định của bên trái hay bên phải. Dùng tọa độ vật lý khi thiết kế thực sự chỉ một cạnh vật lý cố định, chẳng hạn chú thích trỏ vào một phần cụ thể của hình ảnh.

Cô lập tên được chèn vào mà không viết lại chuỗi

Tên đứng cạnh dấu hai chấm và số đếm có thể làm thay đổi thứ tự dấu câu nếu các đoạn chữ của nó tham gia vào phép tính hướng của câu xung quanh. Phần tử bdi tạo ngữ cảnh cô lập cho tên được chèn. Hướng mặc định của nó là tự động, nên tên minh họa bằng chữ Ả Rập không đòi hỏi đổi cả đoạn tiếng Việt sang rtl.

Thay tên minh họa bằng cách chèn văn bản an toàn:

const memberName = document.querySelector('#member-name');
const suppliedName = 'Minh <reader>';
memberName.textContent = suppliedName;
console.log(memberName.textContent === suppliedName); // true

Các dấu ngoặc nhọn vẫn là ký tự văn bản; chúng không tạo phần tử reader. Tính an toàn ở đây đến từ textContent, không phải bdi. Cô lập là đặc tính trình bày, không phải thao tác làm sạch HTML, kiểm tra quyền truy cập hay biện pháp chống mọi mã định danh gây nhầm lẫn. Chính sách tên người dùng có yêu cầu bảo mật cần quy tắc riêng cho ký tự giống nhau về hình thức và ký tự điều khiển vô hình.

Cũng đừng đảo chuỗi để làm nó trông đúng. Văn bản tiếng Ả Rập được lưu theo thứ tự ký tự logic; trình duyệt tính cách hiển thị. JavaScript biểu diễn chuỗi bằng các đơn vị mã UTF-16. Đảo các đơn vị đó còn có thể tách đôi cặp surrogate, và ngay cả đảo theo điểm mã cũng có thể tách dấu kết hợp khỏi ký tự mà nó bổ nghĩa. Văn bản đa ngôn ngữ thông thường cần thông tin đúng và ranh giới trình bày phù hợp, không cần sửa thứ tự giá trị đã lưu.

Quan sát hướng tự động thực sự chọn gì

Hướng auto của ô nhập thay đổi theo nội dung. Trong những ví dụ đơn giản chỉ có một dòng này, ký tự có hướng mạnh đầu tiên quyết định hướng cơ sở. Chữ số và dấu hai chấm đứng trước chữ Ả Rập không gây tác động giống các chữ Latin ID. Chạy đoạn sau trong console sau khi tải tài liệu:

const form = document.querySelector('#direction-demo');
const message = document.querySelector('#message');
const original = message.value;
const samples = [
  'مرحبا بالعالم',
  'Xin chào bạn đọc',
  '2026: مرحبا بالعالم',
  'ID: مرحبا بالعالم'
];
const rows = samples.map(value => {
  message.value = value;
  const data = new FormData(form);
  return {
    value: data.get('message'),
    direction: data.get('message.dir'),
    unchanged: data.get('message') === value
  };
});
message.value = original;
console.table(rows);

Các hướng lần lượt là rtl, ltr, rtl và ltr; mọi giá trị unchanged đều là true. Thuộc tính dirname yêu cầu bước tạo dữ liệu biểu mẫu bổ sung một trường hướng chữ. Ở đây trường có tên message.dir. Nó mang hướng, không phải thẻ ngôn ngữ, còn giá trị ô nhập vẫn giữ nguyên các ký tự ban đầu.

Bốn giá trị một dòng tạo trường hướng rtl, ltr, rtl và ltr trong khi giữ nguyên từng giá trị, cho thấy vì sao tiền tố Latin làm đổi hướng tự độngMở ảnh kích thước đầy đủ ↗

Trường bổ sung giúp máy chủ giữ lại thông tin trình bày hữu ích. Tuy nhiên, nó vẫn là dữ liệu do phía khách gửi: chỉ chấp nhận những giá trị hướng được hỗ trợ nếu dùng lại về sau. Bài tập console này tạo dữ liệu tại chỗ; nó không gửi yêu cầu hay cài đặt điểm cuối lưu trữ. Thí nghiệm chỉ xét trường hợp ô nhập một dòng; điều khiển nhiều dòng có thêm hành vi theo từng đoạn mà ví dụ chưa bao quát.

Kiểm tra phần người đọc chọn và điều hướng được

Thử bốn mẫu, rồi tạm bỏ dir khỏi trích dẫn để so sánh dấu câu và đường viền ở phía đầu. Căn văn bản sang phải không khôi phục khai báo ngữ nghĩa đang thiếu. Thay tên bằng cả hai hệ chữ và kiểm tra dấu hai chấm cùng số đếm bên cạnh ở khung nhìn hẹp. Giữ tên trong vùng cô lập ngay cả khi tên thử hôm nay tình cờ là tiếng Anh.

Chọn và sao chép một câu có chữ khác hướng vào trình soạn thảo văn bản thuần, rồi xem thứ tự logic. So sánh giá trị ban đầu với văn bản được chọn; vị trí nhìn thấy không phải chỉ số đáng tin cậy vào chuỗi đã lưu. Kiểm tra thao tác sao chép và dán thực tế trong những môi trường được hỗ trợ, thay vì cho rằng đọc DOM thành công chứng minh hành vi bộ nhớ tạm ở mọi nơi.

Cuối cùng, đi qua trang bằng bàn phím và thử lại khi tăng cỡ chữ. Hướng chữ và bố cục CSS có thể đổi vị trí hiển thị của điều khiển mà không đổi thứ tự DOM. Thông tin ngôn ngữ, nét chữ dễ đọc, trình tự tiêu điểm dễ hiểu và dữ liệu nguyên vẹn đều cần được kiểm tra riêng.

Nguồn tham khảo & đọc thêm

  1. W3C Internationalization: structural direction
  2. W3C Internationalization: language declarations
  3. MDN: lang
  4. MDN: bdi
  5. MDN: dirname
  6. MDN: padding-inline-start
  7. MDN: JavaScript strings and Unicode
← Về trang bài viết

Hình minh họa

100%