HTML ngữ nghĩa

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

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

Chuỗi mã này chưa đề cập đến nhiều phần tử HTML, nhưng ngay cả khi không biết về HTML, hai đ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ố từ thay vì ipsum lorem để lưu một số thao tác cuộn. Hãy sử dụng trí tưởng tượng của bạn để mở rộng "ba mươi 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</h2>
    <div>sixty-eight words</div>
    <div>forty-four words</div>
  </div>
</div>
<div>
   <span>five words</span>
</div>

Bạn có hiểu ý nghĩa của những từ đó 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>
    <h1>five words</h1>
  </header>
  <section>
    <h2>three words</h2>
    <p>forty-six words</p>
    <p>forty-four words</p>
  </section>
  <section>
    <h2>seven words</h2>
    <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 ý nghĩa? Nếu chỉ sử dụng các phần tử phi 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 thể hiện nội dung gì. Ví dụ thứ hai về mã, với các phần tử ngữ nghĩa, cung cấp đủ ngữ cảnh để người không phải mã hoá có thể giải mã mục đích và ý nghĩa mà không cần gặp thẻ HTML. Chắc chắn là trang đó cung cấp đủ ngữ cảnh để nhà phát triển hiểu được đường viền 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 mà không cần hiểu nội dung vì các phần tử ngữ nghĩa mang lại ý nghĩa và cấu trúc. Bạn có thể biết rằng tiêu đề đầu tiên là biểu ngữ của trang web, trong đó <h1> có thể là tên trang web. Chân trang là chân trang web: năm từ có thể là tuyên bố về bản quyền hoặc địa chỉ doanh nghiệp.

Mã đánh dấu ngữ nghĩa không chỉ giúp nhà phát triển dễ đọc mã đánh dấu, mà còn giúp các công cụ tự động dễ dàng giải mã mã đánh dấu. Các công cụ cho nhà phát triển cũng minh hoạ cách các phần tử ngữ nghĩa tạo nên 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ẽ xây dựng mô hình đối tượng tài liệu (DOM) và mô hình đối tượng CSS (CSSOM). Sau đó, công cụ này cũng tạo 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à 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 điều khiển hỗ trợ tiếp cận của Firefox:

Danh sách các nút đều là đường liên kết hoặc lá văn bản.
Đoạn mã đầu tiên.
Danh sách các nút có các mốc rõ ràng.
Đoạn mã thứ hai.

Trong ảnh chụp màn hình thứ hai, có 4 vai trò điểm mốc trong khối mã thứ hai. Phương thức này sử dụng các mốc ngữ nghĩa được đặt tên thuận tiện là <header>, <main>, <footer><nav> cho mục đích "điều hướng". Địa danh cung cấp cấu trúc cho nội dung web và đảm bảo các phần quan trọng của nội dung có thể dễ dàng điều hướng bằng bàn phím đối với người dùng trình đọc màn hình.

Lưu ý <header><footer> là các mốc có vai trò của bannercontentinfo tương ứng, khi chúng không được lồng trong các mốc khác. AOM của Chrome hiển thị đ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.
Đoạn mã đầu tiên.
Tất cả các nút văn bản đều có nội dung mô tả.
Đoạn mã thứ hai.

Trong công cụ cho nhà phát triển Chrome, bạn sẽ 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 không sử dụng.

Rõ ràng là việc sử dụng phần tử ngữ nghĩa giúp hỗ trợ tiếp cận, còn việc sử dụng các phần tử không phải ngữ nghĩa sẽ làm giảm khả năng hỗ trợ tiếp cận. HTML nói chung có thể truy cập theo mặc định. Công việc của chúng tôi với tư cách nhà phát triển là bảo vệ tính chất mặc định có thể truy cập của HTML và đảm bảo rằng chúng tôi tối đa hoá khả năng tiếp cận. Bạn có thể kiểm tra AOM trong công cụ 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 toàn cục (có nghĩa là thuộc tính này hợp lệ trên tất cả các phần tử) được xác định theo thông số kỹ thuật của ARIA chứ không phải theo thông số kỹ thuật HTML của WhatWG, trong đó hầu hết mọi nội dung khác trong loạt bài này đều được xác định.

Mỗi phần tử ngữ nghĩa đều có vai trò ngầm ẩn, một số phần tử tuỳ thuộc vào ngữ cảnh. Như chúng ta đã thấy trong ảnh chụp màn hình Công cụ dành cho nhà phát triển hỗ trợ tiếp cận của Firefox, cấp cao nhất <header>, <main>, <footer><nav> đều là các mốc, còn <header> 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ử sau: <main>main, <nav>navigation<footer>contentinfo. Khi <header> là tiêu đề của tài liệu, vai trò mặc định sẽ là banner. Vai trò này xác định mục này là tiêu đề toàn trang web. Khi <header> hoặc <footer> được lồng trong một phần tử phân mục, đó không phải là vai trò mốc. Ảnh chụp màn hình của cả hai 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ử rất quan trọng trong việc xây dựng AOM. Ngữ nghĩa của một phần tử hay "vai trò" rất quan trọng đối với các công nghệ hỗ trợ và trong một số trường hợp đối với các công cụ tìm kiếm. Người dùng công nghệ hỗ trợ dựa vào ngữ nghĩa để di chuyển và hiểu ý nghĩa của nội dung. Vai trò của phần tử này cho phép người dùng truy cập nhanh vào nội dung họ tìm kiếm và có thể quan trọng hơn là vai trò này thông báo cho người dùng trình đọc màn hình cách tương tác với một phần tử tương tác sau khi phần tử đó được đặt 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ự thẻ trên bàn phím, đồng thời tất cả đều có hỗ trợ mặc định theo dự kiến cho thao tác 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 về hoạt động tương tác mặc định của người dùng theo phần tử cụ thể.

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 ẩn là button. Với role="button", bạn có thể chuyển bất kỳ phần tử nào về mặt 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ẽ cho trình đọc màn hình biết rằng phần tử đó là một nút, nhưng điều 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 được tự động thêm vào trình tự sắp xếp thẻ của tài liệu, có nghĩa là phần tử này có thể làm tâm điểm theo mặc định bằng bàn phím. Cả hai phím Enter và Space đề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 đó. Sẽ dễ dàng hơn rất nhiều nếu bạn sử dụng <button>.

Quay lại ảnh chụp màn hình của AOM cho khối mã không có ngữ nghĩa. Bạn cần lưu ý rằng các phần tử phi ngữ nghĩa không có vai trò ngầm ẩn. Chúng ta có thể tạo ngữ nghĩa cho phiên bản phi ngữ nghĩa bằng cách chỉ định một vai trò cho mỗi 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ù thuộc tính role có thể dùng để thêm ngữ nghĩa cho 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à mình cần.

Phần tử ngữ nghĩa

Thông thường, bạn sẽ chọn được yếu tố phù hợp nhất cho công việc này nếu tự hỏi "Thành phần nào thể hiện đúng nhất chức năng của mục đánh dấu này?" 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 sử dụng HTML để định cấu trúc nội dung, chứ không phải để xác định hình thức của nội dung. Giao diện này chính là lĩnh vực của CSS. Mặc dù một số phần tử được xác định là xuất hiện theo một cách nhất định, nhưng đừng sử dụng phần tử dựa trên cách biểu định kiểu 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 chức năng và ý nghĩa ngữ nghĩa của phần tử đó. Việc lập trình HTML theo cách hợp lý, có ngữ nghĩa và có ý nghĩa giúp đảm bảo CSS được áp dụng như dự định.

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

Trong phần tiếp theo, bạn sẽ dùng các phần tử ngữ nghĩa để tạo cấu trúc tài liệu.

Kiểm tra kiến thức

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.