
Web Development Essentials 035.3: Khái niệm cơ bản về SQL
Tạo bảng SQLite, hiểu khóa chính và CHECK, dùng CRUD có WHERE và bind tham số từ Node.js; kiểm tra transaction rollback, mở lại dữ liệu và API driver.

Chọn màu, alpha, nền và phông chữ CSS dễ đọc; phân biệt px, em, rem, phần trăm, viewport; kiểm chứng cỡ chữ, khoảng dòng và shorthand bằng lab cục bộ.
Một trang hướng dẫn có thể đúng HTML nhưng vẫn khó đọc: chữ nhỏ, dòng quá sát, nền ảnh che nội dung hoặc màu nhạt làm thông báo biến mất. Khi phóng to chữ, một số thành phần còn giữ khoảng cách cũ. Để sửa có căn cứ, cần hiểu giá trị của thuộc tính đang được tính theo cơ sở nào, thay vì thử nhiều con số đến khi vừa mắt.
Bài 033.3, Tạo kiểu CSS, tham chiếu giáo trình Web Development Essentials 030-100, trang in 172–187, được biên soạn độc lập và đối chiếu nguồn ngày 23/10/2026. Kiến thức tiên quyết là HTML cơ bản, selector, cascade và kế thừa. Mục tiêu là chọn màu, nền, phông chữ, trang trí và đơn vị có thể giải thích, rồi kiểm tra cách chúng thay đổi theo kích thước chữ và viewport.
color đặt màu tiền cảnh, thường dùng cho chữ và giá trị currentColor. background-color đặt màu nền. Có thể viết màu sRGB bằng tên, mã hex như #135f75, hoặc hàm rgb(19, 95, 117). Ba cách biểu diễn không tạo ba mức ưu tiên; cascade vẫn phân xử như bài trước. Mã rút gọn chỉ hợp lệ khi từng cặp chữ số lặp, chẳng hạn #aabbcc thành #abc.
Alpha thể hiện độ đục của màu. Cú pháp hiện hành dễ đọc là rgb(19 95 117 / 0.15); dạng dùng dấu phẩy rgba(19, 95, 117, 0.15) cũng hợp lệ. Dùng dấu chấm thập phân trong mã CSS, bất kể giao diện máy dùng tiếng Việt. Viết rgba(255,0,0,0,5) tạo thừa thành phần, không có nghĩa là đỏ với alpha một nửa. Đây là lỗi cú pháp cần sửa khi đọc ví dụ cũ.
Alpha của riêng màu nền khác với opacity trên cả phần tử. Nền bán trong suốt vẫn có thể giữ chữ đục hoàn toàn. opacity: 0.5 ảnh hưởng kết quả tổng hợp của phần tử cùng nội dung con, nên có thể làm chữ nhạt đi ngoài dự định. Màu nhìn thấy còn phụ thuộc lớp nằm phía sau; không đo tương phản chỉ từ mã màu bán trong suốt mà bỏ qua nền thực tế.
Chọn cặp chữ và nền có độ tương phản phù hợp, đồng thời giữ nội dung văn bản như “Cần bổ sung thông tin”. Màu đỏ một mình không truyền đạt đủ trạng thái cho mọi người. Việc một cặp màu đạt ngưỡng tương phản cũng chưa chứng minh toàn trang đạt WCAG: focus, kích thước, thứ tự đọc và nhiều yêu cầu khác cần kiểm tra riêng.
px trong CSS là pixel tham chiếu, không phải lời hứa một đơn vị luôn bằng một điểm ảnh vật lý trên màn hình. Mật độ điểm ảnh, mức zoom và cách thiết bị ánh xạ CSS pixel có thể thay đổi. Quan hệ 1in = 96px là quan hệ trong hệ đơn vị CSS; không nên lấy thước đo trên mọi màn hình để kiểm định kích thước vật lý từ đó.
| Đơn vị | Cơ sở cần biết |
|---|---|
rem |
Kích thước chữ của phần tử gốc, thường là html |
em |
Với font-size: kích thước chữ được kế thừa; với nhiều độ dài khác: font-size của chính phần tử |
% |
Tùy thuộc tính; width thường theo chiều rộng containing block, font-size theo chữ của cha |
vw |
Một phần trăm chiều rộng viewport |
vh |
Một phần trăm chiều cao viewport lớn theo định nghĩa hiện hành |
dvh |
Một phần trăm chiều cao viewport động, hữu ích khi thanh trình duyệt di động thay đổi |
body không phải phần tử gốc HTML. Nếu html có font-size 16px, body là 20px thì 1rem vẫn tương ứng 16px trong trường hợp thông thường này. Với phần tử con, font-size: 1.25em tính theo chữ được kế thừa. Sau khi font-size đã tính ra, padding: 1em dùng cỡ chữ của chính phần tử. Các tầng em lồng nhau có thể nhân dồn; rem giúp nhiều thành phần chia sẻ một cơ sở.
Tỷ lệ phần trăm không có một công thức chung “theo cha” cho mọi thuộc tính. Chẳng hạn background-position có quy tắc khác width. Các trường hợp height phần trăm còn phụ thuộc kích thước xác định của containing block và ngữ cảnh bố cục. Tra trang tham chiếu của thuộc tính khi thay đổi điều kiện, thay vì suy rộng từ một ví dụ.
Phần mở rộng dvh giải quyết một nhu cầu thật của giao diện di động, nhưng không phải mọi khối đều nên cao đúng một màn hình. Nội dung dài cần được phép nở và cuộn. Với trang bài học, luồng nội dung tự nhiên thường dễ bảo trì hơn ép chiều cao cố định. Bài bố cục tiếp theo sẽ kiểm tra phần tràn trang cụ thể hơn.

Dùng một chuỗi font dự phòng, chẳng hạn system-ui, sans-serif. Font thực tế phụ thuộc máy và ký tự; cùng tên CSS không bảo đảm cùng độ rộng ở mọi thiết bị. Với tiếng Việt, kiểm tra dấu và ký tự thực tế. Web font còn liên quan giấy phép, tải mạng và cách hiển thị khi chưa tải xong, nên không thêm chỉ để làm bài tập phức tạp.
font-size điều khiển cỡ chữ; font-weight chọn độ đậm và font-style chọn kiểu thường, italic hoặc oblique. Oblique là kiểu nghiêng, không đồng nghĩa nghiêng đậm. Các font có thể cung cấp biến thể thật hoặc cần cơ chế thay thế, nên kết quả hình học không hoàn toàn giống nhau giữa hệ thống.
Với văn bản nhiều dòng, line-height: 1.6 là hệ số không đơn vị. Khi được kế thừa, nó giúp con tính chiều cao dòng theo cỡ chữ của con. Đặt line-height bằng em có thể khiến con kế thừa một độ dài đã tính ở cha, tạo kết quả bất ngờ nếu cỡ chữ con khác. Khoảng cách dòng còn cần đánh giá với font và nội dung thật, không có một con số đảm bảo đọc tốt cho mọi ngôn ngữ.
text-decoration thêm gạch chân hoặc gạch ngang. Giữ dấu hiệu nhận biết liên kết ngay cả khi người đọc không phân biệt màu. Gạch ngang bằng CSS chỉ là trình bày; khi cần biểu đạt nội dung bị xóa hoặc thay thế, cân nhắc ngữ nghĩa HTML thích hợp. list-style-type: square thay marker của ul mà không biến thứ tự thành có nghĩa; nếu thứ tự thao tác quan trọng, chọn ol ngay trong HTML.
Nền ảnh có thể dùng cho trang trí, nhưng nội dung quan trọng cần có trong HTML với văn bản hoặc alt phù hợp. URL tương đối trong stylesheet ngoài được giải theo URL của stylesheet, không theo tệp HTML. Vì vậy, di chuyển CSS sang thư mục khác có thể làm mất ảnh dù trang vẫn mở được.
background-repeat, background-size và background-position kiểm soát cách ảnh xuất hiện. Với vị trí phần trăm theo một trục, có thể hình dung độ dịch là tỷ lệ nhân với kích thước vùng đặt nền trừ kích thước ảnh. Một ảnh 40px đặt trong vùng 200px với vị trí ngang 50% có độ dịch 80px, không phải 100px. Khi ảnh bằng kích thước vùng, thay đổi tỷ lệ không tạo khoảng dịch theo trục đó.
Đường viền cần kiểu hiển thị như solid hoặc dashed; chỉ tăng border-width không nhất thiết làm viền xuất hiện nếu border-style vẫn none. Shorthand như border hoặc background giúp viết gọn nhưng cũng đặt lại những thuộc tính con không được nêu về giá trị ban đầu tương ứng. Khi sửa stylesheet có sẵn, đọc cả các longhand trước đó để tránh vô tình xóa ảnh nền hoặc thay kiểu viền.
Tạo index.html và style.css trong thư mục DEMO. Không cần ảnh tải ngoài vì nền dùng gradient trang trí. Mở trang trong browser và DevTools. Ghi lại font-size tính được, padding và line-height trước mỗi thay đổi; không dùng chiều cao toàn khối làm đại diện cho cỡ chữ vì nội dung có thể xuống dòng.
<!doctype html>
<html lang="vi">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DEMO giá trị CSS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="sheet">
<h1>Chuẩn bị yêu cầu DEMO</h1>
<p class="note">Chỉ ghi triệu chứng, không ghi thông tin bí mật.</p>
<p class="sample">Cỡ chữ theo cha. <span>Cỡ chữ con lớn hơn.</span></p>
<ul><li>Ghi thời điểm lỗi.</li><li>Ghi ứng dụng và thao tác.</li></ul>
<a href="#contact">Xem nơi tiếp nhận</a>
<h2 id="contact">Liên hệ DEMO</h2>
<p>Chưa gửi biểu mẫu hoặc dữ liệu ra mạng.</p>
</main>
</body>
</html>
html { font-size: 100%; }
body { margin: 0; color: #213641; background-color: #fff; font-family: system-ui, sans-serif; line-height: 1.6; }
.sheet { width: 80%; max-width: 40rem; margin: 1rem auto; }
h1 { font-size: 2rem; }
.note { color: #213641; background-color: rgb(19 95 117 / 0.15); border: 2px solid #135f75; padding: 1rem; }
.sample { font-size: 1.25em; padding: 1em; border: 1px dashed #607d8b; }
.sample span { font-size: 1.5em; }
ul { list-style-type: square; }
a { color: #135f75; text-decoration: underline; }
a:focus-visible { outline: 3px solid #b45309; outline-offset: 3px; }
.sheet { background-image: linear-gradient(to right, #eef4f2, #fff); background-repeat: no-repeat; background-size: 50% 8px; background-position: right top; }
Trong môi trường có chữ mặc định 16px, dự đoán h1 là 32px, sample là 20px, padding sample 20px, span 30px. Line-height sample là 32px và span 48px vì kế thừa hệ số 1.6. Với viewport rộng 1000px, sheet bị giới hạn ở 40rem, tức 640px. Ở viewport rộng 400px, width 80% cho 320px. Đây là các điều kiện đo cụ thể, không phải cam kết mặc định mọi browser luôn là 16px.
Trong DevTools, tạm đổi html thành font-size 20px. H1 phải lên 40px, sample 25px, span 37.5px; padding sample 25px. Khôi phục html về 100%. Tiếp theo đặt body font-size 20px, giữ html 16px: h1 vẫn 32px còn sample lên 25px. Thử nghiệm này phân biệt rem với em mà không cần đo bằng mắt. Xóa khai báo body vừa thêm và xác nhận phục hồi.
Quan sát gradient chỉ chiếm nửa chiều rộng phía trên. Tạm thêm .sheet { background: #fff; } sau cùng: ảnh nền bị đặt lại thành none. Hoàn tác rồi kiểm tra gradient trở lại. Nhấn Tab để thấy liên kết vẫn có dấu focus, không dựa vào màu nền trang trí.

Lab được chạy ngày 23/10/2026 với Chromium 151.0.7922.34 trong context mới, chặn mạng: các số đo trên, alpha hợp lệ, cú pháp alpha sai bị từ chối, focus và việc shorthand đặt lại nền đều được xác nhận bằng assertion. Hoàn tác trả các giá trị về ban đầu. Chưa thử thanh trình duyệt di động với dvh, điểm ảnh vật lý, font/ảnh tải ngoài, trình đọc màn hình hoặc toàn bộ WCAG.
Nếu số đo khác, kiểm tra stylesheet có tải, quy tắc thắng trong cascade, cỡ chữ gốc, viewport và thuộc tính đang đọc. Font fallback có thể làm xuống dòng khác dù font-size giống nhau. Một bản sửa tốt ghi rõ điều kiện đo và thay đổi đã hoàn tác, thay vì ép thiết bị người học giống ảnh minh họa.
Bạn có thể giải thích vì sao 1em padding khác 1em font-size, vì sao đổi body không đổi rem, và vì sao shorthand làm mất gradient? Alpha nền có làm con mờ như opacity không? Vì sao không dùng mỗi màu để báo lỗi? Trả lời bằng cơ chế rồi xác nhận bằng một thay đổi nhỏ trên bản DEMO.

Tạo bảng SQLite, hiểu khóa chính và CHECK, dùng CRUD có WHERE và bind tham số từ Node.js; kiểm tra transaction rollback, mở lại dữ liệu và API driver.

Tạo route Express, phục vụ CSS và render EJS; đọc query, params, body, kiểm tra dữ liệu form, escape HTML và phân biệt XSS với CSRF qua lab loopback.

Chạy Node.js LTS, phân biệt ES module và CommonJS, package.json và lockfile; cài package DEMO cục bộ, dùng npm ci và kiểm tra server HTTP trên loopback.

Chọn node DOM, phân biệt collection sống và tĩnh, textContent và innerHTML; cập nhật class, thuộc tính và sự kiện nút bằng chuột, bàn phím trong lab DEMO.