Buổi 3: HTML (1): tài liệu, phần tử, thuộc tính, phần đầu
Bạn muốn làm một trang giới thiệu cho cửa hàng sách của lớp: có tiêu đề, vài đoạn mô tả, logo và một liên kết sang trang đặt hàng. Trình duyệt không "hiểu" ý định của bạn; nó chỉ hiểu mã đánh dấu mà bạn viết ra. Ngôn ngữ đánh dấu đó là HTML. Buổi này bạn sẽ học cách một tài liệu HTML được dựng nên từ các phần tử (element), cách thêm thông tin cho phần tử bằng thuộc tính (attribute), cách viết mã cho sạch và đúng chuẩn, cách khai báo phần đầu (head) của trang (tiêu đề, favicon, meta, base) và cách phân biệt hai họ phần tử khối và nội tuyến. Đây là nền móng cho mọi buổi HTML, CSS và JavaScript phía sau.
Mục tiêu buổi học
- Sau buổi này bạn có thể giải thích HTML là gì, mô tả cấu trúc cơ bản của một tài liệu HTML5 (
<!DOCTYPE html>,html,head,body) và tạo, mở, xem trước một tệp.html. - Sau buổi này bạn có thể phân biệt phần tử, thẻ mở, thẻ đóng, phần tử rỗng và viết được các phần tử lồng nhau đúng cú pháp.
- Sau buổi này bạn có thể khai báo và dùng thuộc tính (
href,src,alt,width,height,style,title,lang, thuộc tính boolean) đúng quy tắc về tên, dấu nháy và vị trí. - Sau buổi này bạn có thể áp dụng các quy ước viết mã HTML và kiểm tra tài liệu bằng công cụ W3C Validator.
- Sau buổi này bạn có thể viết phần
headđầy đủ:title, favicon bằnglink, các thẻmeta(charset,description,keywords,author,viewport) vàbase. - Sau buổi này bạn có thể phân biệt phần tử khối (block) với phần tử nội tuyến (inline) và dùng
div,spanđúng chỗ.
Bản đồ buổi học
| Phần | Nội dung | Thời lượng gợi ý |
|---|---|---|
| 1. Giới thiệu về ngôn ngữ HTML | Khái niệm HTML, cấu trúc tài liệu, chú thích, tạo và xem tài liệu | 25 phút |
| 2. Phần tử HTML | Phần tử là gì, thẻ mở/đóng, phần tử rỗng, lồng nhau, thuộc tính | 40 phút |
| 3. Quy ước khi viết mã HTML | 16 quy ước, kiểm tra mã bằng Validator | 20 phút |
| 4. Phần đầu (head) của tài liệu | Tiêu đề, ảnh biểu tượng, thẻ meta, đường dẫn cơ sở | 40 phút |
| 5. Phần tử khối và phần tử nội tuyến | Block, inline, div và span |
25 phút |
| Thực hành & ôn tập | Thực hành theo giáo trình, câu hỏi ôn tập, bài tập trên Codelab | 30 phút |
Khoảng một nửa thời gian của buổi là thực hành: sau mỗi phần lý thuyết bạn gõ, sửa và chạy thử mã ngay trong bài, rồi làm nhóm bài tập tương ứng trên Codelab.
1. Giới thiệu về ngôn ngữ HTML
Giáo trình: Chương 2 — mục "Giới thiệu về ngôn ngữ HTML" (Khái niệm về HTML; Chú thích trong HTML; Tạo tài liệu HTML).
1.1. Khái niệm về HTML
HTML (Hyper Text Markup Language) là ngôn ngữ đánh dấu siêu văn bản được dùng để mô tả các thành phần và nội dung của trang Web. Ngôn ngữ HTML được dùng để tạo ra tài liệu HTML. Chú ý: HTML là ngôn ngữ đánh dấu (markup), không phải ngôn ngữ lập trình; nó mô tả "đây là tiêu đề", "đây là đoạn văn", "đây là ảnh" chứ không tính toán gì cả.
Dưới đây là một tài liệu HTML đơn giản (ví dụ của giáo trình). Bạn bấm Chạy thử để thấy trang hiển thị, đồng thời bảng console in ra những gì trình duyệt "hiểu" về cấu trúc tài liệu:
<!DOCTYPE html>
<html>
<head>
<title>Tiêu đề tài liệu html</title>
</head>
<body>
<h1>Tiêu đề bài viết</h1>
<p>Nội dung bài viết</p>
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='60'%3E%3Crect width='120' height='60' fill='%23f59e0b'/%3E%3C/svg%3E" alt="Ảnh minh hoạ"/>
<script>
console.log("doctype:", document.doctype.name);
console.log("phần tử gốc:", document.documentElement.tagName);
console.log("tiêu đề tài liệu:", document.title);
console.log("con của body:", [...document.body.children].map(e => e.tagName).join(", "));
</script>
</body>
</html>Trong tài liệu trên (bản gốc của giáo trình dùng src="photo.jpg"; ở đây ta thay bằng một ảnh nhỏ nhúng sẵn để xem được ngay):
- Khai báo
<!DOCTYPE html>đánh dấu đây là một tài liệu HTML (cụ thể là HTML5). - Phần tử
<html>khai báo phần tử gốc. - Phần tử
<head>chứa các thông tin mô tả tài liệu HTML. - Phần tử
<title>khai báo tiêu đề của tài liệu HTML. - Phần tử
<body>chứa nội dung của tài liệu HTML, là phần sẽ hiển thị cho người dùng. - Phần tử
<h1>khai báo một tiêu đề (heading). - Phần tử
<p>định nghĩa một đoạn văn (paragraph). - Phần tử
<img>tạo ra một phần tử ảnh (image).
<!DOCTYPE html>Khai báo kiểu tài liệu: HTML5<html lang="vi">Phần tử gốc + thuộc tính lang<head>Phần đầu: thông tin về trang<meta charset="UTF-8">Phần tử rỗng: không có thẻ đóng<title>Trang đầu tiên</title>Tiêu đề hiện trên tab trình duyệt</head>Thẻ đóng của head<body>Phần thân: nội dung hiển thị<h1>Xin chào</h1>Thẻ mở + nội dung + thẻ đóng<img src="a.png" alt="Logo">Phần tử rỗng có 2 thuộc tính</body>Thẻ đóng của body</html>Thẻ đóng phần tử gốc<p title="Xin chào">
Đặt trong thẻ mở, tên viết chữ thường, giá trị trong dấu nháy.
<input type="checkbox" checked>
Chỉ cần ghi tên thuộc tính là bật.
<br> <img src="a.png">
Không có nội dung nên không cần thẻ đóng; các phần tử còn lại luôn phải đóng.
Tài liệu HTML là cây các phần tử lồng nhau: DOCTYPE, html, phần đầu head và phần thân body; mỗi phần tử gồm thẻ mở, thuộc tính, nội dung và thẻ đóng.
Hình trên chỉ ra từng "bộ phận" của tài liệu: khai báo DOCTYPE, phần tử gốc html, hai nhánh head và body, thẻ mở/đóng, thuộc tính và nội dung. Hãy đọc từ ngoài vào trong: html bao tất cả; bên trong có head (thông tin về trang) và body (nội dung nhìn thấy).
Một số điểm cần nhớ về cấu trúc này:
- Khai báo
<!DOCTYPE>chỉ xuất hiện một lần, ở đầu trang (trước bất kỳ phần tử HTML nào), giúp khai báo loại tài liệu. - Ngoài khai báo đó, toàn bộ các phần tử khác đều đặt trong phần tử
<html>. - Phần tử
<head>thường chứa các thẻ<meta>,<title>và<link>. Thẻ<meta>khai báo thông tin dữ liệu về tài liệu (siêu dữ liệu, metadata); thẻ<title>chứa tiêu đề; thẻ<link>khai báo liên kết tới tài nguyên khác như CSS hoặc ảnh favicon. - Phần tử
<head>nằm trong<html>và đặt trước<body>. - Phần tử
<body>chứa nội dung chính mà người dùng nhìn thấy. Bên trongbody, các phần tử như<header>,<nav>,<main>,<section>,<footer>phân chia và tổ chức nội dung hợp lý (buổi sau sẽ học kỹ nhóm phần tử ngữ nghĩa này). Cấu trúc đó giúp trang dễ hiểu, dễ duy trì và tối ưu cho công cụ tìm kiếm và nhiều thiết bị.
Lưu ý: Chỉ nội dung bên trong phần tử
<body>mới được hiển thị trên trình duyệt. Mọi thứ trong<head>là thông tin "ở hậu trường".
Ví dụ thực tế: Khi bạn mở một trang báo, thanh tab ghi tên bài viết (lấy từ
titletronghead), còn tiêu đề lớn, ảnh và đoạn văn bạn đọc là nội dung trongbody.
1.2. Chú thích trong HTML
Bạn có thể thêm chú thích (comment) vào mã nguồn HTML bằng cú pháp <!-- ... -->. Chú thích không được trình duyệt hiển thị nhưng giúp ghi lại ý đồ hoặc tạm vô hiệu hóa một đoạn mã.
<!-- Đây là một chú thích -->
<p>Đây là một đoạn văn.</p>
<!-- Nhớ bổ sung thêm thông tin ở đây -->Ba lưu ý của giáo trình:
- Có một dấu
!trong thẻ mở, nhưng không có trong thẻ đóng. - Chú thích có thể viết trên nhiều dòng.
- Chú thích không được hiển thị, nhưng giúp ghi lại và vô hiệu hóa mã nguồn HTML.
Hãy chạy thử để thấy chú thích "biến mất" khỏi trang nhưng vẫn nằm trong cây tài liệu:
<h2>Trang thử chú thích</h2>
<!-- Đây là một chú thích -->
<p>Đây là một đoạn văn.</p>
<!-- Nhớ bổ sung thêm thông tin ở đây -->
<!--
<p>Đoạn này bị vô hiệu hóa nên không hiển thị.</p>
-->
<script>
const cm = [];
const it = document.createNodeIterator(document.body, NodeFilter.SHOW_COMMENT);
let n;
while ((n = it.nextNode())) cm.push(n.nodeValue.trim().split("\n")[0]);
console.log("số chú thích:", cm.length);
console.log("số đoạn văn hiển thị:", document.querySelectorAll("p").length);
</script>Mẹo: Trong Visual Studio Code, chọn dòng mã rồi bấm Ctrl + / (macOS: Cmd + /) để bật/tắt chú thích nhanh. Đây là cách "tắt" tạm một phần tử để thử nghiệm.
Cảnh báo: Chú thích vẫn nằm trong mã nguồn mà bất kỳ ai cũng xem được (nhấn chuột phải → Xem nguồn trang). Đừng ghi mật khẩu, khóa API hay thông tin nội bộ trong chú thích.
1.3. Tạo tài liệu HTML
Tài liệu HTML được tạo ra theo hai cách: do kịch bản hoặc chương trình phía máy chủ sinh ra (Web động), hoặc do người thiết kế tạo sẵn và lưu ở máy chủ (Web tĩnh). Các tài liệu HTML có phần mở rộng là .html, được tạo bằng IDE hoặc Text Editor. Các công cụ này hỗ trợ nhiều thao tác khi soạn tệp: ví dụ để tạo nhanh khung một tài liệu HTML5 trong Visual Studio Code, bạn gõ doc rồi bấm phím Tab (nhiều bản VS Code cũng cho phép gõ ! rồi Tab).
Quy trình tối thiểu để tạo một tài liệu HTML trên máy của bạn:
- Tạo một thư mục cho dự án Web (ví dụ
trang-dau-tien). - Trong VS Code, tạo tệp mới và lưu với tên chữ thường, đuôi
.html(ví dụindex.html). - Gõ
doc+ Tab để sinh khung tài liệu, rồi viết nội dung trongbody. - Lưu tệp (Ctrl + S) và mở bằng trình duyệt để xem.
Để xem tài liệu HTML, bạn có thể dùng trình duyệt mở tệp. Với VS Code, bạn có thể thêm Extension để việc chạy tệp HTML dễ dàng hơn; ví dụ Live Preview giúp tạo nhanh một máy chủ nhỏ để xem trước tệp HTML. Công cụ này cho phép xem trước các thay đổi trong tệp HTML, CSS và JavaScript ngay trong môi trường soạn thảo mà không cần mở trình duyệt riêng, nhờ vậy tiết kiệm thời gian và đồng bộ công việc phát triển Web.
Giáo trình: Chương 2 — Hình 2-2 đến 2-4 minh họa việc tạo tệp HTML trong Visual Studio Code, cài đặt tiện ích "Live Preview" và xem trước Website bằng công cụ này. Các hình chụp màn hình không đưa vào bài giảng; bạn thực hiện trực tiếp trên máy theo các bước ở trên.
Mở rộng: Trong lớp này bạn còn có một "xưởng nhỏ" ngay trên Codelab: các khung Chạy thử trong bài và ô Tự thử trong slide cho phép gõ HTML và xem kết quả tức thì, không cần cài gì. Khi làm dự án lớn hơn, hãy chuyển sang VS Code + Live Preview như giáo trình hướng dẫn.
Hãy dùng "xưởng" dưới đây để thử ngay: sửa tiêu đề, thêm một đoạn văn rồi chạy lại.
(Chương trình không in gì.)
Chạy trong khung cách ly ngay trên trình duyệt của bạn; không có mạng.
Đây là trình soạn HTML/CSS/JavaScript trực tiếp. Gõ vào ô HTML, kết quả hiện ngay ở khung xem trước; bạn sẽ dùng nó ở mọi buổi trong khóa.
Bạn vừa học xong khái niệm tài liệu HTML, chú thích và cách tạo tệp; hãy làm hai bài đầu để tự dựng một trang có chú thích và một trang giới thiệu bản thân.
2. Phần tử HTML
Giáo trình: Chương 2 — mục "Phần tử HTML" (Phần tử HTML là gì?; Thẻ HTML; Thuộc tính HTML).
2.1. Phần tử HTML là gì?
Phần tử HTML (HTML element) là một loại thành phần của tài liệu HTML. Mỗi phần tử được tạo từ các thẻ HTML gồm: thẻ mở, thẻ đóng và các thuộc tính kèm theo. Phần tử cũng có thể có nội dung, gồm văn bản và các phần tử khác.
<p class="ghi-chu">Xin chào HTML</p>
└─┬─┘ └────┬────┘└──────┬──────┘└┬┘
thẻ mở thuộc tính nội dung thẻ đóng
└──────────────── phần tử ────────────────┘Hãy nhớ ba cách gọi, vì chúng hay bị lẫn: thẻ (tag) chỉ riêng <p> hoặc </p>; phần tử (element) là toàn bộ từ thẻ mở đến thẻ đóng, kể cả nội dung bên trong; thuộc tính (attribute) là cặp tên – giá trị nằm trong thẻ mở.
2.2. Thẻ HTML
Một phần tử HTML thường gồm thẻ mở và thẻ đóng, gọi chung là thẻ HTML, với nội dung chèn vào giữa: <tên thẻ> Nội dung ... </tên thẻ>. Thẻ đóng viết giống thẻ mở nhưng có dấu gạch chéo chèn trước tên thẻ. Phần tử HTML bao gồm toàn bộ nội dung tính từ thẻ mở đến thẻ đóng.
| Thẻ mở | Thẻ đóng |
|---|---|
<h1> |
</h1> |
<p> |
</p> |
<img> |
Không cần |
<br> |
Không cần |
Bảng 2-1. Ví dụ một số thẻ mở và thẻ đóng
HTML5 có một số phần tử chỉ cần khai báo thẻ mở mà không cần thẻ đóng. Các phần tử này không có nội dung và được gọi là phần tử rỗng (empty element); ví dụ <br> (ngắt dòng), <img> (ảnh), <hr> (đường kẻ ngang). HTML5 không yêu cầu đóng các phần tử rỗng, nhưng nếu muốn chặt chẽ hơn (hoặc để tài liệu đọc được bằng các trình phân tích cú pháp XML) thì nên đóng đúng cách, chẳng hạn <br />, <img ... />.
Các phần tử HTML có thể lồng nhau (phần tử này chứa phần tử khác). Mọi tài liệu HTML đều là các phần tử lồng nhau. Ví dụ sau chứa 5 phần tử HTML: html, body, h1 và hai p.
<!DOCTYPE html>
<html>
<body>
<h1>Tiêu đề bài viết</h1>
<p>Đoạn 1 bài viết</p>
<p>Đoạn 2 bài viết</p>
</body>
</html>
<script>
const all = document.querySelectorAll("*:not(script)");
console.log("số phần tử bạn viết:", all.length - 1, "(+1 là head do trình duyệt tự sinh)");
console.log("con trực tiếp của body:", [...document.body.children].map(e => e.tagName.toLowerCase()).join(", "));
console.log("nội dung h1:", document.querySelector("h1").textContent);
</script>Trong ví dụ trên: phần tử <html> định nghĩa toàn bộ tài liệu, có thẻ mở <html> và thẻ đóng </html>; phần tử body xác định phần thân, có thẻ mở <body> và thẻ đóng </body>; nội dung của body là ba phần tử khác (một h1 và hai p); h1 định nghĩa một tiêu đề với nội dung "Tiêu đề bài viết"; hai phần tử p là hai đoạn văn với nội dung "Đoạn 1 bài viết" và "Đoạn 2 bài viết".
Lưu ý: Nếu bạn đếm toàn bộ phần tử trong cây tài liệu, trình duyệt báo nhiều hơn 5 vì nó tự sinh thêm phần tử
headcòn thiếu. Đây là ví dụ cho thấy trình duyệt "sửa lỗi" giúp bạn, nhưng đừng dựa vào điều đó.
Cảnh báo: Đừng quên thẻ đóng. Trong hầu hết trường hợp trình duyệt vẫn hiển thị đúng dù bạn quên, nhưng cây tài liệu mà nó tự "đoán" có thể khác ý bạn, và lỗi chỉ lộ ra khi thêm CSS hoặc JavaScript.
Hãy xem trình duyệt tự "đoán" thế nào khi bạn lồng sai thứ tự thẻ:
<p><b>Đậm <i>và nghiêng</b> chỉ nghiêng?</i></p>
<script>
console.log("HTML trình duyệt dựng lại:");
console.log(document.querySelector("p").innerHTML);
</script>Quy tắc vàng: thẻ nào mở sau thì phải đóng trước (như dấu ngoặc lồng nhau). Mở b rồi i thì phải đóng i rồi mới đóng b.
2.3. Thuộc tính HTML
Thuộc tính (attribute) cung cấp thông tin khai báo bổ sung cho phần tử. Mỗi loại phần tử có thể có các thuộc tính khác nhau. Thuộc tính bắt buộc đặt trong thẻ mở, thường viết dưới dạng cặp tên = "giá trị".
Ví dụ, liên kết được định nghĩa bằng thẻ <a>; địa chỉ liên kết nằm trong thuộc tính href:
<a href="https://www.neu.edu.vn">Đến trang www.neu.edu.vn</a>Ảnh được định nghĩa bằng thẻ <img>:
<img src="logo.jpg" width="500" height="600" alt="Logo công ty">Trong ví dụ trên, thẻ <img> tạo ảnh; tên tệp nguồn ảnh chỉ định bằng thuộc tính src; kích thước ảnh chỉ định bằng width và height (width="500" nghĩa là rộng 500 pixel, height="600" là cao 600 pixel); thuộc tính alt là văn bản thay thế dùng khi ảnh không hiển thị được. Giá trị alt còn được trình đọc màn hình đọc lên, nhờ đó một người khiếm thị "nghe" được nội dung ảnh.
Hãy chạy thử để thấy alt hoạt động khi ảnh bị lỗi, và để đọc lại các thuộc tính bằng JavaScript:
<a href="https://www.neu.edu.vn">Đến trang www.neu.edu.vn</a>
<br>
<img id="anh" src="khong-co-anh.jpg" width="200" height="60" alt="Logo công ty">
<script>
const a = document.querySelector("a");
const img = document.getElementById("anh");
console.log("href =", a.getAttribute("href"));
console.log("src =", img.getAttribute("src"));
console.log("kích thước =", img.getAttribute("width") + " x " + img.getAttribute("height"));
console.log("alt =", img.getAttribute("alt"));
</script>Dấu nháy quanh giá trị
Các thuộc tính không bắt buộc đặt trong dấu ngoặc kép, trừ khi giá trị có khoảng trắng bên trong. Vì vậy thẻ <img> ở trên có thể viết:
<img src=flower.jpg width=500 height=600 alt="Bông hoa">Dấu nháy kép ("...") là phổ biến nhất, nhưng có thể dùng dấu nháy đơn ('...'). Khi bản thân giá trị chứa dấu nháy kép, hãy bọc bằng dấu nháy đơn, ví dụ title='Bấm vào "đây"'. Dù giáo trình cho phép bỏ nháy, nên luôn dùng nháy để mã nhất quán và ít lỗi.
Thuộc tính style, title và lang
Thuộc tính style xác định kiểu dáng của phần tử như màu, phông chữ, kích thước...:
<p style="color:red">Đây là một đoạn văn</p>Thuộc tính title gắn chú thích cho phần tử; giá trị này hiển thị dưới dạng chú thích khi di chuột qua (tooltip). Thuộc tính lang khai báo ngôn ngữ của tài liệu, đặt ở thẻ <html>:
<!DOCTYPE html>
<html lang="en-US">
<body>
<p title="Xin chào">Đây là một đoạn văn</p>
</body>
</html>Ngôn ngữ được khai báo bằng thuộc tính lang. Việc khai báo ngôn ngữ quan trọng đối với các ứng dụng hỗ trợ (ví dụ trình đọc màn hình) và công cụ tìm kiếm. Hai chữ cái đầu của lang chỉ ngôn ngữ (ví dụ en); nếu cần chỉ rõ biến thể theo quốc gia/vùng lãnh thổ thì thêm hai chữ cái nữa (ví dụ US). Với trang tiếng Việt, bạn dùng lang="vi".
<p style="color:red" title="Xin chào" id="p1">Rê chuột vào đoạn này để thấy chú thích.</p>
<script>
const p = document.getElementById("p1");
console.log("style =", p.getAttribute("style"));
console.log("title =", p.title);
console.log("màu chữ tính được:", p.style.color);
</script>Thuộc tính boolean
Một thuộc tính có thể có kiểu boolean, tức chỉ nhận một trong hai trạng thái (đúng – sai, bật – tắt). Để bật nó, chỉ cần khai báo tên thuộc tính, không cần giá trị. Ví dụ ô chọn có thuộc tính checked nghĩa là được chọn sẵn:
<input type="checkbox" name="mailList" checked><label><input type="checkbox" id="a" name="mailList" checked> Nhận bản tin</label><br>
<label><input type="checkbox" id="b" name="mailList"> Nhận khuyến mãi</label>
<script>
console.log("ô a checked =", document.getElementById("a").checked);
console.log("ô b checked =", document.getElementById("b").checked);
</script>Một số lưu ý khi khai báo thuộc tính
- HTML không yêu cầu tên thuộc tính viết chữ thường:
titlehayTITLEđều được; tuy nhiên hầu hết nên viết chữ thường để nhất quán. - Dấu nháy kép quanh giá trị là phổ biến nhất nhưng cũng dùng được dấu nháy đơn; khi giá trị chứa dấu nháy kép thì dùng nháy đơn bao ngoài.
- Thuộc tính luôn nằm trong thẻ mở, không bao giờ nằm ở thẻ đóng.
Mở rộng: Ngoài
style,title,lang, mọi phần tử còn dùng chung hai thuộc tính rất quan trọng cho CSS và JavaScript làid(định danh duy nhất trong trang) vàclass(tên nhóm, dùng chung cho nhiều phần tử). HTML5 còn cho phép thuộc tính tùy chỉnh dạngdata-*, ví dụdata-gia="150000", để gắn dữ liệu riêng vào phần tử. Bạn sẽ dùng chúng ở các buổi CSS và JavaScript.
<div id="sp-101" class="the-sp" data-id="101" data-gia="150000">
<p class="ten">Sách Thiết kế Web</p>
</div>
<script>
const d = document.getElementById("sp-101");
console.log("id =", d.id, "| class =", d.className);
console.log("data-id =", d.dataset.id, "| data-gia =", d.dataset.gia);
</script>Bạn vừa học xong phần tử, thẻ và thuộc tính; hãy làm các bài này để thành thạo img, id, class, data-* và thuộc tính của iframe.
3. Quy ước khi viết mã HTML
Giáo trình: Chương 2 — mục "Quy ước khi viết mã HTML" (Một số quy ước quan trọng; Kiểm tra mã HTML).
3.1. Một số quy ước quan trọng
Khi viết mã HTML, có một số quy ước cơ bản nên tuân thủ để mã hiển thị chính xác trên các trình duyệt Web và dễ bảo trì. Giáo trình nêu 16 quy ước; để dễ nhớ, bảng dưới đây gom chúng thành bốn nhóm.
| Nhóm | Quy ước |
|---|---|
| Tên thẻ & phong cách | Dùng tên thẻ bằng chữ thường; nhất quán một phong cách viết mã; dùng cú pháp gần với XHTML |
| Cấu trúc tài liệu | Luôn khai báo loại tài liệu bằng DOCTYPE ở dòng đầu tiên; đóng tất cả phần tử HTML; đóng cả phần tử rỗng; không bỏ các thẻ cơ bản html, body, head, title, meta |
| Thuộc tính & hình ảnh | Ảnh luôn khai báo đầy đủ alt; luôn xác định chiều rộng và chiều cao ảnh; luôn để một dấu cách trước và sau dấu = |
| Trình bày & tên tệp | Tránh dòng mã dài hơn 80 ký tự; không thêm dòng trống vô lý; tên tệp chữ thường; tệp HTML có đuôi .html hoặc .htm, CSS có đuôi .css, JavaScript có đuôi .js |
Ví dụ một mẩu mã vi phạm nhiều quy ước, và bản sửa theo giáo trình:
<!-- Chưa tốt -->
<P CLASS=ghichu>Chào bạn<BR>
<IMG SRC=anh.jpg><!-- Tốt hơn -->
<p class="ghichu">Chào bạn<br />
<img src="anh.jpg" width="200" height="100" alt="Ảnh minh họa" /></p>Một lý do thực tế để luôn khai báo width và height cho ảnh: trình duyệt dành sẵn chỗ cho ảnh trước khi tải xong, nên bố cục trang không bị giật khi ảnh hiện ra. Còn alt giúp trình đọc màn hình và công cụ tìm kiếm hiểu ảnh.
Lưu ý: Nhiều quy ước (chữ thường, dấu nháy, đóng phần tử rỗng) không làm trình duyệt báo lỗi nếu bạn vi phạm, nhưng chúng là thói quen chuyên nghiệp giúp nhóm cùng làm việc trên một mã nguồn mà không phải đoán ý nhau.
Mẹo: Tên tệp nên viết chữ thường, không dấu, không khoảng trắng, nối bằng dấu gạch ngang, ví dụ
gioi-thieu.html. Trên nhiều máy chủ,Index.HTMLvàindex.htmllà hai tệp khác nhau, và liên kết gõ sai chữ hoa/thường sẽ báo lỗi 404.
Để cảm nhận lợi ích của quy ước, hãy chạy một "máy kiểm tra mini" tự viết bằng JavaScript: nó đọc một mẩu HTML và báo những ảnh vi phạm quy ước về alt, width, height.
const mau = `
<img src="a.jpg" alt="Logo" width="100" height="50">
<img src="b.jpg" width="100" height="50">
<img src="c.jpg" alt="Banner">
`;
const doc = new DOMParser().parseFromString(mau, "text/html");
for (const img of doc.querySelectorAll("img")) {
const loi = [];
if (!img.hasAttribute("alt")) loi.push("thiếu alt");
if (!img.hasAttribute("width") || !img.hasAttribute("height")) loi.push("thiếu width/height");
console.log(img.getAttribute("src"), "→", loi.length ? loi.join(", ") : "đạt quy ước");
}Công cụ thật (như Validator ở mục sau) làm việc tương tự nhưng kiểm tra hàng trăm quy tắc.
3.2. Kiểm tra mã HTML
Kiểm tra mã (validation) HTML là quan trọng vì nó giúp đảm bảo trang Web hiển thị đúng trên mọi trình duyệt và thiết bị. Việc kiểm tra tìm ra các lỗi cú pháp, thiếu thẻ đóng hoặc sai định dạng — những lỗi có thể làm trang hiển thị sai, trông thiếu chuyên nghiệp hoặc không hiển thị đúng ở một số trình duyệt. Kiểm tra mã còn giúp xác định vấn đề bảo mật có thể gặp, và phát hiện nguyên nhân làm chậm quá trình tải trang, từ đó cải thiện tốc độ tải.
Để kiểm tra lỗi HTML, bạn dùng trang https://validator.w3.org (W3C Markup Validation Service). Công cụ này có thể kiểm tra ba dạng đầu vào:
- Một tài liệu HTML trên máy chủ (nhập địa chỉ URL);
- Một tệp tài liệu HTML (tải lên);
- Một đoạn mã HTML (dán trực tiếp).
Giáo trình: Chương 2 — Hình 2-6 và 2-7: giao diện Validator và ví dụ kết quả khi kiểm tra trang www.vncodelab.com (liệt kê các lỗi/cảnh báo kèm số dòng). Bạn nên tự thực hiện: dán một đoạn mã có lỗi vào Validator và đọc danh sách lỗi.
Các lỗi mà Validator thường báo cho người mới học: thiếu lang ở thẻ html, thiếu title trong head, thiếu alt ở ảnh, thẻ đóng không khớp, thuộc tính không hợp lệ với phần tử.
Ví dụ thực tế: Nhóm làm trang cho cửa hàng sách thường chạy Validator trước khi nộp bài. Một thẻ
<div>quên đóng ở chân trang có thể làm cả phần chân trang "trôi" lên giữa màn hình trên một số trình duyệt, nhưng trình duyệt ở máy bạn lại tự sửa nên bạn không thấy.
4. Phần đầu (head) của tài liệu
Giáo trình: Chương 2 — mục "Phần đầu (head) của tài liệu" (Tiêu đề; Ảnh biểu tượng; Các thẻ meta; Đường dẫn cơ sở).
Một tài liệu HTML có hai phần chính: phần đầu (head) và phần thân (body). Phần đầu chứa các thông tin về trang Web, còn phần thân chứa nội dung. Phần đầu nằm trong phần tử <head> và thường chứa:
- Tiêu đề của trang Web;
- Ảnh biểu tượng (xuất hiện bên cạnh tiêu đề);
- Siêu dữ liệu (metadata);
- Thông tin đường dẫn cơ sở.
4.1. Tiêu đề
Mỗi tài liệu HTML đều có một tiêu đề. Tiêu đề được trình duyệt hiển thị trên thẻ (tab) của trình duyệt và được tạo bằng thẻ title:
<head>
<title>My Shop</title>
</head>Tiêu đề thông thường là tên của Website hoặc tên tổ chức; tuy nhiên phổ biến nhất là dùng tiêu đề cho tên bài viết. Tiêu đề có ý nghĩa rất lớn với công cụ tìm kiếm (search engine) và xuất hiện trong kết quả tìm kiếm.
Trong khung xem trước dưới đây bạn không thấy tab, nhưng JavaScript đọc được tiêu đề qua document.title:
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>My Shop - Cửa hàng sách</title>
</head>
<body>
<h1>Chào mừng đến My Shop</h1>
<script>
console.log("tiêu đề tab:", document.title);
console.log("độ dài tiêu đề:", document.title.length, "ký tự");
</script>
</body>
</html>Mẹo: Tiêu đề trên kết quả tìm kiếm thường bị cắt sau khoảng 50–60 ký tự. Hãy đặt ý chính ở đầu và để mỗi trang có một tiêu đề riêng, đừng dùng chung một tiêu đề cho cả Website.
4.2. Ảnh biểu tượng
Biểu tượng của Website, còn gọi là favicon, là một hình nhỏ hiển thị ở góc trên bên trái cửa sổ hoặc thẻ (tab) của trình duyệt đang mở trang Web. Người dùng nhìn thấy nó như hình đại diện của Website; nó là dạng rút gọn của logo giúp phân biệt thương hiệu dễ dàng. Favicon thường được thiết kế ở nhiều kích thước, phổ biến là 16 × 16, 32 × 32 và 48 × 48 pixel.
Favicon được khai báo trong phần head bằng thẻ <link>:
<head>
<title>Tiêu đề trang Web</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>Các ảnh icon có thể tạo bằng công cụ như https://favicon.io, trong đó có hướng dẫn cấu hình để favicon hiển thị cả trên thiết bị di động như tab của điện thoại Android hoặc iOS. Các bước làm:
- Chọn nguồn để tạo favicon: từ ảnh, từ văn bản, hoặc từ biểu tượng emoji;
- Tạo favicon và tải các tệp favicon vào thư mục lưu trữ Website;
- Thêm các thẻ
<link>vào phần<head>của trang HTML.
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
<link rel="icon" type="image/png" sizes="512x512" href="/android-chrome-512x512.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/x-icon" href="/favicon.ico">Mỗi thẻ link mang ba thông tin chính: rel cho biết mối quan hệ (đây là icon hay apple-touch-icon), href là đường dẫn tới tệp ảnh, còn sizes và type mô tả kích thước và định dạng để trình duyệt chọn ảnh vừa nhất. Hãy chạy thử để đọc các thẻ link này bằng JavaScript (ảnh icon ở đây là một ô vuông SVG nhúng sẵn):
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Favicon thử nghiệm</title>
<link rel="icon" type="image/svg+xml" sizes="32x32" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Crect width='32' height='32' fill='%232563eb'/%3E%3C/svg%3E">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
</head>
<body>
<p>Nhìn lên thẻ tab: có favicon xanh nếu trình duyệt cho phép.</p>
<script>
for (const l of document.querySelectorAll("head link")) {
console.log("rel =", l.getAttribute("rel"), "| sizes =", l.getAttribute("sizes"), "| type =", l.getAttribute("type") || "(không khai báo)");
}
</script>
</body>
</html>Giáo trình: Chương 2 — Hình 2-9 và 2-10 (favicon trên tab của trình duyệt máy tính và trên Android). Bạn sẽ tự tạo favicon ở mục "Thực hành theo giáo trình" (Bài 2.3).
4.3. Các thẻ meta
Các thẻ meta khai báo trong head để mô tả thông tin về tài liệu, ví dụ: tác giả, từ khóa, khung nhìn... Ví dụ của giáo trình:
<head>
<meta charset="UTF-8">
<meta name="description" content="Thiết kế Website">
<meta name="keywords" content="HTML, CSS, JavaScript">
<meta name="author" content="Dương Minh">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>Ý nghĩa từng thẻ:
| Thẻ meta | Ý nghĩa |
|---|---|
charset="UTF-8" |
Tập ký tự mã hóa tài liệu. UTF-8 là bộ mã hóa Unicode rất phổ biến, tương thích ngược với ASCII. Thiếu khai báo này, tiếng Việt có thể bị lỗi hiển thị |
name="description" |
Mô tả ngắn về trang; công cụ tìm kiếm thường dùng làm đoạn tóm tắt dưới tiêu đề |
name="keywords" |
Bộ từ khóa của tài liệu (ví dụ HTML, CSS, JavaScript) |
name="author" |
Tác giả của tài liệu |
name="viewport" |
Khung nhìn: width=device-width cho trang rộng bằng màn hình thiết bị, initial-scale=1.0 đặt mức phóng ban đầu là 100% — thiết yếu cho thiết kế đáp ứng (responsive) trên điện thoại |
Các thông tin này giúp công cụ tìm kiếm hiểu và tìm được tài liệu, đồng thời giúp trình duyệt hiển thị tài liệu chính xác hơn.
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="description" content="Thiết kế Website">
<meta name="keywords" content="HTML, CSS, JavaScript">
<meta name="author" content="Dương Minh">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Đọc thẻ meta</title>
</head>
<body>
<p>Các thẻ meta không hiển thị, nhưng đọc được bằng JavaScript.</p>
<script>
console.log("charset:", document.querySelector("meta[charset]").getAttribute("charset"));
for (const m of document.querySelectorAll("meta[name]")) {
console.log(m.getAttribute("name") + " = " + m.getAttribute("content"));
}
</script>
</body>
</html>Cảnh báo: Thẻ
<meta charset="UTF-8">nên đặt ngay đầuhead(trong 1024 byte đầu của tệp) và tệp phải được lưu với mã hóa UTF-8. Nếu khai báo một đằng, lưu tệp một nẻo, tiếng Việt sẽ hiện thành các ký tự lạ như "á".
Mở rộng: Từ khóa
keywordsngày nay hầu như không còn được các công cụ tìm kiếm lớn dùng để xếp hạng;descriptionvàtitlemới quan trọng. Giáo trình giới thiệukeywordsvì nó vẫn xuất hiện trong rất nhiều trang hiện có.
4.4. Đường dẫn cơ sở
Một tài liệu HTML thường liên kết tới rất nhiều nguồn bên ngoài thông qua đường dẫn (ví dụ ảnh, liên kết). Để khai báo đường dẫn cơ sở cho các liên kết này, dùng phần tử <base>. Ví dụ, ảnh và liên kết tới trang https://minh-blogs.web.app/ có thể viết đầy đủ:
<img src="https://minh-blogs.web.app/images/logo.png" width="24" height="39">
<a href="https://minh-blogs.web.app/index.html">Vào trang chủ</a>và được viết gọn lại thành:
<head>
<base href="https://minh-blogs.web.app/" target="_blank">
</head>
<body>
<img src="images/logo.png" width="24" height="39">
<a href="index.html">Trang chủ</a>
</body>Thẻ base có hai thuộc tính: href là địa chỉ gốc mà mọi đường dẫn tương đối trong trang sẽ được "nối" vào; target đặt cách mở mặc định của các liên kết (_blank là mở trong tab mới). Chạy thử để xem các đường dẫn tương đối được trình duyệt "đổi" thành địa chỉ đầy đủ như thế nào:
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<base href="https://minh-blogs.web.app/" target="_blank">
<title>Đường dẫn cơ sở</title>
</head>
<body>
<a id="lk" href="index.html">Trang chủ</a>
<script>
const a = document.getElementById("lk");
console.log("href viết trong mã:", a.getAttribute("href"));
console.log("địa chỉ thực tế :", a.href);
console.log("base target :", document.querySelector("base").target);
</script>
</body>
</html>Lưu ý: Mỗi tài liệu chỉ nên có một phần tử
base, đặt trongheadvà trước mọi phần tử có đường dẫn.baseảnh hưởng đến tất cả đường dẫn tương đối trong trang (kể cả liên kết tới mục#...cùng trang), nên chỉ dùng khi bạn thực sự cần.
Bạn vừa học xong phần đầu của tài liệu; hãy làm ba bài này để tự viết head với meta, title, link (CSS ngoài, favicon) và bản head đầy đủ.
5. Phần tử khối và phần tử nội tuyến
Giáo trình: Chương 2 — mục "Phần tử khối và phần tử nội tuyến" (Phần tử khối; Phần tử nội tuyến).
Tất cả các phần tử trong HTML có thể chia thành hai loại: các phần tử khối (block) và các phần tử nội tuyến (inline).
Phần tử đi sau luôn xuống dòng mới (↵), kể cả khi nội dung rất ngắn.
Đây là bảng tóm tắt thuộc tính trong CSS, cần thiết để tra cứu khi dùng style, nằm liền mạch trên cùng một dòng.
Chỉ rộng bằng nội dung, tự xuống dòng khi hết chỗ.
<p><h1>…<h6><div><ul><ol><blockquote><pre><hr><dl><address><span><b><i><u><em><strong><sup><sub><del><ins><code><cite><kbd><small><div> là khối đa dụngGom nhóm để chia bố cục; đặt id/class rồi tạo kiểu bằng CSS.
<span> là nội tuyến đa dụngBọc một đoạn chữ ngắn để tô màu, đậm nhạt riêng bằng CSS.
Khối chứa được cả khối lẫn nội tuyến; nội tuyến chỉ nên chứa nội tuyến.
Phần tử khối bắt đầu trên dòng mới và chiếm hết chiều rộng; phần tử nội tuyến chỉ rộng bằng nội dung và nằm cùng một dòng, hết chỗ thì tự xuống dòng.
Hình trên so sánh hai họ phần tử: phần tử khối xuống dòng và chiếm hết bề ngang, còn phần tử nội tuyến nằm nối tiếp nhau trên cùng một dòng, chỉ chiếm vừa đủ nội dung của mình.
5.1. Phần tử khối
Phần tử khối (block) thường bắt đầu và kết thúc bằng một dòng mới khi hiển thị trong trình duyệt. Ví dụ: <p>, <h1> đến <h6>, <blockquote>, <address>, <dl>, <pre>, <hr>, <ul> và <ol>. Các phần tử này đều bắt đầu ở dòng mới và chiếm toàn bộ độ rộng của trang Web, nghĩa là các phần tử đi sau chúng cũng phải xuất hiện trên dòng mới.
Thẻ <div> là thẻ tiêu biểu để tạo phần tử khối phi ngữ nghĩa (phần tử ngữ nghĩa sẽ học ở buổi sau). Đây là phần tử đa dụng, thường dùng để tạo khối chứa các phần tử HTML khác: nhóm các thẻ lại với nhau và áp dụng CSS cho cả nhóm. <div> có thể dùng để tạo bố cục (layout) cho Web: nhà thiết kế chia các phần khác nhau của trang (trái, phải, trên...) bằng thẻ này. Bản thân div không tạo ra thay đổi nào về mặt hiển thị, nhưng nó có nhiều ý nghĩa hơn khi được đặt tên (bằng id hoặc class) và dùng cùng các thuộc tính CSS.
Ví dụ đơn giản về div (ví dụ của giáo trình):
<div>
<p><em>Ngôn ngữ HTML là gì?</em></p>
HTML viết tắt của <strong>Hypertext Markup Language</strong> là ngôn ngữ đánh dấu dùng để xây dựng và cấu trúc lại các thành phần có trong Website...
</div>
<script>
const d = document.querySelector("div");
console.log("hiển thị của div:", getComputedStyle(d).display);
console.log("hiển thị của p :", getComputedStyle(d.querySelector("p")).display);
console.log("hiển thị của em :", getComputedStyle(d.querySelector("em")).display);
</script>5.2. Phần tử nội tuyến
Phần tử nội tuyến (inline) là các phần tử mặc định xuất hiện cùng nhau trên một dòng. Chúng được tạo bởi các thẻ <span>, <b>, <i>, <u>, <em>, <strong>, <sup>, <sub>, <big>, <small>, <li>, <ins>, <del>, <code>, <cite>, <dfn>, <kbd>, <var>... (danh sách theo giáo trình).
Thẻ <span> là phần tử nội tuyến tiêu biểu và dùng khá phổ biến. Nó cũng không tạo thay đổi hiển thị nào, nhưng có nhiều ý nghĩa hơn khi dùng cùng CSS. Khác biệt giữa span và div: span dùng với các phần tử nội tuyến (chứa các phần tử nội tuyến khác bên trong), còn div thường dùng với cả phần tử nội tuyến và phần tử khối. Ví dụ đơn giản về span:
<div>
Đây là bảng tóm tắt tất cả các <span style="font-weight: bold">thuộc tính được sử dụng trong <em>CSS</em></span>. Sẽ rất cần thiết cho bạn tham khảo, tra cứu khi sử dụng CSS. Chi tiết từng thuộc tính sẽ được giới thiệu ở từng bài riêng...
</div>
<script>
const s = document.querySelector("span");
console.log("span hiển thị:", getComputedStyle(s).display);
console.log("chữ đậm bên trong span:", s.textContent);
</script>Kết quả hiển thị: Đây là bảng tóm tắt tất cả các thuộc tính được sử dụng trong CSS. Sẽ rất cần thiết cho bạn... — phần đậm nằm ngay giữa dòng văn bản mà không làm ngắt dòng.
Mở rộng: Giáo trình liệt kê
litrong nhóm nội tuyến. Trên thực tế mỗilimặc định hiển thịdisplay: list-item(xuống dòng và có dấu đầu dòng, giống phần tử khối); bạn sẽ thấy rõ khi học danh sách ở buổi sau. Một số thẻ trong danh sách (big,u) cũng đã cũ: nên dùng CSS để đổi cỡ chữ hoặc gạch chân thay vì các thẻ này.
5.3. So sánh khối và nội tuyến
| Tiêu chí | Phần tử khối (block) | Phần tử nội tuyến (inline) |
|---|---|---|
| Xuống dòng | Luôn bắt đầu dòng mới | Nằm cùng dòng với phần tử bên cạnh |
| Độ rộng mặc định | Chiếm toàn bộ độ rộng có sẵn | Chỉ chiếm vừa đủ nội dung |
| Có thể chứa | Khối và nội tuyến | Chủ yếu chỉ nội tuyến |
| Ví dụ | div, p, h1–h6, ul, ol, pre, hr |
span, em, strong, code, sub, sup |
| Thẻ "đa dụng" | div |
span |
Hãy tự quan sát: hai div nằm trên hai dòng, còn hai span nằm cạnh nhau. Chạy thử, rồi đoán display của từng phần tử trước khi xem bảng console.
<div style="background:#fde68a">Khối 1 (div)</div>
<div style="background:#bbf7d0">Khối 2 (div)</div>
<span style="background:#bfdbfe">Nội tuyến A</span>
<span style="background:#fbcfe8">Nội tuyến B</span>
<p style="background:#e9d5ff">Đoạn văn (p)</p>
<script>
const ds = ["div", "span", "p", "em", "h1", "ul", "code", "pre", "img"];
for (const t of ds) {
console.log(t.padEnd(5), "→", getComputedStyle(document.createElement(t)).display);
}
</script>Lưu ý: Bảng console cho thấy
displaymặc định của mỗi thẻ. Về sau ở phần bố cục CSS bạn sẽ biết cách đổi kiểu hiển thị (ví dụ chospanchiếm khối bằngdisplay: block) mà không đổi thẻ.
Mẹo: Chọn
divkhi bạn cần một vùng chứa (nhóm các khối lại để bố cục hoặc áp CSS); chọnspankhi cần làm nổi bật một cụm chữ giữa dòng văn bản. Nếu có thẻ ngữ nghĩa phù hợp (nhưp,em,strong,nav...), hãy ưu tiên nó hơndiv/span.
Bạn vừa học xong khối và nội tuyến; hãy làm ba bài này để nhận biết h2, div, span hoạt động khác nhau thế nào.
Cuối cùng, bạn gom mọi thứ của buổi — khung tài liệu, head, thuộc tính, khối và nội tuyến — vào những trang hoàn chỉnh.
Ba bài tổng hợp này yêu cầu bạn dựng cả trang (hồ sơ cá nhân, khung header/nav/footer, danh thiếp). Một số thẻ ngữ nghĩa (header, main, article) sẽ được giảng kỹ ở buổi sau; bạn chỉ cần dùng đúng theo đề bài.
Thực hành theo giáo trình
Giáo trình: Chương 2 — mục "Thực hành", Bài 2.3 "Tạo favicon" (thuộc phần đầu của tài liệu). Bài 2.1 "Tạo form đăng ký" và Bài 2.2 "Danh mục sản phẩm" thuộc các buổi sau (biểu mẫu; bảng, danh sách, liên kết).
Bài 2.3. Tạo favicon
Mục tiêu: tạo ảnh favicon từ một chữ cái và khai báo nó trong phần head của trang, kèm tệp Webmanifest.json cho thiết bị di động.
Các bước chính (theo giáo trình):
- Vào trang https://favicon.io, chọn Text → Ico để chuyển một chữ cái thành ảnh favicon. Trang cung cấp ba cách tạo favicon (từ ảnh, từ văn bản, từ emoji).
- Chọn một chữ cái phù hợp (ví dụ chữ F), chọn màu chữ và màu nền để tạo ảnh.
- Tải toàn bộ ảnh về và đặt trong thư mục
images/faviconcủa Website. - Khai báo trong phần
<head>bằng đoạn mã sau:
<link rel="apple-touch-icon" sizes="180x180" href="images/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="images/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="images/favicon/favicon-16x16.png">
<link rel="manifest" href="/Webmanifest.json">- Tạo tệp Webmanifest.json với nội dung:
{
"name": "",
"short_name": "",
"icons": [
{
"src": "images/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}Tệp manifest cho trình duyệt (đặc biệt trên điện thoại) biết tên ứng dụng, các biểu tượng theo kích thước, màu chủ đạo và cách hiển thị khi người dùng thêm trang vào màn hình chính. Bạn điền name và short_name bằng tên Website của mình. Chạy thử đoạn dưới đây để đọc tệp manifest như một đối tượng JavaScript và kiểm tra mọi biểu tượng đã có kích thước:
const manifest = {
name: "Cửa hàng sách",
short_name: "Sách",
icons: [
{ src: "images/favicon/android-chrome-192x192.png", sizes: "192x192", type: "image/png" },
{ src: "images/favicon/android-chrome-512x512.png", sizes: "512x512", type: "image/png" }
],
theme_color: "#ffffff",
background_color: "#ffffff",
display: "standalone"
};
console.log("Tên:", manifest.name, "/", manifest.short_name);
for (const ic of manifest.icons) console.log("-", ic.sizes, "→", ic.src);
console.log("Tất cả icon đều có sizes:", manifest.icons.every(i => i.sizes));Tự kiểm tra sau khi làm: mở trang trên trình duyệt thật, thấy chữ cái của bạn trên thẻ (tab); thử mở DevTools → tab Application để thấy manifest; chạy Validator để chắc head không có lỗi.
Câu hỏi ôn tập
Các câu 2.1–2.10 của giáo trình trải đều cả chương; câu 2.6, 2.7, 2.10 thuộc nội dung buổi này (thuộc tính href, width/height của ảnh). Các câu 2.1–2.5, 2.8, 2.9 sẽ gặp ở các buổi về văn bản, bảng, danh sách và phần tử ngữ nghĩa. Sáu câu bổ sung (B1–B6) bao quát phần còn lại của buổi.
Câu 2.6. Để tạo liên kết trong thẻ a sử dụng thuộc tính gì? A. href · B. src · C. link · D. ref
Đáp án: A. href (địa chỉ liên kết nằm trong thuộc tính href của thẻ a; src dùng cho nguồn ảnh).
Câu 2.7. Đơn vị nào được dùng cho thuộc tính kích thước ảnh? A. Pixels · B. Centimeters · C. Dot · D. Inches
Đáp án: A. Pixels (width="500" là rộng 500 pixel).
Câu 2.10. Đoạn mã nào là ĐÚNG để tạo một đường dẫn? A. <a url="http://www.w3schools.com">W3Schools.com</a> · B. <a href="http://www.w3schools.com">W3Schools.com</a> · C. <a name="http://www.w3schools.com">W3Schools.com</a> · D. <a>http://www.w3schools.com</a>
Đáp án: B. Chỉ phương án B dùng đúng thuộc tính href trong thẻ mở.
Câu B1. Phần tử nào chứa nội dung hiển thị cho người dùng: head, body, title hay meta?
Đáp án: body. head chỉ chứa thông tin mô tả tài liệu.
Câu B2. Cú pháp nào đúng để viết một chú thích HTML? A. // chú thích · B. /* chú thích */ · C. <!-- chú thích --> · D. # chú thích
Đáp án: C. Thẻ mở có dấu !, thẻ đóng thì không.
Câu B3. Thẻ nào sau đây là phần tử rỗng (không có thẻ đóng)? A. p · B. div · C. br · D. span
Đáp án: C. br (cùng img, hr) là phần tử rỗng.
Câu B4. Thuộc tính nào khai báo ngôn ngữ của tài liệu và đặt ở thẻ nào? Vì sao quan trọng?
Đáp án: Thuộc tính lang, đặt ở thẻ html (ví dụ lang="vi"). Quan trọng với trình đọc màn hình và công cụ tìm kiếm.
Câu B5. Thẻ nào dùng để khai báo favicon và đặt ở đâu?
Đáp án: Thẻ link với rel="icon" và href trỏ tới ảnh, đặt trong head.
Câu B6. Phân loại div, span, p, em thành phần tử khối hoặc nội tuyến.
Đáp án: div, p là phần tử khối; span, em là phần tử nội tuyến.
Sai lầm thường gặp
| Sai lầm | Hậu quả | Cách đúng |
|---|---|---|
Quên <!DOCTYPE html> ở dòng đầu |
Trình duyệt vào "quirks mode", hiển thị lệch giữa các trình duyệt | Luôn khai báo <!DOCTYPE html> ở dòng đầu tiên |
Quên thẻ đóng hoặc lồng sai thứ tự (<b><i>...</b></i>) |
Cây tài liệu bị trình duyệt tự "đoán", giao diện lệch khi thêm CSS | Thẻ mở sau đóng trước; chạy Validator |
Ảnh không có alt, width, height |
Người khiếm thị không biết ảnh nói gì; trang bị giật khi tải ảnh | Luôn khai báo alt, width, height |
| Đặt thuộc tính trong thẻ đóng hoặc quên nháy khi giá trị có khoảng trắng | Thuộc tính bị bỏ qua hoặc cắt giá trị | Thuộc tính chỉ ở thẻ mở; dùng dấu nháy quanh giá trị |
Quên <meta charset="UTF-8"> hoặc lưu tệp không phải UTF-8 |
Tiếng Việt hiển thị sai (ký tự lạ) | Khai báo charset đầu head và lưu tệp UTF-8 |
Đặt nội dung hiển thị trong head hoặc đặt title trong body |
Nội dung không hiển thị đúng chỗ, mất tiêu đề tab | head chỉ chứa thông tin mô tả; nội dung đặt trong body |
Dùng div/span cho mọi thứ |
Mã khó đọc, công cụ tìm kiếm không hiểu cấu trúc | Chọn thẻ có ý nghĩa; div/span chỉ khi không có thẻ phù hợp |
| Tên tệp có chữ hoa, khoảng trắng, dấu tiếng Việt | Liên kết hỏng khi đưa lên máy chủ | Tên tệp chữ thường, không dấu, nối bằng dấu gạch ngang |
Tóm tắt
- HTML là ngôn ngữ đánh dấu siêu văn bản; một tài liệu HTML5 gồm
<!DOCTYPE html>, phần tử gốchtml, phần đầuheadvà phần thânbody; chỉ nội dung trongbodyđược hiển thị. - Chú thích dùng
<!-- ... -->, không hiển thị nhưng vẫn nằm trong mã nguồn. Tệp HTML có đuôi.html, tạo bằng IDE/Text Editor (VS Code: gõdoc+ Tab), xem bằng trình duyệt hoặc Live Preview. - Phần tử = thẻ mở + nội dung + thẻ đóng; phần tử rỗng (
br,img,hr) không có thẻ đóng; phần tử có thể lồng nhau; thuộc tính (href,src,alt,width,height,style,title,lang, boolean) đặt trong thẻ mở dạng tên = "giá trị". - 16 quy ước viết mã: chữ thường, đóng mọi thẻ, đủ
alt,width,height, DOCTYPE đầu tiên, tên tệp chữ thường...; kiểm tra bằng https://validator.w3.org. - Trong
head:title(tab và kết quả tìm kiếm),link rel="icon"(favicon),meta(charset,description,keywords,author,viewport),base(đường dẫn cơ sở). - Phần tử khối xuống dòng và chiếm hết bề ngang (
div,p,h1...); phần tử nội tuyến nằm cùng dòng (span,em,strong...).divvàspanlà hai thẻ "đa dụng" không có ngữ nghĩa, kết hợp vớiid/classvà CSS.