HTML ngữ nghĩa

Với hơn 100 phần tử HTML và khả năng tạo các phần tử tuỳ chỉnh, bạn có vô số cách để đánh dấu nội dung của mình. Tuy nhiên, một số cách (đặc biệt là về mặt ngữ nghĩa) sẽ hiệu quả hơn những cách khác.

Ngữ nghĩa có nghĩa là "liên quan đến ý nghĩa". Viết HTML có ngữ nghĩa nghĩa là sử dụng các phần tử HTML để cấu trúc nội dung dựa trên ý nghĩa của từng phần tử, chứ không phải dựa trên hình thức của phần tử đó.

Loạt bài này chưa đề cập đến nhiều phần tử HTML, nhưng ngay cả khi bạn không biết HTML, 2 đoạn mã sau đây cho thấy cách đánh dấu ngữ nghĩa có thể cung cấp ngữ cảnh nội dung. Cả hai đều sử dụng số lượng từ thay vì ipsum lorem để tiết kiệm thời gian cuộn. Hãy dùng trí tưởng tượng để mở rộng "30 từ" thành 30 từ:

Đoạn mã đầu tiên sử dụng <div><span>, hai phần tử không có giá trị ngữ nghĩa.

<div>
  <span>Three words</span>
  <div>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
  </div>
</div>
<div>
  <div>
    <div>five words</div>
  </div>
  <div>
    <div>three words</div>
    <div>forty-six words</div>
    <div>forty-four words</div>
  </div>
  <div>
    <div>seven words</div>
    <div>sixty-eight words</div>
    <div>forty-four words</div>
  </div>
</div>
<div>
   <span>five words</span>
</div>

Bạn có hình dung được những từ đó sẽ mở rộng đến đâu không? Thực ra là không.

Hãy viết lại mã này bằng các phần tử ngữ nghĩa:

<header>
  <h1>Three words</h1>
  <nav>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
  </nav>
</header>
<main>
  <header>
    <h2>five words</h2>
  </header>
  <section>
    <h2>three words</h2>
    <p>forty-six words</p>
    <p>forty-four words</p>
  </section>
  <section>
    <h3>seven words</h3>
    <p>sixty-eight words</p>
    <p>forty-four words</p>
  </section>
</main>
<footer>
  <p>five words</p>
</footer>

Khối mã nào truyền tải ý nghĩa? Chỉ sử dụng các phần tử không ngữ nghĩa của <div><span>, bạn thực sự không thể biết nội dung trong khối mã đầu tiên đại diện cho điều gì. Ví dụ về mã thứ hai, có các phần tử ngữ nghĩa, cung cấp đủ bối cảnh để người không phải là lập trình viên có thể giải mã mục đích và ý nghĩa mà không cần phải gặp thẻ HTML. Chắc chắn rằng thông tin này cung cấp đủ bối cảnh để nhà phát triển hiểu được bố cục của trang, ngay cả khi họ không hiểu nội dung, chẳng hạn như nội dung bằng tiếng nước ngoài.

Trong khối mã thứ hai, chúng ta có thể hiểu được cấu trúc ngay cả khi không hiểu nội dung vì các phần tử ngữ nghĩa cung cấp ý nghĩa và cấu trúc. Bạn có thể nhận thấy tiêu đề đầu tiên là biểu ngữ của trang web, trong đó <h1> có khả năng là tên trang web. Phần chân trang là phần chân trang của trang web: 5 từ này có thể là một tuyên bố về bản quyền hoặc địa chỉ doanh nghiệp.

Việc đánh dấu ngữ nghĩa không chỉ giúp nhà phát triển dễ đọc hơn mà còn quan trọng nhất trong việc giúp các công cụ tự động diễn giải việc đánh dấu. Các công cụ dành cho nhà phát triển cũng minh hoạ cách các phần tử ngữ nghĩa cung cấp cấu trúc mà máy có thể đọc được.

Mô hình đối tượng hỗ trợ tiếp cận (AOM)

Khi phân tích cú pháp nội dung nhận được, trình duyệt sẽ tạo mô hình đối tượng tài liệu (DOM) và mô hình đối tượng CSS (CSSOM). Sau đó, nó cũng tạo một cây hỗ trợ tiếp cận. Các thiết bị hỗ trợ, chẳng hạn như trình đọc màn hình, sử dụng AOM để phân tích cú pháp và diễn giải nội dung. DOM là một cây gồm tất cả các nút trong tài liệu. AOM giống như một phiên bản ngữ nghĩa của DOM.

Hãy so sánh cách cả hai cấu trúc tài liệu này được hiển thị trong bảng hỗ trợ tiếp cận của Firefox:

Cây hỗ trợ tiếp cận DOM không có HTML ngữ nghĩa.
Hình 1. Danh sách các nút đều là đường liên kết hoặc văn bản.
Cây hỗ trợ tiếp cận DOM bằng HTML ngữ nghĩa.
Hình 2. Danh sách các nút có địa danh rõ ràng.

Trong hình 2, có 4 vai trò điểm mốc trong khối mã thứ hai. Thẻ này sử dụng các điểm mốc ngữ nghĩa được đặt tên thuận tiện là <header>, <main>, <footer><nav> cho "navigation" (điều hướng). Điểm mốc cung cấp cấu trúc cho nội dung trên web và giúp cho biết các phần nội dung quan trọng để người dùng trình đọc màn hình có thể dùng bàn phím để di chuyển.

<header><footer> là các điểm mốc, có vai trò lần lượt là bannercontentinfo khi chúng không được lồng trong các điểm mốc khác. AOM của Chrome cho thấy điều này như sau:

Tất cả các nút văn bản đều được liệt kê dưới dạng văn bản tĩnh.
Hình 3. Đoạn mã đầu tiên.
Tất cả các nút văn bản đều có nội dung mô tả.
Hình 4. Đoạn mã thứ hai.

Khi xem xét các công cụ cho nhà phát triển của Chrome, bạn sẽ nhận thấy sự khác biệt đáng kể giữa mô hình đối tượng hỗ trợ tiếp cận khi sử dụng các phần tử ngữ nghĩa so với khi bạn không sử dụng.

Rõ ràng là việc sử dụng phần tử ngữ nghĩa giúp cải thiện khả năng hỗ trợ tiếp cận, còn việc sử dụng phần tử không ngữ nghĩa sẽ làm giảm khả năng hỗ trợ tiếp cận. Nhìn chung, theo mặc định, HTML có thể truy cập được. Là nhà phát triển, công việc của chúng tôi là bảo vệ bản chất có thể truy cập mặc định của HTML và tối đa hoá khả năng tiếp cận cho người dùng. Bạn có thể kiểm tra AOM trong các công cụ dành cho nhà phát triển.

Thuộc tính role

Thuộc tính role mô tả vai trò của một phần tử trong ngữ cảnh của tài liệu. Thuộc tính role là một thuộc tính chung (tức là thuộc tính này hợp lệ trên tất cả các phần tử) do bản đặc tả ARIA xác định chứ không phải bản đặc tả HTML của WHATWG, nơi xác định hầu hết mọi thứ khác trong loạt bài này.

Mỗi phần tử ngữ nghĩa đều có một vai trò ngầm ẩn, một số vai trò phụ thuộc vào ngữ cảnh. Như chúng ta thấy trong ảnh chụp màn hình công cụ hỗ trợ tiếp cận của Firefox, <header>, <main>, <footer><nav> cấp cao nhất đều là các điểm mốc, trong khi <header> được lồng trong <main> là một phần. Ảnh chụp màn hình Chrome liệt kê vai trò ARIA của các phần tử này: <main>main, <nav>navigation<footer>contentinfo vì đây là chân trang của tài liệu. Khi <header> là tiêu đề của tài liệu, vai trò mặc định là banner, xác định phần này là tiêu đề trang web chung. Khi <header> hoặc <footer> được lồng trong một phần tử phân đoạn, thì đó không phải là vai trò điểm mốc. Cả hai ảnh chụp màn hình của công cụ dành cho nhà phát triển đều cho thấy điều này.

Tên vai trò của phần tử đóng vai trò quan trọng trong việc xây dựng AOM. Ngữ nghĩa của một phần tử hoặc "vai trò" là yếu tố quan trọng đối với các công nghệ hỗ trợ và trong một số trường hợp, cả công cụ tìm kiếm. Người dùng công nghệ hỗ trợ dựa vào ngữ nghĩa để điều hướng và hiểu ý nghĩa của nội dung. Vai trò của phần tử này giúp người dùng nhanh chóng truy cập vào nội dung mà họ muốn và có thể quan trọng hơn là vai trò này cho người dùng trình đọc màn hình biết cách tương tác với một phần tử tương tác sau khi phần tử đó được lấy tiêu điểm.

Các phần tử tương tác (chẳng hạn như nút, đường liên kết, dải ô và hộp đánh dấu) đều có vai trò ngầm ẩn, tất cả đều tự động được thêm vào trình tự phím tab và tất cả đều có chế độ hỗ trợ hành động mặc định dự kiến của người dùng. Vai trò ngầm ẩn hoặc giá trị role rõ ràng sẽ thông báo cho người dùng biết rằng họ có thể mong đợi các hoạt động tương tác mặc định dành riêng cho từng phần tử.

Khi sử dụng thuộc tính role, bạn có thể chỉ định vai trò cho bất kỳ phần tử nào, kể cả vai trò khác với vai trò mà thẻ ngụ ý. Ví dụ: <button> có vai trò ngầm định là button. Với role="button", bạn có thể chuyển đổi bất kỳ phần tử nào theo ngữ nghĩa thành một nút: <p role="button">Click Me</p>.

Mặc dù việc thêm role="button" vào một phần tử sẽ thông báo cho trình đọc màn hình rằng phần tử đó là một nút, nhưng việc này không làm thay đổi giao diện hoặc chức năng của phần tử. Phần tử button cung cấp rất nhiều tính năng mà bạn không cần làm gì cả. Phần tử button sẽ tự động được thêm vào trình tự sắp xếp thẻ của tài liệu, tức là theo mặc định, phần tử này có thể lấy tiêu điểm bằng bàn phím. Cả phím Enter và phím cách đều kích hoạt nút này. Các nút cũng có tất cả phương thức và thuộc tính do giao diện HTMLButtonElement cung cấp. Nếu không sử dụng nút ngữ nghĩa cho nút, bạn phải lập trình lại tất cả các tính năng đó. Bạn sẽ dễ dàng hơn nhiều khi sử dụng <button>.

Quay lại ảnh chụp màn hình của AOM cho khối mã không theo ngữ nghĩa. Ở đây, các phần tử không có ngữ nghĩa không có vai trò ngầm ẩn. Chúng ta có thể chuyển phiên bản không ngữ nghĩa thành phiên bản ngữ nghĩa bằng cách chỉ định vai trò cho từng phần tử:

<div role="banner">
  <span role="heading" aria-level="1">Three words</span>
  <div role="navigation">
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
  </div>
</div>

Mặc dù bạn có thể dùng thuộc tính role để thêm ngữ nghĩa vào bất kỳ phần tử nào, nhưng bạn nên dùng các phần tử có vai trò ngầm ẩn mà bạn cần.

Phần tử ngữ nghĩa

Nếu tự hỏi "Phần tử nào thể hiện rõ nhất chức năng của phần đánh dấu này?", thì có thể bạn sẽ chọn được phần tử phù hợp nhất. Phần tử bạn chọn và do đó, các thẻ bạn sử dụng phải phù hợp với nội dung bạn đang hiển thị, vì thẻ có ý nghĩa ngữ nghĩa.

Bạn nên dùng HTML để cấu trúc nội dung, chứ không phải để xác định giao diện của nội dung. Giao diện là phạm vi của CSS. Mặc dù một số phần tử được xác định để xuất hiện theo một cách nhất định, nhưng đừng sử dụng một phần tử dựa trên cách trang định kiểu của tác nhân người dùng làm cho phần tử đó xuất hiện theo mặc định. Thay vào đó, hãy chọn từng phần tử dựa trên ý nghĩa ngữ nghĩa và chức năng của phần tử đó. Việc lập trình HTML theo cách logic, ngữ nghĩa và có ý nghĩa sẽ giúp CSS được áp dụng như dự kiến.

Việc chọn đúng phần tử cho công việc khi bạn viết mã có nghĩa là bạn sẽ không phải tái cấu trúc hoặc nhận xét HTML của mình. Nếu bạn nghĩ đến việc sử dụng đúng nguyên tố cho công việc, thì bạn thường sẽ chọn đúng nguyên tố cho công việc đó. Khi hiểu được ngữ nghĩa của từng phần tử và nhận thức được lý do tại sao việc chọn đúng phần tử lại quan trọng, bạn có thể đưa ra lựa chọn phù hợp mà không cần tốn nhiều công sức.

Tiếp theo, hãy sử dụng các phần tử ngữ nghĩa để tạo cấu trúc tài liệu.

Kiểm tra mức độ hiểu biết của bạn

Kiểm tra kiến thức của bạn về HTML ngữ nghĩa.

Bạn phải luôn thêm role="button" vào phần tử <button>.

Sai.
Chính xác! Phần tử <button> đã có vai trò này.
Đúng.
Hãy thử lại.