← HTML: cấu trúc & semantic

Bài 5 · Vận dụng · 22 phút

Semantic HTML là gì & vì sao cần

Biên soạn bởi Nguyễn Anh Tuấn

Thẻ ngữ nghĩa header/nav/main/article/section/aside/footer thay cho "div soup"; vì sao semantic tốt cho SEO, accessibility (screen reader) và CSS dễ nhắm.

Ở các bài trước, mèo con dùng đúng thẻ cho từng nội dung: tiêu đề là h1, đoạn văn là p, ảnh là img. Đó chính là tinh thần semantic (ngữ nghĩa): chọn thẻ theo ý nghĩa của nội dung, không theo dáng vẻ.

Phản ví dụ kinh điển là "div soup" - một trang mà gần như mọi thứ đều là <div>. Trên màn hình trông vẫn ổn, nhưng với máy thì cả trang là một mớ hộp giống hệt nhau: đâu là menu, đâu là nội dung chính - không tài nào biết được.

div soupsemantic<div><div><div><div><header><nav><main><footer>cùng bố cục, nhưng bên phải máy đọc được vai trò từng vùng
Cùng một bố cục: bên trái máy chỉ thấy các hộp vô danh; bên phải máy đọc được vai trò.
  • Semantic HTML = chọn thẻ theo VAI TRÒ/ý nghĩa của nội dung.
  • "div soup" là trang toàn div vô nghĩa - máy không hiểu cấu trúc.
  • Mắt người vẫn đọc được div soup; nhưng máy (Google, screen reader) thì không.

HTML có sẵn một bộ thẻ đặt tên cho các vùng lớn của trang. Mỗi thẻ tự khai báo vai trò của mình:

  • <header>: phần đầu - logo, tựa đề, đôi khi chứa nav.
  • <nav>: khu vực điều hướng (menu chính).
  • <main>: nội dung CHÍNH của trang - mỗi trang chỉ một main.
  • <article>: một mẩu nội dung độc lập (bài viết, sản phẩm, bình luận).
  • <section>: một phần có chủ đề riêng bên trong trang/bài.
  • <aside>: nội dung phụ bên lề (tin liên quan, quảng cáo).
  • <footer>: phần chân trang - bản quyền, liên hệ.
<header><nav><main><article><aside><footer>
Một bố cục quen thuộc: header, nav, main (chứa article và aside), footer.

bo-cuc.html · khung một trang bằng thẻ semantic (mở .html bằng trình duyệt)

<header>Logo Mèo Ham Học</header>
<nav>Trang chủ · Khoá học · Liên hệ</nav>
<main>
  <article>Nội dung chính của bài…</article>
  <aside>Bài liên quan…</aside>
</main>
<footer>© Mèo Ham Học</footer>

Hãy để ý: ngay cả khi chưa có một dòng CSS, chỉ đọc các thẻ là đã hình dung được bố cục trang. Bài kế sẽ ghép chúng thành một trang hoàn chỉnh.

Vậy có nên xoá sạch div? Không. Khi một khối nội dung không mang vai trò ngữ nghĩa nào - chỉ cần gom nhóm lại để CSS tạo kiểu hay JS xử lý - thì <div> (khối) và <span> (trong dòng) chính là công cụ đúng. Chúng "vô nghĩa" một cách có chủ ý.

div-span.html · dùng đúng chỗ: gom nhóm không mang nghĩa

<div class="the-gia">
  <span class="tien">39.000đ</span>
  <span class="giam">-10%</span>
</div>

Trung thực

Ranh giới đôi khi không tuyệt đối: vài chỗ có thể tranh luận nên dùng section hay div. Quy tắc kinh nghiệm: có thẻ semantic hợp nghĩa thì ưu tiên dùng; chỉ rơi về div/span khi thật sự không có vai trò ngữ nghĩa. Đừng vì lười mà quay lại div soup.

Vì sao đáng công chọn đúng thẻ, khi trang div soup nhìn vẫn y hệt? Vì semantic mang lại bốn lợi ích mà mắt thường không thấy ngay - trong đó lợi ích cho SEO & metadata và cho a11y: web cho mọi người đều sẽ được mổ xẻ kỹ ở bài riêng:

  • SEO: Google hiểu đâu là nội dung chính, xếp hạng trang tốt hơn.
  • Accessibility: screen reader cho người khiếm thị nhảy thẳng theo các "landmark" (header, nav, main, footer) như mục lục.
  • CSS dễ nhắm: viết kiểu theo tên thẻ (main, article…), gọn và rõ hơn là bám vào hàng tá class.
  • Dễ đọc - dễ bảo trì: người sau (và chính mèo con vài tháng sau) nhìn code là hiểu bố cục.

Cả bốn lợi ích đều âm thầm: không chọn semantic thì trang không "hỏng", chỉ là kém hơn ở những chỗ không nhìn thấy. Chính vì hậu quả vô hình mà người mới hay xem nhẹ - và cũng vì thế mà đây là bài trung tâm của khoá.

Quay lại sợi chỉ xuyên suốt khoá: cấu trúc đúng trước, đẹp sau. Bài này thêm một tầng nghĩa: "cấu trúc đúng" không chỉ là lồng thẻ hợp lệ, mà còn là chọn thẻ đúng vai trò để máy hiểu được. Một trang semantic tốt là một trang vừa dễ làm đẹp bằng CSS, vừa thân thiện với Google và người khiếm thị.

Bước tiếp theo

Giờ mèo con đã biết bộ thẻ semantic và vì sao chúng quan trọng. Bài kế ta ghép chúng lại thành một trang hoàn chỉnh, đúng thứ bậc - ở bài Cấu trúc một trang chuẩn semantic.

Câu hỏi thường gặp

"div soup" là cách gọi vui một trang mà gần như mọi thứ đều là thẻ <div>. Nhìn trên màn hình thì vẫn ổn, nhưng với MÁY (Google, screen reader) thì cả trang là một mớ hộp giống hệt nhau, không biết đâu là menu, đâu là nội dung chính. Semantic HTML là cách thoát khỏi mớ đó.

Không. div vẫn rất hữu ích KHI không có thẻ semantic nào hợp nghĩa - thường để gom nhóm phần tử lại cho dễ tạo kiểu bằng CSS hoặc xử lý bằng JS. Nguyên tắc: ưu tiên thẻ semantic khi có; chỉ rơi về div/span khi nội dung thật sự không mang vai trò ngữ nghĩa nào.

Cả hai đều "vô nghĩa" (không nói gì về nội dung), khác nhau ở cách chiếm chỗ. div là khối (block): chiếm trọn một dòng, dùng để gom các khối lớn. span là trong dòng (inline): nằm gọn giữa dòng chữ, dùng để bọc một đoạn ngắn trong câu (vd tô màu một từ bằng CSS).

article là một mẩu nội dung ĐỘC LẬP, tự nó đứng được nếu mang đi nơi khác (một bài viết, một sản phẩm, một bình luận). section là một PHẦN có chủ đề riêng bên trong trang/bài, thường có tiêu đề. Mẹo: nếu mang ra ngoài mà vẫn trọn nghĩa thì là article; nếu chỉ là một mục của cái lớn hơn thì là section.

Trang vẫn hiện bình thường - trình duyệt không "báo lỗi". Nhưng cái giá là vô hình: Google hiểu kém hơn, screen reader điều hướng sai, CSS khó nhắm và người sau đọc code mệt hơn. Vì hậu quả âm thầm nên người mới hay xem nhẹ; đó chính là lý do bài này nằm ở trung tâm khoá học.

Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.

Tick những điều em tự tin làm được sau khi học bài này. 0/6

Trả lời vài câu để chắc rằng em đã nắm bài.

Câu 1/3 Điểm: 0

"Semantic HTML" nghĩa là gì?

Bài tập về nhà

  1. 1

    Semantic trong một câu

    Bằng lời của mèo con, giải thích "semantic HTML" là gì trong 1-2 câu.

    ✅ Hoàn thành khi: Nêu được: chọn thẻ theo VAI TRÒ/ý nghĩa của nội dung, để máy (Google, screen reader) hiểu được trang.

  2. 2

    Gọi tên vùng

    Cho một trang có: thanh trên cùng chứa logo, một dải menu, phần nội dung chính, và dòng bản quyền cuối trang. Đặt mỗi vùng vào thẻ semantic phù hợp.

    ✅ Hoàn thành khi: header (logo) · nav (menu) · main (nội dung chính) · footer (bản quyền).

  3. 3

    article hay section?

    Chọn article hay section: (a) một bài blog hoàn chỉnh; (b) mục "Câu hỏi thường gặp" bên trong trang giới thiệu.

    ✅ Hoàn thành khi: (a) article (độc lập, mang đi vẫn trọn nghĩa); (b) section (một phần có chủ đề của trang).

  4. 4

    div hay thẻ semantic?

    Với mỗi chỗ, nên dùng div hay thẻ semantic: (a) khu vực điều hướng chính; (b) một nhóm 3 ô chỉ gom lại để CSS canh thành hàng.

    ✅ Hoàn thành khi: (a) nav (có nghĩa); (b) div (chỉ để CSS gom nhóm, không mang nghĩa).

  5. 5

    Bốn lợi ích

    Liệt kê bốn lợi ích của semantic HTML và mỗi cái một câu ngắn vì sao.

    ✅ Hoàn thành khi: SEO (Google hiểu trang) · accessibility (screen reader nhảy theo landmark) · CSS dễ nhắm (selector theo thẻ) · dễ đọc/bảo trì.

  6. 6

    Dọn div soup

    Cho <div class="top">…</div><div class="menu">…</div><div class="content">…</div>. Viết lại bằng thẻ semantic.

    ✅ Hoàn thành khi: Đổi thành <header>…</header><nav>…</nav><main>…</main> đúng vai trò.