Buổi 2: HTML, CSS, JavaScript và các công cụ thiết kế Web
Hãy hình dung bạn được giao làm website cho một cửa hàng trà sữa gần trường. Chủ quán muốn có một trang giới thiệu thực đơn, màu sắc tươi sáng, và một nút "Đặt món" bấm vào thì hiện thông báo. Bạn sẽ bắt đầu từ đâu? Viết chữ gì, tô màu gì, làm cho nút "biết phản ứng" bằng cách nào, và dùng phần mềm nào để vẽ mẫu, gõ mã, xem thử rồi sửa lỗi? Buổi trước bạn đã biết một Website được tạo nên từ đâu và quy trình phát triển có bảy bước. Buổi này ta đi vào ba công nghệ nền tảng của mọi trang web là HTML, CSS và JavaScript, rồi làm quen với bộ đồ nghề mà người thiết kế web dùng hằng ngày: công cụ thiết kế giao diện (Adobe, Figma), công cụ viết mã (Visual Studio Code, Sublime Text, JetBrains, CodePen, CodeSandbox, jsFiddle) và công cụ có sẵn ngay trong trình duyệt (View Source, Developer Tools).
Mục tiêu buổi học
- Sau buổi này bạn có thể phân biệt vai trò của HTML (cấu trúc và nội dung), CSS (trình bày, định dạng, bố cục) và JavaScript (hành vi), và giải thích cách trình duyệt kết hợp ba thứ này khi hiển thị một trang.
- Sau buổi này bạn có thể mô tả cấu trúc cơ bản của một tài liệu HTML (
DOCTYPE,html,head,body), lịch sử các phiên bản HTML, CSS và vai trò của W3C, WHATWG. - Sau buổi này bạn có thể liên kết một tệp CSS vào tài liệu HTML bằng thẻ
linkvà nhận biết cách một tệp JavaScript được tải về và thực thi. - Sau buổi này bạn có thể kể tên và so sánh các công cụ thiết kế giao diện (Adobe Dreamweaver, Photoshop, Illustrator, Figma) và các công cụ viết mã (VS Code, Sublime Text, JetBrains, CodePen, CodeSandbox, jsFiddle).
- Sau buổi này bạn có thể dùng "View Source" và Developer Tools của trình duyệt để xem mã nguồn, đếm tệp CSS/JS và biết ý nghĩa của các bảng điều khiển chính.
- Sau buổi này bạn có thể thực hiện các thao tác cơ bản trên Figma (tìm thiết kế mẫu, công cụ cơ bản, vị trí và kích thước, màu sắc, mặt nạ).
Bản đồ buổi học
| Phần | Nội dung | Thời lượng gợi ý |
|---|---|---|
| 1. HTML, CSS, JavaScript trong thiết kế Web | Vai trò ba công nghệ; tài liệu HTML; ngôn ngữ CSS; ngôn ngữ JavaScript | 55 phút |
| 2. Công cụ thiết kế giao diện Web | Bộ công cụ của Adobe; Figma | 10 phút |
| 3. Công cụ viết mã lệnh thiết kế | VS Code, Sublime Text, JetBrains, CodePen.io, CodeSandbox.io, jsFiddle.net | 20 phút |
| 4. Công cụ hỗ trợ phát triển trên trình duyệt | View Source, Developer Tools và các bảng điều khiển | 25 phút |
| Thực hành theo giáo trình | Bài 1.1–1.5 (Figma), bài tự thực hành 1.6–1.7 | 50 phút |
| Ôn tập và bài tập trên Codelab | Câu hỏi ôn tập chương 1, bài tập Codelab | 20 phút |
Khoảng một nửa thời gian của buổi dành cho thực hành: gõ thử các ví dụ có nút "▶ Chạy thử", dùng Figma và làm các nhóm bài trên Codelab ngay sau mỗi phần lý thuyết.
1. HTML, CSS, JavaScript trong thiết kế Web
Giáo trình: Chương 1 — mục "HTML, CSS, JavaScript trong thiết kế Web" (gồm "Tài liệu HTML", "Ngôn ngữ định dạng CSS", "Ngôn ngữ lập trình JavaScript").
Ba công nghệ cơ bản, có vai trò quan trọng trong thiết kế Web gồm:
- Ngôn ngữ đánh dấu siêu văn bản HTML (HyperText Markup Language).
- Ngôn ngữ định dạng CSS (Cascading Style Sheets).
- Ngôn ngữ lập trình JavaScript.
<h4>Khóa học HTML</h4><p>Học dựng trang Web…</p><button>Đăng ký</button>
Học dựng trang Web từ đầu.
.card { border-radius: 12px; }h4 { color: #4f46e5; }button { background: #4f46e5; }
Khóa học HTML
Học dựng trang Web từ đầu.
const btn = document.querySelector('button')btn.onclick = () => {btn.textContent = 'Đã đăng ký ✓'}
Khóa học HTML
Học dựng trang Web từ đầu.
HTML cho biết trang có gì, CSS quyết định trang trông thế nào, JavaScript quyết định trang làm gì khi người dùng thao tác.
Sơ đồ trên tóm tắt phân công của ba "người thợ". Cách đọc đơn giản nhất là hình dung một ngôi nhà: HTML là khung và các căn phòng (trang gồm những thành phần, nội dung gì), CSS là sơn tường, nội thất và cách bài trí (màu sắc, bố cục), còn JavaScript là hệ thống điện, công tắc và cửa tự động (hành vi, phản ứng khi người dùng thao tác).
HTML cung cấp cấu trúc và nội dung cho trang Web. Một Website thường gồm nhiều tài liệu HTML (HTML document), lưu trong các tệp có phần mở rộng .html hoặc .htm. Một tài liệu HTML bao gồm các thẻ (tag); một cặp thẻ mở, thẻ đóng cùng nội dung bên trong tạo thành một phần tử (element). HTML quyết định một trang Web bao gồm những thành phần và nội dung gì. Điều quan trọng cần nhớ là HTML không phải là ngôn ngữ lập trình, vì vậy HTML không thể tạo ra các chức năng "động".
CSS kiểm soát trình bày, định dạng và bố cục. CSS được dùng để định dạng các thành phần do HTML tạo ra. CSS định nghĩa các phong cách (style) gồm thông tin về bố cục, màu sắc trang... rồi áp dụng các phong cách này cho từng loại thành phần. CSS có thể khai báo ngay trong tệp HTML hoặc trong một tệp CSS riêng.
JavaScript kiểm soát hành vi của các yếu tố khác nhau. Đây là ngôn ngữ kịch bản (scripting language); khi chạy ở phía máy khách, nó hoạt động độc lập với máy chủ để thực hiện các kịch bản cần thiết. Tuy vậy, JavaScript cũng được dùng để gửi và nhận dữ liệu từ máy chủ.
Khi người dùng gửi yêu cầu tới máy chủ, trình duyệt nhận về tài liệu HTML rồi tiếp tục tải các tệp CSS, JavaScript được liên kết; khi đó tệp CSS định dạng hiển thị cho các thành phần trong tệp HTML, đồng thời tệp JavaScript cũng được thực thi.
Hãy tự quan sát ba vai trò bằng một ví dụ nhỏ. Cùng một đoạn nội dung, ta thêm lần lượt từng lớp. Đoạn HTML thuần chỉ có cấu trúc: tiêu đề, một đoạn văn và một nút.
<h1>Trà sữa NEU</h1>
<p>Thực đơn hôm nay: trà đào, trà vải, hồng trà.</p>
<button id="dat">Đặt món</button>
<script>
console.log("Số phần tử trong body:", document.body.children.length);
console.log("Nút bấm chưa có hành vi nào: onclick =", document.getElementById("dat").onclick);
</script>Bạn thấy trình duyệt vẫn hiển thị được trang, nhưng ở dạng mặc định: chữ đen, nền trắng và nút bấm chưa làm gì. Bây giờ ta thêm CSS (trình bày) và JavaScript (hành vi) vào cùng trang:
<style>
body { background-color: cornflowerblue; font-family: verdana; }
h1 { color: white; text-align: center; }
p { font-size: 20px; }
</style>
<h1>Trà sữa NEU</h1>
<p>Thực đơn hôm nay: trà đào, trà vải, hồng trà.</p>
<button id="dat">Đặt món</button>
<script>
document.getElementById("dat").addEventListener("click", function () {
alert("Đã nhận đơn của bạn!");
});
console.log("Đã gắn hành vi cho nút Đặt món");
</script>Sau khi thêm CSS, trang đổi màu nền và căn giữa tiêu đề mà không sửa một chữ nào của nội dung HTML. Bấm nút "Đặt món" trong khung xem trước để thấy hộp thoại. Đó chính là tinh thần "tách biệt cấu trúc – trình bày – hành vi" mà giáo trình nhấn mạnh.
Lưu ý: HTML quyết định có gì trên trang, CSS quyết định trông thế nào, JavaScript quyết định làm gì khi người dùng thao tác. Khi gặp một yêu cầu mới ("đổi màu nút", "thêm mục vào thực đơn", "hiện thông báo"), hãy tự hỏi nó thuộc về lớp nào để sửa đúng chỗ.
Tài liệu HTML
Giáo trình: Chương 1 — mục "HTML, CSS, JavaScript trong thiết kế Web", phần "Tài liệu HTML".
Một tài liệu HTML bao gồm các thẻ (tag) nhằm định nghĩa nội dung và cấu trúc của Website:
- Tất cả các tài liệu HTML đều bắt đầu bằng khai báo DOCTYPE.
- Toàn bộ tài liệu HTML khai báo các thẻ nằm bên trong thẻ mở
<html>và thẻ đóng</html>. - Một tài liệu HTML cơ bản có phần head và body; trong đó
headchứa các thông tin về tài liệu vàbodychứa những nội dung sẽ hiển thị. - Mỗi thẻ trong tài liệu tạo ra một phần tử HTML.
- Mỗi phần tử HTML có thể có các thuộc tính (attribute) để định danh và xác định nó được hiển thị hoặc có hành vi như thế nào.
W3C và WHATWG
Các chuẩn HTML được phát triển bởi hai tổ chức quốc tế: W3C (World Wide Web Consortium), website https://www.w3.org, và WHATWG (Web Hypertext Application Technology Working Group, "Nhóm làm việc về công nghệ ứng dụng siêu văn bản Web"), gồm các thành viên chính là các công ty Apple, Mozilla, Google và Microsoft, website https://www.whatwg.org.
Các phiên bản HTML
HTML được phát triển từ năm 1993 và đã trải qua nhiều phiên bản:
| Phiên bản | Năm | Đặc điểm chính (theo giáo trình) |
|---|---|---|
| HTML 1.0 | 1993 | Ra đời năm 1993 và chưa bao giờ trở thành một chuẩn |
| HTML 2.0 | 1995–1996 | Còn gọi là chuẩn RFC 1866; các đặc tính chính (core) như thẻ html, head, body, p, ul, li... |
| HTML 3.2 | 1996 | Bổ sung bảng (table), applet, dòng chảy văn bản quanh ảnh, chỉ số trên và chỉ số dưới... |
| HTML 4.0 | 1997 | Hỗ trợ đầy đủ hơn đa phương tiện, ngôn ngữ kịch bản, khung (frame) và tách phần trình bày sang bảng kiểu (style sheet). Bản HTML 4.01 (1999) được dùng phổ biến hơn một thập kỷ |
| XHTML 1.0 | 2000 | Cải tổ HTML 4 theo cú pháp XML, giúp đọc và phân tích cú pháp dễ dàng hơn |
| XHTML 1.1 | 2001 | Chặt chẽ hơn, thiết kế để làm việc hoàn toàn với XML, tuân thủ quy tắc nghiêm ngặt hơn HTML |
| HTML5 | từ 2008 | Kế thừa cả XHTML; thêm nhiều cú pháp và thẻ mới như video, audio, canvas, tích hợp đồ họa vector. Từ năm 2019, HTML được duy trì dưới dạng HTML Living Standard do WHATWG cập nhật liên tục, thay cho cách đánh số phiên bản |
Bạn có thể tra cứu dòng thời gian này bằng chính JavaScript. Ví dụ dưới đây lưu các phiên bản trong một mảng đối tượng rồi lọc những phiên bản ra đời trước năm 2000:
const versions = [
{ name: "HTML 1.0", year: 1993 },
{ name: "HTML 2.0", year: 1995 },
{ name: "HTML 3.2", year: 1996 },
{ name: "HTML 4.0", year: 1997 },
{ name: "XHTML 1.0", year: 2000 },
{ name: "XHTML 1.1", year: 2001 },
{ name: "HTML5", year: 2008 }
];
const truoc2000 = versions.filter(v => v.year < 2000).map(v => v.name);
console.log("Ra đời trước năm 2000:", truoc2000.join(", "));
console.log("Số phiên bản tính đến HTML5:", versions.length);
console.log("HTML5 sau HTML 4.0 bao nhiêu năm:", versions[6].year - versions[3].year);Một tài liệu HTML mẫu
Ví dụ về một tài liệu HTML mẫu của giáo trình:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<body>
<h1>Tiêu đề</h1>
Nội dung
</body>
</html>Khi hiển thị ra trình duyệt, bạn thấy một tiêu đề lớn và dòng chữ "Nội dung" bên dưới (Hình 1-16 của giáo trình). Phần tiêu đề My Website trong title không hiện trong khung trang mà hiện trên thẻ (tab) của trình duyệt.
Trong tài liệu trên, khai báo <!DOCTYPE html> cho biết đây là một tài liệu HTML5. Đôi khi người thiết kế Web không đưa khai báo này vào; khi đó trình duyệt sẽ tự động suy đoán đây là tài liệu HTML và phiên bản của nó, điều này có thể dẫn đến việc hiển thị tài liệu không chính xác. Bạn có thể kiểm chứng bằng thuộc tính document.compatMode: giá trị CSS1Compat nghĩa là trình duyệt dùng chế độ chuẩn (standards mode), còn BackCompat là chế độ tương thích ngược (quirks mode).
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Có DOCTYPE</title></head>
<body>
<script>
console.log("Có DOCTYPE -> compatMode =", document.compatMode);
console.log("Tên doctype:", document.doctype.name);
</script>
</body>
</html><html>
<head><meta charset="UTF-8"><title>Thiếu DOCTYPE</title></head>
<body>
<script>
console.log("Thiếu DOCTYPE -> compatMode =", document.compatMode);
console.log("document.doctype =", document.doctype);
</script>
</body>
</html>Cảnh báo: Thiếu
<!DOCTYPE html>khiến trình duyệt rơi vào chế độ quirks và có thể hiển thị khác với dự định (kích thước hộp, căn lề...). Hãy luôn khai báo DOCTYPE ở dòng đầu tiên của mỗi tài liệu.
Trong phần head thường khai báo các thông tin như metadata (thông tin về dữ liệu): tiêu đề, các liên kết CSS, thông tin miêu tả, từ khóa... của tài liệu. Thẻ body định nghĩa phần thân hay phần nội dung của tài liệu; khi áp dụng các thuộc tính cho thẻ body, thuộc tính đó mặc định áp dụng cho toàn bộ các thành phần nội dung của tài liệu.
<!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ỉ rõ từng bộ phận: khai báo DOCTYPE, phần tử gốc html, hai nhánh head và body, thẻ mở – nội dung – thẻ đóng và thuộc tính. Đây là bản đồ bạn sẽ quay lại nhiều lần ở các buổi 3 và 4.
Ngôn ngữ định dạng CSS
Giáo trình: Chương 1 — mục "HTML, CSS, JavaScript trong thiết kế Web", phần "Ngôn ngữ định dạng CSS".
CSS ra đời từ năm 1996 và có ba phiên bản chính:
| Phiên bản | Thời điểm | Nội dung chính |
|---|---|---|
| CSS1 | 12/1996 | Định dạng font chữ, màu sắc, căn lề, trang trí viền, thiết lập khoảng cách... Hiện không còn được W3C bảo trì |
| CSS2 | 5/1998 | Kế thừa nhiều định dạng của CSS1 và bổ sung việc thiết lập vị trí; có thêm phiên bản CSS2.1 sửa lỗi và bổ sung một số nội dung |
| CSS3 | phát triển từ 1999, song song CSS2 | Bo tròn góc, đổ bóng, chuyển động, cùng các khai báo cấu hình bố cục như flexbox hay grid layout |
Mỗi phiên bản CSS thường bổ sung hoặc bỏ đi các khai báo thuộc tính khác nhau, và mức độ hỗ trợ các thuộc tính ở mỗi trình duyệt là khác nhau. Giáo trình giới thiệu bảng hỗ trợ thuộc tính CSS của từng trình duyệt (Hình 1-17): bảng cho biết một thuộc tính có được trình duyệt hỗ trợ hay không và từ phiên bản nào. Bảng đầy đủ có tại https://www.w3schools.com/cssref/css3_browsersupport.asp. Chúng ta sẽ quay lại vấn đề tương thích trình duyệt khi học thiết kế bố cục.
Mở rộng: Ngoài bảng của W3Schools, các nhà phát triển còn tra cứu khả năng hỗ trợ tại các trang như MDN Web Docs hoặc caniuse.com. Thói quen "kiểm tra trình duyệt hỗ trợ trước khi dùng tính năng mới" rất quan trọng với một Website phải chạy trên nhiều thiết bị.
Ví dụ một tài liệu CSS được lưu trong tệp test.css của giáo trình:
body {
background-color: cornflowerblue;
}
h1 {
color: white;
text-align: center;
}
p {
font-family: verdana;
font-size: 20px;
}Mỗi khối gồm bộ chọn (selector) cho biết áp dụng cho phần tử nào, và các khai báo thuộc tính: giá trị; nằm trong cặp ngoặc nhọn. Để xem tác dụng, ta đặt chính các quy tắc này vào thẻ style của một trang nhỏ:
<style>
body { background-color: cornflowerblue; }
h1 { color: white; text-align: center; }
p { font-family: verdana; font-size: 20px; }
</style>
<h1>Tiêu đề</h1>
<p>Nội dung</p>
<script>
const h1 = document.querySelector("h1");
const kieu = getComputedStyle(h1);
console.log("Màu chữ h1:", kieu.color);
console.log("Căn lề h1:", kieu.textAlign);
console.log("Cỡ chữ p:", getComputedStyle(document.querySelector("p")).fontSize);
</script>Trong thời kỳ đầu, các tài liệu HTML định nghĩa cả cấu trúc, nội dung và định dạng, điều này gây khó khăn khi biên tập. Ngày nay, người ta thường tách riêng phần định dạng ra và lưu trong các tệp CSS. Có ba cách để khai báo và sử dụng CSS (sẽ được trình bày chi tiết ở chương về CSS, tức buổi 6), tuy nhiên cách phổ biến nhất để áp dụng CSS cho một tài liệu HTML là dùng tệp CSS.
Khi đó, tài liệu HTML dùng thẻ link để liên kết tới tệp CSS. Thuộc tính href cho biết cần liên kết đến tệp CSS nào. Thuộc tính rel cho biết mối quan hệ (relationship) giữa tài liệu HTML và tài liệu được liên kết đến là stylesheet, nghĩa là liên kết được dùng để định dạng phong cách cho tài liệu. Ví dụ đưa tệp CSS vào tài liệu HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Website</title>
<link href="style.css" rel="stylesheet">
</head>
<body>
<h1>Tiêu đề</h1>
Nội dung
</body>
</html>Nội dung tệp style.css:
h1 {
text-align: center;
color: white;
}
body {
background-color: darkseagreen;
}Ví dụ này cần hai tệp nằm cùng thư mục nên không chạy trực tiếp trong bài; kết quả (Hình 1-18) tương đương với trang dưới đây, trong đó nội dung style.css được đặt vào thẻ style:
<style>
h1 { text-align: center; color: white; }
body { background-color: darkseagreen; }
</style>
<h1>Tiêu đề</h1>
Nội dung
<script>
console.log("Màu nền body:", getComputedStyle(document.body).backgroundColor);
</script>Để kiểm chứng một trang có thật sự gắn tệp CSS, bạn có thể dùng JavaScript đếm thẻ link có rel="stylesheet". Ví dụ dưới đây dùng DOMParser để đọc một chuỗi HTML (không tải gì từ mạng) và hỏi xem trang đó liên kết tới tệp CSS nào:
const html = `<!DOCTYPE html>
<html><head>
<meta charset="UTF-8"><title>My Website</title>
<link href="style.css" rel="stylesheet">
</head><body><h1>Tiêu đề</h1>Nội dung</body></html>`;
const doc = new DOMParser().parseFromString(html, "text/html");
const links = doc.querySelectorAll('link[rel="stylesheet"]');
console.log("Số tệp CSS liên kết:", links.length);
links.forEach(l => console.log("href =", l.getAttribute("href"), "| rel =", l.rel));
console.log("Tiêu đề trang:", doc.title);Mẹo: Hãy tạo thói quen tách CSS ra tệp riêng (
style.css) ngay từ đầu. Một tệp CSS có thể dùng chung cho nhiều trang HTML, trình duyệt chỉ cần tải một lần rồi dùng lại, và khi muốn đổi giao diện cả website bạn chỉ sửa một nơi.
Ngôn ngữ lập trình JavaScript
Giáo trình: Chương 1 — mục "HTML, CSS, JavaScript trong thiết kế Web", phần "Ngôn ngữ lập trình JavaScript".
JavaScript là ngôn ngữ lập trình được dùng rộng rãi ở cả phía máy khách (trên trình duyệt) và phía máy chủ (Node.js). Ở phía máy khách, JavaScript được tích hợp và nhúng trong HTML giúp Website sống động hơn, cho phép kiểm soát hành vi trang Web tốt hơn so với chỉ dùng HTML. JavaScript và CSS là các thành phần không thể thiếu khi phát triển Website.
Khi trang HTML trả về có tham chiếu tới các tệp CSS và JavaScript, trình duyệt sẽ tự động gửi yêu cầu tới máy chủ để tải các tệp này về. Các tệp JavaScript và CSS tải về sẽ phục vụ cho việc kết xuất (render) để hiển thị trên trình duyệt (Hình 1-19: cách thức một tệp JavaScript được tải về và thực hiện).
<buttononclick="alert('Chào!')">Bấm</button>
- ✓ Ngắn, tiện thử nhanh
- ✗ Trộn HTML với JS, khó bảo trì
- ✗ Không dùng lại được
<script>let e = document.getElementById("info")e.innerText = "Xin chào"</script>
- ✓ Dễ thấy, không cần tệp thêm
- ✓ Đặt ở bất kỳ vị trí nào
- ✗ Khó dùng lại giữa nhiều trang
<!-- index.html --><script src="js/main.js"></script>// js/main.jsconsole.log("OK")
- ✓ Tách HTML và JS, dễ đọc, dễ bảo trì
- ✓ Trình duyệt lưu đệm → tải nhanh hơn
- ✓ Dùng chung cho nhiều trang
<noscript>Không hỗ trợ JavaScript</noscript><script> cuối <body>DOM đã dựng xong khi mã chạy; cách làm quen thuộc, an toàn.<script src="a.js">Mặc định (đồng bộ): chặn việc phân tích HTML cho tới khi tải và chạy xong.<script src="a.js" defer>Tải song song, chạy sau khi phân tích HTML xong và đúng thứ tự khai báo.<script src="a.js" async>Tải song song, tải xong là chạy ngay (chen ngang), thứ tự không đảm bảo.Mã có thể nằm trong thuộc tính thẻ (inline), trong thẻ <script> (nội bộ) hoặc tệp .js riêng (ngoài); vị trí thẻ và defer/async quyết định thời điểm chạy.
Hình trên minh họa các cách đưa JavaScript vào trang (nhúng ngay trong thẻ, đặt trong thẻ script, hoặc nạp từ tệp .js bên ngoài). Giáo trình sẽ đi sâu ở chương về JavaScript (buổi 10); ở đây bạn chỉ cần nắm cơ chế chung: tệp .js cũng là một "tài nguyên" mà trình duyệt phải tải về giống như tệp CSS.
Dưới đây là ba cách nhúng, chạy thử cả ba trong một trang. Chú ý thứ tự dòng in ra trong bảng console: trình duyệt xử lý mã theo thứ tự tìm thấy trên trang.
<button onclick="console.log('1) Mã nhúng trong thuộc tính onclick')">Bấm tôi</button>
<script>
console.log("2) Mã đặt trong thẻ script, chạy khi trình duyệt đọc tới đây");
</script>
<p id="kq">Chờ JavaScript...</p>
<script>
document.getElementById("kq").textContent = "3) JavaScript vừa sửa nội dung đoạn văn";
console.log("4) Đọc lại nội dung:", document.getElementById("kq").textContent);
</script>Ngoài hai cách trên, cách thứ ba là tham chiếu tệp ngoài bằng script src="app.js" rồi đặt mã trong tệp app.js; cách này cũng khiến trình duyệt gửi thêm một yêu cầu để tải tệp.
Tiếp theo là một đoạn quan trọng của giáo trình: JavaScript được dùng để người sử dụng tương tác với Web trên trình duyệt. Khi trình duyệt tải một trang Web, nó tải về mã HTML. Khi phân tích cú pháp mã HTML, trình duyệt tạo ra Mô hình đối tượng tài liệu (Document Object Model – DOM). Trong tài liệu HTML có thể có các khai báo CSS và mã JavaScript:
- Nếu là khai báo CSS, trình duyệt chuyển cho bộ phân tích CSS (CSS Parser).
- Nếu là mã JavaScript, trình duyệt gửi đến bộ máy JavaScript (JavaScript Engine).
Tuy nhiên, quá trình chạy mã JavaScript được thực hiện sau khi các chỉ thị CSS hoàn tất. Thứ tự thực hiện theo thứ tự tìm thấy trên các trang Web. Khi đó, các hàm được gọi, các sự kiện được kích hoạt, dẫn đến việc DOM được JavaScript cập nhật và hiển thị lại cho người dùng.
<html> <head><title>Trang</title></head> <body> <h1 id="tt">Xin chào</h1> <ul><li>HTML</li><li>CSS</li></ul> </body> </html>
- tài liệunodeType 9, gốc của cây
- phần tửnodeType 1, nodeName = tên thẻ
- văn bảnnodeType 3, nodeName "#text"
- thuộc tínhđọc bằng getAttribute()
- Mã xuống dòng, thụt lề sẽ sinh thêm nút
#textchứa khoảng trắng giữa các thẻ; hình đã lược bỏ cho gọn.
ul.parentNode→<body>body.firstChild→<h1>h1.nextSibling→<ul>ul.lastChild→<li> thứ haili2.previousSibling→<li> thứ nhất- nodeName
- "H1"
- nodeValue
- null
- nodeType
- 1
- nodeName
- "#text"
- nodeValue
- "Xin chào"
- nodeType
- 3
- nodeName
- "#document"
- nodeValue
- null
- nodeType
- 9
Trình duyệt biến mã HTML thành cây nút; JavaScript đi trên cây bằng parentNode, firstChild, lastChild, nextSibling, previousSibling và đọc nodeName, nodeValue, nodeType.
Cây DOM trên cho thấy trình duyệt biến mã HTML thành các nút lồng nhau: html là gốc, head và body là hai nhánh, các phần tử khác là lá hoặc nhánh con. Hãy xem JavaScript đọc cây DOM đó ra sao và sửa nó thế nào:
<style>
.moi { color: crimson; font-weight: bold; }
</style>
<h1>Tiêu đề</h1>
<p id="nd">Nội dung ban đầu</p>
<script>
console.log("readyState khi script chạy:", document.readyState);
console.log("Các con của body:", Array.from(document.body.children).map(e => e.tagName).join(", "));
const p = document.getElementById("nd");
p.textContent = "Nội dung đã được JavaScript cập nhật";
p.classList.add("moi");
console.log("Sau khi sửa:", p.outerHTML);
</script>Khi bạn bấm "Chạy thử", cây DOM bị sửa và trình duyệt vẽ lại ngay: đoạn văn đổi chữ và đổi màu. Đó là ý nghĩa của câu "DOM được JavaScript cập nhật và hiển thị lại cho người dùng".
Ví dụ thực tế: Khi bạn mở trang Shopee hay một trang tin tức, trình duyệt tải về một tệp HTML, rồi hàng chục tệp CSS, JavaScript, ảnh. Trong tab Network của Developer Tools (mục 4 bên dưới) bạn sẽ nhìn thấy từng yêu cầu đó xuất hiện dần theo thời gian.
Bảng tổng hợp ba công nghệ giúp bạn nhớ nhanh:
| HTML | CSS | JavaScript | |
|---|---|---|---|
| Vai trò | Cấu trúc và nội dung | Trình bày, định dạng, bố cục | Hành vi, tương tác |
| Là ngôn ngữ lập trình? | Không (ngôn ngữ đánh dấu) | Không (ngôn ngữ định dạng) | Có (ngôn ngữ kịch bản) |
| Lưu trong tệp | .html, .htm |
.css |
.js |
| Nạp vào trang bằng | Chính là tài liệu trang | Thẻ link rel="stylesheet", thẻ style |
Thẻ script |
| Xử lý bởi | Bộ phân tích HTML, tạo DOM | Bộ phân tích CSS (CSS Parser) | Bộ máy JavaScript (JavaScript Engine) |
Vừa học xong vai trò của HTML, CSS, JavaScript và cách trình duyệt tải các tài nguyên, bạn đã có đủ kiến thức để nhận biết loại tệp nào là tài nguyên tĩnh, tệp nào do máy chủ sinh ra, cũng như loại nội dung (Content-Type) gắn với từng tệp. Hãy làm nhóm bài sau để luyện điều này.
2. Công cụ thiết kế giao diện Web
Giáo trình: Chương 1 — mục "Công cụ thiết kế giao diện Web" (gồm "Bộ công cụ của Adobe", "Công cụ Figma").
Ở bước "Thiết kế giao diện, trải nghiệm người dùng" trong quy trình phát triển Web (buổi 1), nhà thiết kế thường vẽ giao diện trước khi viết mã. Các công cụ thiết kế giao diện cho phép tạo bản mẫu trực quan, trao đổi với khách hàng rồi mới chuyển cho lập trình viên.
Bộ công cụ của Adobe
Công ty phần mềm Adobe cung cấp bộ công cụ để thiết kế Web một cách trực quan, gồm:
| Công cụ | Viết tắt | Đặc điểm theo giáo trình |
|---|---|---|
| Adobe Dreamweaver | AD | Công cụ phát triển Web, cung cấp môi trường thiết kế trực quan bằng thao tác kéo thả hoặc viết mã trực tiếp; liên kết chặt chẽ với Adobe Photoshop và Adobe Illustrator |
| Adobe Photoshop | AP | Công cụ chỉnh sửa ảnh nổi tiếng, cũng quen thuộc với nhà thiết kế Web; cho phép thiết kế và xuất ra tệp định dạng html |
| Adobe Illustrator | AI | Làm việc với dữ liệu vector, vì vậy phù hợp để thiết kế các trang Web có giao diện phẳng; cũng dùng nhiều để tinh chỉnh trực quan các đối tượng vector khi làm việc với HTML5 |
Hình 1-20 của giáo trình là biểu tượng của bộ ba công cụ Adobe. Điểm đáng chú ý: Photoshop thiên về ảnh điểm (bitmap), còn Illustrator thiên về vector. Sự khác biệt này sẽ xuất hiện lại ở buổi 5 khi bạn chèn ảnh bitmap và ảnh vector (SVG) vào trang.
Mở rộng: Bitmap lưu ảnh dưới dạng lưới các điểm ảnh nên phóng to sẽ bị vỡ, còn vector lưu ảnh bằng các công thức hình học nên phóng to vẫn sắc nét. Vì vậy biểu tượng (icon), logo thường được làm bằng vector.
Công cụ Figma
Figma (figma.com) là công cụ trực tuyến khá thông dụng để thiết kế giao diện Website. Các điểm mạnh theo giáo trình:
- Lưu các thiết kế dưới dạng dữ liệu vector.
- Hỗ trợ làm việc nhóm theo thời gian thực.
- Lưu nhiều phiên bản, giúp dễ dàng quay lại phiên bản trước.
- Có kho tiện ích mở rộng (plugin) phong phú và hữu dụng.
Hình 1-21 là màn hình chính của Figma: thanh công cụ ở trên, danh sách lớp (layers) bên trái, vùng thiết kế ở giữa và bảng thuộc tính bên phải. Bạn sẽ thực hành trực tiếp trong phần "Thực hành theo giáo trình" ở cuối bài này.
Một lợi ích lớn của việc thiết kế bằng công cụ như Figma là các giá trị thiết kế (mã màu, kích thước, khoảng cách) có thể chuyển thẳng thành CSS. Ví dụ, Figma cho phép nhập màu dưới dạng mã HEX hoặc RGB. Đoạn JavaScript sau đổi một mã HEX sang rgb() và rgba() để dán vào CSS:
function hexToRgb(hex) {
const h = hex.replace("#", "");
const n = parseInt(h, 16);
return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };
}
const mau = hexToRgb("#6495ED"); // cornflowerblue
console.log("rgb:", `rgb(${mau.r}, ${mau.g}, ${mau.b})`);
const opacity = 0.5; // Opacity trong Figma
console.log("rgba:", `rgba(${mau.r}, ${mau.g}, ${mau.b}, ${opacity})`);
console.log("Đen:", JSON.stringify(hexToRgb("#000000")));
console.log("Trắng:", JSON.stringify(hexToRgb("#FFFFFF")));Lưu ý: Hình thức thiết kế (Figma) và hình thức viết mã (HTML/CSS/JS) là hai bước nối tiếp nhau. Bản thiết kế càng rõ ràng (màu, cỡ chữ, khoảng cách) thì việc "dịch" sang mã càng nhanh và ít sai.
3. Công cụ viết mã lệnh thiết kế
Giáo trình: Chương 1 — mục "Công cụ viết mã lệnh thiết kế" (Visual Studio Code, Sublime Text, bộ công cụ của JetBrains, CodePen.io, CodeSandbox.io, jsFiddle.net).
Có rất nhiều công cụ để tạo và chỉnh sửa các tệp HTML, CSS và JS. Để xây dựng một Website, nhà phát triển nên có một môi trường phát triển tích hợp (Integrated Development Environment – IDE). IDE tích hợp sẵn các công cụ biên tập, hỗ trợ lập trình, biên dịch, gỡ lỗi, kiểm thử và triển khai. Một IDE cũng có thể tích hợp kèm trình duyệt để hiển thị Web. Các IDE có thể miễn phí hoặc trả phí. Một số công cụ phổ biến trong phát triển Web gồm Visual Studio Code, Sublime Text và các IDE của JetBrains như WebStorm, IntelliJ IDEA...
Công cụ Visual Studio Code
Visual Studio Code (VSC) do Microsoft phát triển, có thể tải miễn phí tại https://code.visualstudio.com. VSC hỗ trợ xây dựng Website với nhiều ngôn ngữ lập trình và công nghệ khác nhau, và có nhiều tiện ích mở rộng (extension) hỗ trợ (Hình 1-22 là giao diện của công cụ).
Công cụ Sublime Text
Sublime Text là một công cụ biên tập nhẹ, cài đặt và sử dụng dễ dàng. Nó hoạt động tốt trên nhiều nền tảng như macOS, Linux và Windows. Có thể tải tại https://www.sublimetext.com (Hình 1-23).
Bộ công cụ của JetBrains
JetBrains là công ty nổi tiếng với các phần mềm, công cụ lập trình và phát triển. Công cụ của JetBrains chuyên nghiệp, dễ sử dụng, có khả năng kiểm tra tự động và sửa lỗi. JetBrains cung cấp nhiều công cụ hỗ trợ phát triển ứng dụng từ nhiều nền tảng khác nhau và đều có thể dùng để phát triển Web. JetBrains cho phép giáo viên, học sinh và sinh viên sử dụng miễn phí (với tài khoản email thuộc tên miền .edu). Công cụ tải tại https://www.jetbrains.com; Hình 1-24 là giao diện IntelliJ IDEA.
Công cụ CodePen.io
CodePen (CodePen.io) là môi trường học lập trình Web hoàn toàn trực tuyến, nơi có thể thử nghiệm hoặc chia sẻ những đoạn mã nguồn dễ dàng. CodePen cung cấp công cụ gọi là Pen, gồm ba cửa sổ cho HTML, CSS, JavaScript và một khung xem trước kết quả. Trong quá trình thiết kế, khung xem trước cập nhật liên tục nên rất dễ thấy kết quả. CodePen cũng hỗ trợ các bộ tiền xử lý (preprocessor), cho phép thêm các tập lệnh từ bên ngoài, dùng các mẫu sẵn có và có chế độ cộng tác (Hình 1-25).
Công cụ CodeSandbox.io
CodeSandbox (codesandbox.io) là trình biên tập trực tuyến để phát triển nhanh Web, hoạt động tương tự các IDE cài trên máy tính. Hiện nay CodeSandbox hỗ trợ nhiều framework phổ biến như React, Vue, Angular, Node HTTP Server... Để dùng, nhà phát triển tạo một Sandbox mới bằng cách chọn từ các Template có sẵn. CodeSandbox tạo một Project mới có giao diện giống IDE trên máy tính, gồm: trình quản lý tệp, quản lý các phụ thuộc (dependencies), ô soạn thảo và trình duyệt thu gọn để hiển thị kết quả. Website được cấp sẵn một đường dẫn để xem trên các trình duyệt thông thường; project cũng dễ chia sẻ cho người khác cùng chỉnh sửa. Một công cụ tương tự là stackblitz.com (Hình 1-26).
Công cụ jsFiddle.net
jsFiddle (jsFiddle.net) là dịch vụ trực tuyến giúp thử nghiệm và chia sẻ mã nguồn JavaScript, HTML, CSS một cách dễ dàng. Người dùng nhập mã vào các ô chỉnh sửa tương ứng cho từng ngôn ngữ, jsFiddle hiển thị kết quả ngay trong cửa sổ xem trước, tiết kiệm thời gian đánh giá và phát triển trực tiếp trên trình duyệt mà không cần cài môi trường phức tạp. jsFiddle còn cho phép lưu trữ, chia sẻ và nhúng ví dụ vào tài liệu, diễn đàn trực tuyến. Các đặc tính chính:
- Hỗ trợ làm việc trực tuyến, dễ chia sẻ và cộng tác.
- Hỗ trợ quản lý phiên bản, quay lại phiên bản trước dễ dàng.
- Có sẵn các thư viện thông dụng: React, Vue, jQuery.
- Hỗ trợ gợi ý mã lệnh, tăng tốc độ lập trình, giảm sai sót.
- Có cộng đồng người dùng lớn.
- Hỗ trợ nhiều tùy chọn và tính năng mở rộng.
Bảng so sánh nhanh các công cụ viết mã trong giáo trình:
| Công cụ | Loại | Chạy ở đâu | Điểm nổi bật |
|---|---|---|---|
| Visual Studio Code | IDE/trình soạn thảo, miễn phí (Microsoft) | Cài trên máy | Nhiều extension, hỗ trợ nhiều ngôn ngữ |
| Sublime Text | Trình biên tập nhẹ | Cài trên máy (macOS, Linux, Windows) | Nhẹ, dễ cài |
| JetBrains (WebStorm, IntelliJ IDEA...) | IDE chuyên nghiệp | Cài trên máy | Kiểm tra và sửa lỗi tự động; miễn phí cho sinh viên email .edu |
| CodePen.io | Trình soạn trực tuyến | Trình duyệt | Pen: 3 cửa sổ HTML/CSS/JS + khung xem trước; tiền xử lý; cộng tác |
| CodeSandbox.io | Trình soạn trực tuyến kiểu IDE | Trình duyệt | Template; hỗ trợ React, Vue, Angular, Node HTTP Server; chia sẻ đường dẫn |
| jsFiddle.net | Trình soạn trực tuyến | Trình duyệt | Thử nghiệm, chia sẻ, nhúng; quản lý phiên bản; thư viện React, Vue, jQuery |
Ngay trong Codelab, bạn cũng có công cụ giống CodePen và jsFiddle: ba tab HTML, CSS, JS và khung xem trước, cập nhật tức thì. Hãy thử gõ và sửa trực tiếp ở demo bên dướ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.
Cách dùng: gõ HTML ở tab đầu tiên, định dạng ở tab CSS, hành vi ở tab JS, rồi quan sát khung xem trước thay đổi. Hãy thử đổi cornflowerblue thành một màu khác, hoặc thêm một nút và gắn sự kiện click cho nó.
Phần lớn trình soạn trực tuyến thật ra làm đúng một việc: ghép ba ô HTML, CSS, JS thành một trang hoàn chỉnh rồi nạp vào khung xem trước. Đoạn mã dưới đây mô phỏng ý tưởng đó bằng JavaScript thuần:
function ghepTrang(html, css, js) {
return `<!DOCTYPE html>
<html><head><meta charset="UTF-8"><style>${css}</style></head>
<body>${html}<script>${js}<\/script></body></html>`;
}
const trang = ghepTrang(
"<h1>Xin chào</h1>",
"h1 { color: teal; }",
"console.log('hi');"
);
console.log(trang);
console.log("Độ dài trang ghép:", trang.length, "ký tự");
const doc = new DOMParser().parseFromString(trang, "text/html");
console.log("Có style:", doc.querySelectorAll("style").length, "| có script:", doc.querySelectorAll("script").length);Mẹo: Khi học, dùng trình soạn trực tuyến (CodePen, jsFiddle, hoặc sandbox ngay trong bài này) để thử ý tưởng nhanh trong vài giây. Khi làm dự án nhiều tệp (như bài tập cuối kỳ), hãy chuyển sang một IDE trên máy như VS Code để quản lý thư mục, tiện ích mở rộng và phiên bản.
Vừa học xong các công cụ viết mã và cách một trang được ghép từ ba tệp, hãy làm nhóm bài sau để luyện tập xử lý đường dẫn và tham số, thứ bạn thấy hằng ngày trên thanh địa chỉ và trong các công cụ này.
4. Công cụ hỗ trợ phát triển trên trình duyệt
Giáo trình: Chương 1 — mục "Công cụ hỗ trợ phát triển trên trình duyệt".
Khi trang Web đã được trả về từ máy chủ, chúng ta có thể xem mã nguồn của nó ngay trên trình duyệt:
- Xem mã nguồn trang HTML bằng cách bấm chuột phải và chọn View Source (Hình 1-28, trên Chrome).
- Xem mã nguồn CSS và JavaScript bằng cách bấm vào tệp CSS và JavaScript tương ứng trong mã nguồn.
Ngoài ra, các công cụ phát triển (Developer Tools) được tích hợp sẵn trên trình duyệt để hỗ trợ phát triển và gỡ lỗi các trang Web (Hình 1-29, Developer Tools của Chrome). Developer Tools tổ chức các nhóm chức năng trong thanh công cụ ở phía trên cùng của cửa sổ. Mỗi thanh công cụ và bảng điều khiển tương ứng cho phép làm việc với một loại hình cụ thể của trang hoặc thông tin ứng dụng, bao gồm các phần tử DOM, tài nguyên (resources) và mã nguồn (sources).
Các bảng điều khiển chính có sẵn trong Developer Tools:
| Bảng điều khiển | Dùng để làm gì |
|---|---|
| Elements | Xem và sửa cây DOM và CSS của trang ngay trên trình duyệt |
| Console | Xem thông báo, lỗi; chạy thử lệnh JavaScript |
| Sources | Xem mã nguồn các tệp HTML, CSS, JS; đặt điểm dừng để gỡ lỗi |
| Network | Xem từng yêu cầu/phản hồi: tệp nào được tải, mã trạng thái, tiêu đề (header), dung lượng, thời gian |
| Performance | Ghi và phân tích hiệu năng tải/hiển thị trang |
| Memory | Theo dõi việc dùng bộ nhớ của trang |
| Application | Xem dữ liệu lưu phía trình duyệt (cookie, localStorage...) |
| Security | Xem thông tin bảo mật, chứng chỉ của trang |
Lưu ý: Phần tên và cách bố trí chi tiết của từng bảng điều khiển có thể khác nhau giữa các trình duyệt (Chrome, Edge, Firefox, Safari) và thay đổi theo phiên bản. Mở Developer Tools bằng phím
F12(hoặcCtrl+Shift+Itrên Windows/Linux,Cmd+Option+Itrên macOS) hoặc bấm chuột phải và chọn Inspect.
Tab Network là nơi bạn gặp lại những gì đã học ở buổi 1: nó cho phép nhìn thấy đúng chuỗi "yêu cầu – phản hồi" của HTTP. Mỗi dòng là một yêu cầu; cột Status là mã trạng thái, cột Type cho biết loại tài nguyên (document, stylesheet, script, image...), và nhấp vào dòng sẽ thấy các header như Content-Type.
Trình duyệt Web (Chrome, Safari, Edge, Firefox…) gửi yêu cầu và hiển thị trang nhận về.
Host: www.example.com
Content-Type: text/html
<!DOCTYPE html> …
Nhận yêu cầu, đọc tệp hoặc truy vấn dữ liệu, rồi trả phản hồi.
Trình duyệt (máy khách) gửi yêu cầu HTTP; máy chủ Web xử lý rồi trả phản hồi HTTP chứa tài liệu HTML để trình duyệt hiển thị.
Hình trên nhắc lại luồng yêu cầu/phản hồi giữa trình duyệt và máy chủ; mọi dòng trong tab Network là một vòng như vậy.
Elements: xem và sửa DOM
Bảng Elements cho phép bạn nhấp đúp để sửa thẻ, thuộc tính, văn bản ngay trên trang; trang cập nhật tức thì (nhưng chỉ trong trình duyệt của bạn, không đổi tệp trên máy chủ). Bạn có thể mô phỏng điều đó bằng JavaScript: in ra outerHTML trước và sau khi sửa.
<h1 id="tieude" class="cu">Trà sữa NEU</h1>
<script>
const h = document.getElementById("tieude");
console.log("Trước:", h.outerHTML);
h.textContent = "Trà sữa NEU - Khuyến mãi";
h.classList.replace("cu", "moi");
h.style.color = "crimson";
console.log("Sau :", h.outerHTML);
</script>View Source và Bài 1.6: đếm tệp CSS, JS
Chức năng View Source cho thấy mã HTML mà máy chủ trả về. Từ đó bạn đếm được trang dùng bao nhiêu tệp CSS (các thẻ link rel="stylesheet") và bao nhiêu tệp JS (các thẻ script src). Đó chính là yêu cầu của Bài 1.6 ở cuối bài. Dưới đây là một đoạn "mã nguồn" giả định và chương trình đếm bằng DOMParser:
const nguon = `<!DOCTYPE html>
<html><head>
<title>Blog mẫu</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/main.css">
<link rel="icon" href="favicon.ico">
<script src="js/vendor.js"></script>
</head><body>
<h1>Blog</h1>
<script src="js/app.js"></script>
<script>console.log("mã nội tuyến, không phải tệp");</script>
</body></html>`;
const doc = new DOMParser().parseFromString(nguon, "text/html");
const css = [...doc.querySelectorAll('link[rel="stylesheet"]')].map(l => l.getAttribute("href"));
const js = [...doc.querySelectorAll("script[src]")].map(s => s.getAttribute("src"));
console.log("Số tệp CSS:", css.length, css);
console.log("Số tệp JS:", js.length, js);
console.log("Thẻ script nội tuyến:", doc.querySelectorAll("script:not([src])").length);Lưu ý: Thẻ
link rel="icon"là biểu tượng của trang, không phải tệp CSS, và thẻscriptkhông cósrclà mã nội tuyến, không phải tệp JS. Khi làm Bài 1.6 trên một trang thật, hãy lọc đúng loại để đếm chính xác.
Network: tệp, loại nội dung và mã trạng thái
Trong tab Network, loại tài nguyên được xác định nhờ header Content-Type của phản hồi, và cột Status cho biết mã trạng thái HTTP. Hai chi tiết nhỏ nhưng rất hay gặp khi gỡ lỗi: (1) một tệp CSS trả về với Content-Type: text/html thường nghĩa là đường dẫn sai và máy chủ trả về trang lỗi; (2) mã trạng thái chia thành năm nhóm theo chữ số đầu (1xx thông tin, 2xx thành công, 3xx chuyển hướng, 4xx lỗi phía client, 5xx lỗi phía server).
const mime = { html: "text/html", css: "text/css", js: "application/javascript", json: "application/json", png: "image/png" };
const tep = ["index.html", "css/style.css", "js/app.js", "data.json", "logo.png"];
tep.forEach(t => {
const duoi = t.split(".").pop();
console.log(t.padEnd(14), "->", mime[duoi]);
});
function nhomTrangThai(ma) {
const nhom = { 1: "Thông tin", 2: "Thành công", 3: "Chuyển hướng", 4: "Lỗi phía client", 5: "Lỗi phía server" };
return nhom[Math.floor(ma / 100)] || "Không rõ";
}
[200, 301, 304, 404, 500].forEach(m => console.log(m, "->", nhomTrangThai(m)));Bạn sẽ thấy hai bài toán này (xác định loại nội dung và phân nhóm mã trạng thái) trong nhóm bài tập của Codelab ngay sau đây. Các header khác cũng đọc được trong tab Network; ví dụ dưới đây tách một khối header thành cặp khóa – giá trị, giống cách DevTools hiển thị:
const header = `Content-Type: text/html; charset=UTF-8
Content-Length: 1256
Cache-Control: max-age=3600
Server: nginx`;
const bang = {};
header.split("\n").forEach(dong => {
const i = dong.indexOf(":");
bang[dong.slice(0, i).trim().toLowerCase()] = dong.slice(i + 1).trim();
});
console.log(JSON.stringify(bang, null, 1));
console.log("Mime chính:", bang["content-type"].split(";")[0]);Địa chỉ trên thanh địa chỉ cũng là thứ bạn đọc thường xuyên khi gỡ lỗi: phần sau dấu ? là query string (ví dụ ?q=tra&page=2), phần sau dấu # là fragment. Tab Network hiển thị query string thành từng cặp tham số. Trình duyệt có sẵn lớp URLSearchParams để làm việc đó:
const url = new URL("https://shop.example.com/search?q=tr%C3%A0+s%E1%BB%AFa&page=2&sort=gia#ket-qua");
console.log("path :", url.pathname);
console.log("fragment :", url.hash.slice(1));
console.log("q :", url.searchParams.get("q"));
console.log("page :", url.searchParams.get("page"));
console.log("số tham số:", [...url.searchParams].length);
const tuKhoa = encodeURIComponent("trà sữa & trân châu");
console.log("encode :", tuKhoa);
console.log("decode :", decodeURIComponent(tuKhoa));Phân tích đường dẫn Web (URL)
gõ URL hoặc chọn mẫu, rê chuột vào từng phầnfit · tên miền conneu · tên miềnedu.vn · đuôi (TLD)GET /codelab/huong-dan.html HTTP/1.1 Host: fit.neu.edu.vn
Hãy gõ thử một URL có cả query và fragment vào demo trên để thấy từng thành phần được tách ra. Sau khi hiểu các công cụ xem và gỡ lỗi này, nhóm bài dưới đây yêu cầu bạn tự viết chương trình đọc mã trạng thái và header giống những gì tab Network hiển thị.
Thực hành theo giáo trình
Giáo trình: Chương 1 — mục "Thực hành" (Bài 1.1 đến Bài 1.5, làm quen với Figma) và "Bài tập tự thực hành" (Bài 1.6, Bài 1.7).
Phần thực hành của chương 1 xoay quanh công cụ thiết kế Figma. Bạn cần một tài khoản Figma miễn phí (đăng nhập tại figma.com). Hãy làm lần lượt các bài, mỗi bài chỉ 5–10 phút.
Bài 1.1. Làm quen với Figma
Mục tiêu: tìm một thiết kế mẫu trong cộng đồng Figma, sao chép về và chạy thử bản mô phỏng.
Các bước chính (giữ đúng thứ tự của giáo trình):
- Đăng nhập vào Figma: truy cập
figma.comrồi đăng nhập; nhấp vào tab Community trong giao diện chính. - Tìm kiếm thiết kế: nhập từ khóa vào thanh tìm kiếm trong Community, nhấn Enter để tìm kiếm.
- Mở thiết kế: chọn thiết kế mong muốn, nhấp Duplicate to your Drafts hoặc Open in Figma; vào tab Drafts để chỉnh sửa và tùy chỉnh thiết kế (Hình 1-30: bảng chọn chính của Figma).
- Chạy thử bản mô phỏng (prototype): một số thiết kế Figma có bản mô phỏng; hãy bấm nút Play ở phía trên cùng bên phải để chạy thử (Hình 1-31).
Mẹo: Hãy chọn một mẫu thiết kế trang web có sẵn (ví dụ trang giới thiệu cửa hàng) để vừa học cách dùng Figma vừa quan sát nhà thiết kế chuyên nghiệp chia lớp, đặt tên và chọn màu như thế nào.
Bài 1.2. Các công cụ cơ bản
Mục tiêu: nhận biết các công cụ cơ bản trên thanh công cụ của Figma (Hình 1-32). Bạn tìm hiểu từng công cụ (chọn, khung Frame, hình dạng, bút vẽ, văn bản T...) bằng cách bấm thử trên một trang thiết kế trống: kéo thả để tạo hình chữ nhật, hình tròn, thêm một dòng chữ và nhấn phím tắt tương ứng.
Bài 1.3. Vị trí và kích thước
Mục tiêu: điều chỉnh vị trí và kích thước của các đối tượng trong cửa sổ thiết kế (Hình 1-33). Hãy chọn một đối tượng rồi nhập số vào các ô X, Y (vị trí) và W, H (chiều rộng, chiều cao) ở bảng thuộc tính bên phải, hoặc kéo tay cầm để đổi kích thước.
Điều này tương ứng trực tiếp với CSS ở các chương sau: vị trí và kích thước của một hộp trong Figma chính là top, left, width, height trong CSS. Thử đoạn dưới đây để thấy một hình chữ nhật đặt ở toạ độ (40, 20), kích thước 200 x 80:
<style>
.khung { position: relative; width: 320px; height: 120px; background: #eee; }
.hop { position: absolute; left: 40px; top: 20px; width: 200px; height: 80px; background: tomato; }
</style>
<div class="khung"><div class="hop" id="hop"></div></div>
<script>
const h = document.getElementById("hop");
const s = getComputedStyle(h);
console.log("X =", s.left, "| Y =", s.top);
console.log("W =", s.width, "| H =", s.height);
</script>Bài 1.4. Màu sắc
Mục tiêu: chọn và cấu hình màu sắc, dùng Style để giữ sự nhất quán.
- Lựa chọn màu sắc: Color Picker (chọn từ bảng màu, nhập mã HEX hoặc điều chỉnh theo RGB/HSL); Style Color (lưu và áp dụng màu dưới dạng Style để bảo đảm nhất quán).
- Cấu hình màu sắc: Opacity (độ trong suốt), Gradient (linear, radial, angular) và Image Fill (dùng hình ảnh làm nền cho phần tử).
- Sử dụng Styles: tạo và lưu màu thành Style rồi áp dụng cho nhiều phần tử; khi cập nhật một Style thì tất cả phần tử dùng Style đó cũng được cập nhật (Hình 1-34).
Trong CSS, ý tưởng "Style màu" tương ứng với biến CSS (bạn sẽ học ở buổi 7): khai báo một lần, dùng nhiều nơi, đổi một chỗ thì cả trang đổi. Hãy bấm chạy để thấy gradient và biến màu:
<style>
:root { --mau-chinh: #6495ED; }
.nen { background: linear-gradient(90deg, var(--mau-chinh), #ffffff); height: 50px; }
.trong-suot { background: rgba(100, 149, 237, 0.4); height: 50px; margin-top: 8px; }
.radial { background: radial-gradient(circle, var(--mau-chinh), #003366); height: 50px; margin-top: 8px; }
</style>
<div class="nen" id="a"></div>
<div class="trong-suot" id="b"></div>
<div class="radial" id="c"></div>
<script>
console.log("Biến --mau-chinh =", getComputedStyle(document.documentElement).getPropertyValue("--mau-chinh").trim());
console.log("Nền linear:", document.getElementById("a").style.background === "" ? "khai báo trong style" : "inline");
</script>Bài 1.5. Mặt nạ
Mục tiêu: thực hành với mặt nạ (mask) trong Figma (Hình 1-35 và Hình 1-36).
Dùng hình làm mặt nạ cho ảnh:
- Tạo các phần tử: vẽ phần tử làm mặt nạ và phần tử cần che.
- Xếp lớp phần tử: bảo đảm phần tử làm mặt nạ nằm trên phần tử cần che trong danh sách layers.
- Chọn các phần tử: giữ phím Shift và nhấp vào từng phần tử để chọn cả hai.
- Tạo mặt nạ: nhấp chuột phải và chọn Use as Mask.
- Chỉnh sửa mặt nạ: chọn phần tử mask trong danh sách layers và điều chỉnh kích thước, vị trí hoặc hình dạng.
Dùng chữ làm mặt nạ:
- Dùng công cụ Text (T) để nhập văn bản.
- Tạo một hình dạng khác để làm mặt nạ cho văn bản.
- Xếp lớp và chọn cả hai phần tử.
- Nhấp chuột phải và chọn "Use as Mask".
- Điều chỉnh kích thước và vị trí của mặt nạ.
Trong CSS, hiệu ứng "mặt nạ hình tròn" làm được bằng border-radius: 50% kèm overflow: hidden, còn "chữ làm mặt nạ cho nền" làm được bằng background-clip: text:
<style>
.anh { width: 120px; height: 120px; border-radius: 50%; overflow: hidden;
background: linear-gradient(135deg, orange, crimson); }
.chu { font-size: 44px; font-weight: bold; margin: 10px 0 0;
background: linear-gradient(90deg, #6495ED, #8A2BE2);
-webkit-background-clip: text; background-clip: text; color: transparent; }
</style>
<div class="anh" id="anh"></div>
<p class="chu">Codelab</p>
<script>
console.log("Bo tròn:", getComputedStyle(document.getElementById("anh")).borderRadius);
console.log("Chữ có nền gradient:", document.querySelector(".chu").textContent);
</script>Bài tập tự thực hành
Bài 1.6. Kiểm tra mã nguồn Website. Xem mã nguồn của trang Web https://minh-blogs.web.app (bấm chuột phải, chọn View Source, hoặc dùng Developer Tools) và cho biết: trang Web sử dụng bao nhiêu tệp CSS? Bao nhiêu tệp JS? (Gợi ý: dùng tab Sources hoặc Network; đếm theo cách của ví dụ ở mục 4.)
Bài 1.7. Thiết kế Website với Figma. Hãy vẽ lại Website https://minh-blogs.web.app trên Figma, chú ý giữ nguyên thiết kế (màu sắc, cỡ chữ, khoảng cách, bố cục).
Câu hỏi ôn tập
Chọn phương án trả lời đúng nhất. Các câu dưới đây thuộc nội dung của buổi này (đối chiếu đáp án ở phụ lục giáo trình); các câu 1.4, 1.5, 1.7 và 1.10 của chương 1 thuộc nội dung buổi 1.
1.1. HTML là viết tắt của cụm từ nào? A. HyperText Markup Language · B. Home Tool Markup Language · C. Hyperlinks and Text Markup Language · D. Hyper Tool Markup Language Đáp án: A — HyperText Markup Language (ngôn ngữ đánh dấu siêu văn bản).
1.2. Các chuẩn HTML được phát triển bởi tổ chức nào? A. Microsoft · B. Google · C. Mozilla · D. World Wide Web Consortium (W3C) Đáp án: D — W3C (cùng với WHATWG).
1.3. CSS là viết tắt của thuật ngữ nào? A. Colorful Style Sheets · B. Cascading Style Sheets · C. Computer Style Sheets · D. Creative Style Sheets Đáp án: B — Cascading Style Sheets.
1.6. Toàn bộ tài liệu HTML khai báo các thẻ bên trong thẻ nào? A. <head> và </head> · B. <body> và </body> · C. <html> và </html> · D. <main> và </main>
Đáp án: C — thẻ mở <html> và thẻ đóng </html>.
1.8. Khai báo <!DOCTYPE html> cho biết điều gì? A. Tài liệu HTML2 · B. Tài liệu HTML3 · C. Tài liệu HTML4 · D. Tài liệu HTML5
Đáp án: D — đây là một tài liệu HTML5.
1.9. DOM là viết tắt của thuật ngữ nào? A. Document Object Model · B. Document Online Model · C. Document Object Mode · D. Document Online Mode Đáp án: A — Document Object Model (Mô hình đối tượng tài liệu).
Bổ sung 1. HTML có phải là ngôn ngữ lập trình không? Vì sao không tạo được chức năng "động" chỉ bằng HTML? Đáp án: Không; HTML là ngôn ngữ đánh dấu, chỉ mô tả cấu trúc và nội dung. Hành vi "động" cần JavaScript (hoặc chương trình trên máy chủ).
Bổ sung 2. Thuộc tính rel="stylesheet" của thẻ link cho biết điều gì?
Đáp án: Mối quan hệ (relationship) giữa tài liệu HTML và tài liệu được liên kết đến là một bảng kiểu (stylesheet), dùng để định dạng phong cách cho tài liệu.
Bổ sung 3. Hai công cụ nào trong giáo trình cho phép viết HTML, CSS, JS trực tuyến với khung xem trước và có chế độ chia sẻ? Công cụ nào hỗ trợ cả template React, Vue, Angular? Đáp án: CodePen.io và jsFiddle.net (ngoài ra là CodeSandbox.io); CodeSandbox.io hỗ trợ các framework React, Vue, Angular, Node HTTP Server qua Template.
Bổ sung 4. Kể tên ba bảng điều khiển chính của Developer Tools và công dụng. Đáp án: Ví dụ Elements (xem/sửa DOM và CSS), Console (thông báo, lỗi, chạy lệnh JS), Network (các yêu cầu, mã trạng thái, header); còn Sources, Performance, Memory, Application, Security.
Bổ sung 5. Vì sao Adobe Illustrator và Figma phù hợp để thiết kế giao diện phẳng? Đáp án: Vì cả hai làm việc với dữ liệu vector nên phóng to/thu nhỏ không vỡ nét.
Bổ sung 6. Trình duyệt xử lý mã CSS và mã JavaScript trong tài liệu HTML bằng bộ phận nào? Đáp án: CSS chuyển cho bộ phân tích CSS (CSS Parser); JavaScript chuyển cho bộ máy JavaScript (JavaScript Engine); mã JavaScript chạy sau khi các chỉ thị CSS hoàn tất và có thể cập nhật DOM.
Sai lầm thường gặp
| Sai lầm | Hậu quả | Cách đúng |
|---|---|---|
| Nghĩ rằng HTML là ngôn ngữ lập trình | Cố viết điều kiện, vòng lặp bằng HTML và không chạy | HTML chỉ mô tả cấu trúc; dùng JavaScript cho logic |
Bỏ khai báo <!DOCTYPE html> |
Trình duyệt vào chế độ quirks, hiển thị lệch | Luôn đặt <!DOCTYPE html> ở dòng đầu tiên |
| Trộn mọi thứ (nội dung, định dạng, hành vi) vào một chỗ | Khó đọc, khó sửa, khó dùng lại | Tách CSS vào tệp .css, JS vào tệp .js rồi liên kết |
Viết link href="style.css" mà thiếu rel="stylesheet" |
Trình duyệt không hiểu đây là bảng kiểu nên không áp dụng | Đủ cả href và rel="stylesheet" |
Đếm mọi thẻ link, script là tệp CSS, JS |
Đếm sai khi làm Bài 1.6 | Chỉ đếm link rel="stylesheet" và script src |
| Sửa trang trong tab Elements rồi tưởng đã lưu | Tải lại trang là mất thay đổi | Sửa trong tệp nguồn (VS Code...) rồi lưu |
| Chọn công cụ trực tuyến cho dự án nhiều tệp lớn | Khó quản lý, khó triển khai | Dùng IDE trên máy (VS Code, JetBrains) cho dự án; công cụ trực tuyến để thử nhanh |
| Dùng thuộc tính CSS mới mà không kiểm tra trình duyệt hỗ trợ | Giao diện vỡ trên trình duyệt cũ | Tra bảng hỗ trợ trình duyệt trước khi dùng |
Tóm tắt
- HTML cung cấp cấu trúc và nội dung (thẻ → phần tử, tệp
.html/.htm); CSS kiểm soát trình bày, định dạng, bố cục; JavaScript kiểm soát hành vi. HTML không phải ngôn ngữ lập trình. - Tài liệu HTML bắt đầu bằng
DOCTYPE, nằm tronghtml, cóhead(metadata) vàbody(nội dung hiển thị). Chuẩn HTML do W3C và WHATWG phát triển; từ 2019 là HTML Living Standard. - CSS có ba phiên bản chính (CSS1 1996, CSS2 1998, CSS3 từ 1999); mức hỗ trợ khác nhau giữa các trình duyệt. Cách phổ biến nhất là tệp
.cssliên kết bằnglinkvớihrefvàrel="stylesheet". - JavaScript chạy ở máy khách (trình duyệt) và máy chủ (Node.js); trình duyệt tải tệp CSS, JS về, tạo DOM, chuyển CSS cho CSS Parser, JS cho JavaScript Engine; JS chạy sau CSS và cập nhật DOM.
- Công cụ thiết kế giao diện: Adobe (Dreamweaver, Photoshop, Illustrator) và Figma (trực tuyến, vector, cộng tác, phiên bản, plugin).
- Công cụ viết mã: VS Code, Sublime Text, JetBrains (IDE); CodePen, CodeSandbox, jsFiddle (trực tuyến).
- Công cụ trên trình duyệt: View Source và Developer Tools (Elements, Console, Sources, Network, Performance, Memory, Application, Security).