Buổi 7: CSS (2): màu sắc và định dạng
Bạn đã biết cách nhúng CSS và chọn đúng phần tử (buổi 6). Hôm nay là buổi "trang điểm" cho trang web: chọn màu cho trang của một trung tâm tin học, tô nền, kẻ viền, chỉnh chữ, làm đẹp bảng điểm, danh sách khóa học, liên kết trên thanh menu và cả biểu mẫu đăng ký khóa học. Cuối buổi bạn còn học cách gom các màu chủ đạo vào biến CSS để đổi cả giao diện chỉ bằng một dòng.
Mục tiêu buổi học
- Sau buổi này bạn có thể chỉ định màu bằng bốn cách: mã Hexadecimal, hàm rgb(), hàm hsl() và tên màu, đồng thời tạo độ trong suốt bằng opacity, rgba(), hsla().
- Bạn định dạng được nền (màu nền, hình nền, vị trí, cố định, viết rút gọn) và viền (kiểu, độ rộng, màu, từng phía, bo tròn).
- Bạn định dạng được văn bản (căn chỉnh, trang trí, chuyển đổi, khoảng cách, chiều cao dòng, bóng, font chữ).
- Bạn trình bày được bảng biểu, danh sách (kể cả bộ đếm CSS counters) và liên kết theo bốn trạng thái
:link,:visited,:hover,:active. - Bạn làm đẹp được biểu mẫu (ô nhập, nút bấm,
:focus,textarea,accent-color) và dùng biến CSS--tencùng hàmvar()để tái sử dụng giá trị.
Bản đồ buổi học
| Phần | Nội dung | Thời lượng gợi ý |
|---|---|---|
| 1. Sử dụng màu sắc | Hex, RGB, HSL, tên màu, độ trong suốt | 25 phút |
| 2. Định dạng nền | Màu nền, hình nền, vị trí, cố định, viết rút gọn | 20 phút |
| 3. Định dạng viền | Kiểu, độ rộng, màu, từng phía, rút gọn, bo tròn | 15 phút |
| 4. Định dạng văn bản | Màu, căn chỉnh, trang trí, khoảng cách, bóng, font | 30 phút |
| 5–7. Bảng, danh sách, liên kết | Thuộc tính bảng, list-style, counters, 4 trạng thái liên kết |
25 phút |
| 8–9. Biểu mẫu và biến | Làm đẹp form, accent-color, var() |
20 phút |
| Thực hành theo giáo trình | Bài 3.1, 3.2, 3.3 và bài tự thực hành 3.4–3.7 | 35 phút |
| Ôn tập, bài tập Codelab | Câu hỏi 3.1–3.10, bài tập chấm tự động | 10 phút |
Tổng cộng 180 phút, trong đó gõ mã và làm bài chiếm khoảng một nửa. Mọi ví dụ có nút ▶ Chạy thử đều chạy ngay trong trang: hãy sửa giá trị rồi bấm lại để xem kết quả thay đổi.
1. Sử dụng màu sắc
Giáo trình: Chương 3 — mục "Sử dụng màu sắc" (Màu hệ thập lục, Màu RGB, Màu HSL, Tên màu, Độ trong suốt).
Màu trong CSS có thể được xác định bằng bốn cách:
- Mã màu Hexadecimal: sử dụng mã màu hệ 16.
- Hàm rgb(): sử dụng hệ màu RGB.
- Hàm hsl(): sử dụng hệ màu HSL.
- Tên màu: sử dụng tên để xác định màu (có 140 tên).
Cả bốn cách đều dùng được ở bất kỳ thuộc tính nhận màu nào: color, background-color, border-color, outline-color, text-shadow... Hình dưới so sánh các cách viết cho cùng một màu.
#ff6347rgb(255, 99, 71)hsl(9, 100%, 64%)tomatoBốn cách viết khác nhau cho cùng một màu (tomato); rgba/hsla thêm kênh alpha để màu trong suốt.
Cách đọc hình: mỗi hàng là một màu, các cột là mã hex, bộ ba rgb() và bộ ba hsl() tương ứng. Hãy chú ý rằng cùng một màu có thể có nhiều cách viết, và trình duyệt đối xử chúng như nhau.
Màu hệ thập lục
Màu hệ thập lục (Hexadecimal) sử dụng mã màu gồm các thành phần RGB. Một màu Hexadecimal được quy định với cú pháp #RRGGBB, trong đó các số nguyên hệ thập lục phân RR (màu đỏ), GG (màu xanh lá) và BB (màu xanh dương) chỉ định các thành phần của màu. Tất cả các giá trị phải nằm trong khoảng từ 00 đến FF (theo hệ 16). Ví dụ, giá trị #0000ff được hiển thị là màu xanh lam, vì thành phần xanh lam được đặt thành giá trị cao nhất (ff) và các giá trị khác được đặt thành 00.
<style>
.o { color: white; padding: 14px; font: bold 16px sans-serif; margin: 4px 0; }
#p1 { background-color: #ff0000; } /* red */
#p2 { background-color: #00ff00; color: #003300; } /* green */
#p3 { background-color: #0000ff; } /* blue */
</style>
<div class="o" id="p1">#ff0000 — đỏ</div>
<div class="o" id="p2">#00ff00 — xanh lá</div>
<div class="o" id="p3">#0000ff — xanh lam</div>Mẹo: Khi cả ba cặp ký tự đều lặp đôi (ví dụ
#ffcc00), bạn có thể viết rút gọn ba ký tự#fc0. Mã#f00chính là#ff0000. Giáo trình dùng dạng đầy đủ, nhưng bạn sẽ gặp dạng rút gọn rất nhiều trong mã thực tế.
Để hiểu cơ chế, ví dụ JavaScript sau tách một mã hex thành ba thành phần số 0–255, đúng như CSS làm bên trong:
function hexToRgb(hex) {
const h = hex.replace("#", "");
const full = h.length === 3 ? h.split("").map(c => c + c).join("") : h;
const n = parseInt(full, 16);
return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
}
for (const m of ["#ff0000", "#0000ff", "#1abc9c", "#fc0"]) {
console.log(m, "→ rgb(" + hexToRgb(m).join(", ") + ")");
}Kết quả cho thấy #1abc9c (màu xanh ngọc mà giáo trình dùng nhiều lần cho tiêu đề và biểu mẫu) tương ứng rgb(26, 188, 156). Mỗi cặp hex là một số trong khoảng 0–255 viết ở hệ 16.
Màu RGB
Màu RGB được xác định bằng hàm rgb(), giá trị cho mỗi màu từ 0 đến 255. Cú pháp: rgb(đỏ, xanh lá cây, xanh dương). Mỗi tham số xác định cường độ của màu là một số nguyên trong khoảng từ 0 đến 255 hoặc giá trị phần trăm (từ 0% đến 100%). Ví dụ giá trị rgb(0,0,255) hiển thị màu xanh lam vì tham số xanh lam đặt giá trị cao nhất (255) và các giá trị khác bằng 0. Hai giá trị sau xác định màu bằng nhau: rgb(0,0,255) và rgb(0%, 0%, 100%).
<style>
.o { color: white; padding: 14px; font: bold 16px sans-serif; margin: 4px 0; }
#p1 { background-color: rgb(255, 0, 0); } /* Màu đỏ */
#p2 { background-color: rgb(0, 255, 0); color: #003300; } /* Màu xanh lá */
#p3 { background-color: rgb(0%, 0%, 100%); } /* Màu xanh lam, viết bằng phần trăm */
</style>
<div class="o" id="p1">rgb(255, 0, 0)</div>
<div class="o" id="p2">rgb(0, 255, 0)</div>
<div class="o" id="p3">rgb(0%, 0%, 100%)</div>RGB có thể dùng thêm alpha, chỉ định độ trong suốt của đối tượng. Tham số alpha là một số từ 0.0 (hoàn toàn trong suốt) đến 1.0 (hoàn toàn đục). Phiên bản có alpha gọi là rgba():
<style>
body { background: repeating-linear-gradient(45deg, #fff 0 12px, #e8e8e8 12px 24px); font: bold 16px sans-serif; }
.o { padding: 14px; margin: 4px 0; }
#p1 { background-color: rgba(255, 0, 0, 0.3); } /* Màu đỏ, trong suốt 0.3 */
#p2 { background-color: rgba(0, 255, 0, 0.3); } /* Màu xanh lá, trong suốt 0.3 */
#p3 { background-color: rgba(0, 0, 255, 0.3); } /* Màu xanh lam, trong suốt 0.3 */
</style>
<div class="o" id="p1">rgba(255, 0, 0, 0.3)</div>
<div class="o" id="p2">rgba(0, 255, 0, 0.3)</div>
<div class="o" id="p3">rgba(0, 0, 255, 0.3)</div>Nền caro phía sau giúp bạn thấy rõ: alpha 0.3 chỉ giữ lại 30% độ đục nên hoa văn bên dưới vẫn lộ ra.
Màu HSL
HSL là một hệ màu phổ biến để xác định màu sắc; để dùng cần gọi hàm hsl(). HSL là viết tắt của màu sắc (hue), độ bão hòa (saturation) và độ sáng (lightness), cú pháp hsl(hue, saturation, lightness).
- Hue là độ trên bánh xe màu (từ 0 đến 360): 0 (hoặc 360) là màu đỏ, 120 là xanh lá cây, 240 là xanh lam.
- Saturation là giá trị phần trăm: 0% là màu xám, 100% là màu đầy đủ.
- Lightness cũng là phần trăm: 0% là màu đen, 100% là màu trắng, 50% là màu "chuẩn".
Các giá trị màu HSLA là phần mở rộng của HSL với kênh alpha, chỉ định độ mờ của đối tượng.
<style>
h2 { margin: 4px 0; padding: 10px; font: bold 18px sans-serif; color: white; }
</style>
<h2 style="background-color:hsl(0, 100%, 50%);">hsl(0, 100%, 50%)</h2>
<h2 style="background-color:hsl(240, 100%, 50%);">hsl(240, 100%, 50%)</h2>
<h2 style="background-color:hsl(147, 50%, 47%);">hsl(147, 50%, 47%)</h2>HSL rất hữu ích khi cần thay đổi màu sắc của các thành phần như nút bấm, tiêu đề và nền. Việc điều chỉnh saturation và lightness giúp tạo ra các sắc độ khác nhau mà vẫn giữ được tông màu gốc: bạn chỉ cần giữ nguyên hue.
<style>
.row { display: flex; }
.row div { flex: 1; padding: 22px 0; text-align: center; font: bold 13px sans-serif; color: white; }
</style>
<div class="row">
<div style="background: hsl(210, 70%, 20%)">L 20%</div>
<div style="background: hsl(210, 70%, 35%)">L 35%</div>
<div style="background: hsl(210, 70%, 50%)">L 50%</div>
<div style="background: hsl(210, 70%, 70%)">L 70%</div>
<div style="background: hsl(210, 70%, 90%); color: #234">L 90%</div>
</div>Năm ô trên cùng hue 210 (xanh dương), cùng saturation 70%, chỉ đổi lightness: đó là cách tạo bảng sắc độ (palette) cho nút bấm bình thường, khi rê chuột và khi nhấn.
Bây giờ bạn tự điều chỉnh các thanh trượt để thấy mối liên hệ giữa ba hệ màu:
🎨 Bộ trộn màu RGB / HSL
Kéo thanh trượt, bánh xe màu hoặc gõ mã HEXrgb(255, 99, 71)hsl(9, 100%, 64%)Cách dùng: kéo từng thanh R, G, B (hoặc H, S, L) và nhìn mã #hex, rgb(), hsl() thay đổi đồng thời. Hãy thử đặt H = 0, 120, 240 và S = 0% để kiểm chứng điều giáo trình nói về bánh xe màu.
Giáo trình: Cuối mục "Màu HSL", giáo trình dẫn tới công cụ "Trộn màu RGB và HSL" của khoa tại fit.neu.edu.vn/smartdoc. Bạn có thể dùng mô phỏng ngay trên trang này thay cho công cụ đó.
Tên màu
Trong CSS, một màu có thể được chỉ định bằng tên màu. Các tên này gọi là "màu được đặt tên" (named colors) và bao gồm red, blue, green, yellow, black, white... cùng 140 tên khác. Tên màu không phân biệt hoa thường: Tomato và tomato như nhau.
Các trình duyệt hiện đại đều hỗ trợ sẵn bộ tên màu chuẩn. Tuy vậy, danh sách tên màu không phải lúc nào cũng đồng nhất giữa các trình duyệt, và không phải tên màu nào cũng được hỗ trợ ở mọi nơi. Vì thế, trong một số trường hợp, dùng mã HEX hoặc RGB sẽ chắc chắn hơn để đảm bảo tính nhất quán giữa các nền tảng. Ví dụ của giáo trình dùng tên màu cho nền:
<style>
div {
background-color: darkseagreen;
}
</style>
<h1 style="background-color:Tomato;">Tiêu đề</h1>
<p style="background-color:Orange;">Đoạn văn</p>
<div> Khối div</div>Hình 3-16 của giáo trình chính là kết quả này: tiêu đề nền Tomato (đỏ cà chua), đoạn văn nền Orange (cam), khối div nền darkseagreen (xanh lục biển sẫm).
Độ trong suốt
Thuộc tính opacity điều chỉnh độ mờ của phần tử, nhận giá trị từ 0.0 đến 1.0; giá trị càng thấp, phần tử càng trong suốt. Khi dùng opacity, toàn bộ phần tử, bao gồm cả nội dung bên trong và viền, trở nên trong suốt theo mức độ được chỉ định.
<style>
body { font: 15px sans-serif; background: repeating-linear-gradient(45deg, #fff 0 12px, #eee 12px 24px); }
div { background: #2d6a4f; color: white; padding: 8px; margin: 3px 0; }
</style>
<div style="opacity: 1;">Độ trong suốt: 1</div>
<div style="opacity: 0.75;">Độ trong suốt: 0.75</div>
<div style="opacity: 0.5;">Độ trong suốt: 0.5</div>
<div style="opacity: 0.25;">Độ trong suốt: 0.25</div>
<div style="opacity: 0;">Độ trong suốt: 0</div>Ô cuối cùng với opacity: 0 vô hình nhưng vẫn chiếm chỗ và vẫn nhận được thao tác chuột (khác với display: none).
opacity thường đi cùng lớp giả :hover để đổi độ mờ khi rê chuột:
article .content img:hover {
opacity: .75;
}Cảnh báo:
opacitykhông kế thừa nhưng tác động lên toàn bộ phần tử, nên khi bạn dùng nó để làm mờ nền thì chữ bên trong cũng mờ theo và có thể khó đọc. Nếu chỉ muốn nền trong suốt còn chữ vẫn rõ, hãy dùng màu RGBA (hoặc HSLA) chobackground, như ví dụdiv { background: rgba(76, 175, 80, 0.3) }của giáo trình.
Ví dụ so sánh trực tiếp hai cách:
<style>
body { font: bold 16px sans-serif; background: repeating-linear-gradient(45deg, #fff 0 12px, #e6e6e6 12px 24px); }
.a, .b { padding: 16px; margin: 6px 0; border: 2px solid #1b4332; color: #1b4332; }
.a { background: rgb(76, 175, 80); opacity: 0.3; }
.b { background: rgba(76, 175, 80, 0.3); }
</style>
<div class="a">opacity: 0.3 — chữ và viền đều mờ</div>
<div class="b">rgba(…, 0.3) — chỉ nền mờ, chữ và viền rõ</div>Ví dụ thực tế: lớp phủ (overlay) tối mờ trên ảnh bìa để chữ trắng nổi bật hầu như luôn viết bằng rgba(0, 0, 0, 0.5) chứ không dùng opacity.
Ví dụ thực tế: Trang tin tức dùng
rgba(0,0,0,0.55)làm nền cho dòng chú thích nằm đè lên ảnh. Ảnh vẫn nhìn xuyên qua mờ mờ, chữ trắng giữ nguyên độ đậm. Nếu dùngopacity: 0.55cho dòng chú thích thì chữ cũng bị mờ đi 45%.
Vừa học xong bốn cách viết màu và độ trong suốt, bạn hãy làm các bài sau để chuyển một màu sang nhiều dạng viết, dùng rgba, hsl và phân biệt opacity với nền trong suốt.
2. Định dạng nền
Giáo trình: Chương 3 — mục "Định dạng nền" (Màu nền, Hình nền, Vị trí hình nền, Hình nền cố định, Cách viết rút gọn).
Nền (background) là lớp nằm sau nội dung của phần tử. CSS có một họ thuộc tính background-* để điều khiển từng khía cạnh của lớp nền này.
| Thuộc tính | Chức năng | Ví dụ giá trị |
|---|---|---|
background-color |
màu nền | #1abc9c, rgba(0,0,0,.5) |
background-image |
hình nền | url('anh.png') |
background-repeat |
lặp hình nền | repeat, repeat-x, repeat-y, no-repeat |
background-size |
kích thước hình nền | auto, cover |
background-position |
vị trí hình nền | right top, 5px center |
background-attachment |
cuộn cùng trang hay cố định | scroll, fixed |
background |
viết rút gọn tất cả | xem bên dưới |
Màu nền
Thuộc tính background-color quy định màu nền của một phần tử. Ví dụ sau thay đổi màu nền của thẻ <header> (ví dụ gốc của giáo trình, trang "Minh's Page"):
<!DOCTYPE html>
<html lang="en">
<head>
<style>
header {
background: #1abc9c;
color: white;
padding: 60px;
text-align: center;
}
</style>
</head>
<body>
<header>
<h1>Minh's Page</h1>
<p>Lập kế hoạch - Ghi chú thích - <b>Viết mã lệnh</b> - Kiểm thử</p>
</header>
</body>
</html>Hình 3-18 của giáo trình là một khối màu xanh ngọc #1abc9c với chữ trắng căn giữa. Bạn thấy padding: 60px đẩy nội dung ra xa mép khối, còn text-align: center căn giữa chữ.
Hình nền
Thuộc tính background-image quy định một hình ảnh làm nền cho phần tử HTML. Theo mặc định, hình ảnh được lặp lại theo cả chiều ngang và chiều dọc để bao phủ toàn bộ phần tử.
header {
background-image: url('/images/1053.png');
color: white;
padding: 60px;
text-align: center;
}Đoạn mã trên dùng tệp ảnh của giáo trình nên không chạy được trong trang này. Ví dụ dưới đây dùng một hình SVG nhỏ nhúng thẳng vào CSS, bạn thấy rõ ảnh được lặp kín khung:
<style>
header {
background-color: #264653;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Ccircle cx='20' cy='20' r='8' fill='%232a9d8f'/%3E%3C/svg%3E");
color: white;
padding: 50px;
text-align: center;
font-family: sans-serif;
}
</style>
<header>
<h1>Minh's Page</h1>
<p>Hình nền lặp theo cả hai chiều</p>
</header>Để lặp theo một chiều cụ thể, dùng repeat-x hoặc repeat-y. Để hình nền không lặp, dùng no-repeat. Với hình không lặp mà muốn vừa khít với hộp chứa nó, nên dùng thuộc tính background-size với giá trị cover; giá trị mặc định là auto (giữ kích thước gốc của ảnh).
header {
color: white;
padding: 60px;
text-align: center;
background-image: url('/public/images/feature.jpg');
background-size: auto; /* mặc định: giữ kích thước gốc của ảnh */
}Ví dụ sau dùng chuyển màu thay cho ảnh để bạn tự so sánh repeat, repeat-x, no-repeat: sửa giá trị background-repeat rồi bấm chạy lại.
<style>
.khung {
height: 80px; margin: 6px 0; border: 1px solid #999;
background-color: #fdf6e3;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Crect width='30' height='30' rx='6' fill='%23e76f51'/%3E%3C/svg%3E");
font: 13px sans-serif;
}
.a { background-repeat: repeat; }
.b { background-repeat: repeat-x; }
.c { background-repeat: no-repeat; }
</style>
<div class="khung a">repeat (mặc định)</div>
<div class="khung b">repeat-x</div>
<div class="khung c">no-repeat</div>Mở rộng:
background-imagekhông chỉ nhậnurl(). Hàmlinear-gradient()tạo chuyển màu (gradient) mà không cần tệp ảnh, ví dụbackground-image: linear-gradient(135deg, #1abc9c, #16a085);. Đây cũng là nội dung bài tự thực hành 3.4 của giáo trình ("sử dụng màu chuyển sắc để nhấn mạnh vùng quan trọng").
<style>
.hero {
background-image: linear-gradient(135deg, #1abc9c, #16a085);
color: white; padding: 40px; text-align: center; font-family: sans-serif;
}
.hero2 { background-image: linear-gradient(to right, #f12711, #f5af19); color: white; padding: 20px; text-align: center; font-family: sans-serif; margin-top: 8px; }
</style>
<div class="hero"><h2>Chuyển màu 135 độ</h2></div>
<div class="hero2">Chuyển màu từ trái sang phải</div>Vị trí hình nền
Thuộc tính background-position xác định vị trí của hình nền trong khung. Ví dụ định vị hình nền ở góc trên bên phải:
header {
color: white;
padding: 60px;
text-align: center;
background-image: url('/public/images/feature.jpg');
background-position: right top;
}Giá trị có thể là từ khóa (left, center, right, top, bottom) hoặc độ dài/phần trăm (5px center, 50% 50%). Ví dụ sau đặt một hình tròn vào ba vị trí để bạn thấy khác biệt (có no-repeat để chỉ xuất hiện một lần):
<style>
.khung {
height: 70px; margin: 6px 0; border: 1px solid #999; background-color: #f1faee;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Ccircle cx='20' cy='20' r='18' fill='%23e63946'/%3E%3C/svg%3E");
background-repeat: no-repeat; font: 13px sans-serif;
}
.a { background-position: right top; }
.b { background-position: center center; }
.c { background-position: 5px bottom; }
</style>
<div class="khung a">right top</div>
<div class="khung b">center center</div>
<div class="khung c">5px bottom</div>Hình nền cố định
Thuộc tính background-attachment cho phép hình nền cuộn cùng nội dung trang (scroll, mặc định) hoặc được cố định (fixed), không di chuyển theo phần còn lại của trang. Hiệu ứng "hình nền đứng yên, nội dung trượt qua" (parallax đơn giản) đến từ giá trị fixed.
header {
color: white;
padding: 60px;
text-align: center;
background-color: #1abc9c;
background-image: url('/public/images/feature.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
background-position: top left;
}Cách viết rút gọn
Để rút ngắn mã, có thể chỉ định mọi thuộc tính nền trong một thuộc tính background duy nhất. Khi dùng cách rút gọn, thứ tự các giá trị là: background-color, background-image, background-repeat, background-attachment, background-position.
header {
color: white;
padding: 60px;
text-align: center;
background: #1abc9c url('/public/images/feature.jpg') no-repeat fixed top left;
}Ví dụ chạy được cùng quy tắc thứ tự (dùng hình nhúng để khỏi phụ thuộc tệp):
<style>
header {
color: white; padding: 40px; text-align: center; font-family: sans-serif;
background: #1abc9c url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Ccircle cx='30' cy='30' r='26' fill='%23ffffff' fill-opacity='.35'/%3E%3C/svg%3E") no-repeat fixed top left;
}
</style>
<header><h2>Viết rút gọn: màu + ảnh + lặp + cố định + vị trí</h2></header>Lưu ý: Dùng
background: ...rút gọn sẽ đặt lại về mặc định mọi giá trị nền bạn không nêu. Nếu bạn viếtbackground: red;sau một dòngbackground-image: url(...), hình nền sẽ biến mất. Thứ tự các khai báo vì thế rất quan trọng.
3. Định dạng viền
Giáo trình: Chương 3 — mục "Định dạng viền" (Kiểu viền, Độ rộng viền, Màu viền, Viền từng phía, Cách viết rút gọn, Viền bo tròn).
Viền (border) là đường bao quanh nội dung và phần đệm (padding) của phần tử. Để một viền xuất hiện bạn cần ít nhất kiểu viền (border-style), vì mặc định kiểu là none.
Kiểu viền
Thuộc tính border-style quy định kiểu đường viền. Các giá trị thông dụng:
- dotted — đường viền chấm
- dashed — đường viền nét đứt
- solid — đường viền liền
- double — đường viền đôi
- none — không có border
- hidden — đường viền ẩn
Ngoài ra còn groove, ridge, inset, outset (các kiểu tạo cảm giác nổi/chìm). Thuộc tính border-style có thể nhận từ một đến bốn giá trị theo thứ tự trên, phải, dưới, trái. Ví dụ các kiểu viền khác nhau:
<style>
p { padding: 6px 10px; margin: 5px 0; font: 14px sans-serif; border-width: 4px; border-color: #1d3557; }
p.dotted {border-style: dotted;}
p.dashed {border-style: dashed;}
p.solid {border-style: solid;}
p.double {border-style: double;}
p.groove {border-style: groove;}
p.ridge {border-style: ridge;}
p.inset {border-style: inset;}
p.outset {border-style: outset;}
p.none {border-style: none;}
p.hidden {border-style: hidden;}
p.mix {border-style: dotted dashed solid double;}
</style>
<p class="dotted">dotted</p>
<p class="dashed">dashed</p>
<p class="solid">solid</p>
<p class="double">double</p>
<p class="groove">groove</p>
<p class="ridge">ridge</p>
<p class="inset">inset</p>
<p class="outset">outset</p>
<p class="none">none</p>
<p class="hidden">hidden</p>
<p class="mix">mix: dotted dashed solid double (trên, phải, dưới, trái)</p>Lưu ý: Với phần tử đơn,
nonevàhiddentrông giống nhau. Chúng chỉ khác nhau khi xung đột viền trong bảng gộp (border-collapse: collapse):hiddenthắng mọi kiểu khác, cònnonethì thua.
div {margin: 20px;border: 10px solid;padding: 20px;width: 500px;}
*, *::before, *::after { box-sizing: border-box; }Mỗi phần tử là một hộp gồm nội dung, đệm (padding), viền (border) và lề (margin); với content-box, width chỉ tính phần nội dung.
Hình trên nhắc lại mô hình hộp mà buổi 8 sẽ học kỹ: viền nằm giữa phần đệm (padding) và phần lề (margin). Hãy nhớ vị trí này để hiểu vì sao tăng độ rộng viền làm hộp to ra.
Độ rộng viền
Thuộc tính border-width chỉ định độ dày của đường viền. Độ rộng có thể là một kích thước cụ thể (px, pt, cm, em...) hoặc một trong ba từ khóa định sẵn: thin (mỏng), medium (trung bình), thick (dày). Thuộc tính này cũng nhận từ một đến bốn giá trị (trên, phải, dưới, trái).
<style>
p { margin: 6px 0; padding: 8px; font: 14px sans-serif; border-style: solid; }
p.one { border-width: 5px; }
p.two { border-width: medium; }
p.three { border-width: 2px 10px 4px 20px; }
</style>
<p class="one">border-width: 5px</p>
<p class="two">border-width: medium</p>
<p class="three">border-width: 2px 10px 4px 20px (trên, phải, dưới, trái)</p>Màu viền
Thuộc tính border-color thiết lập màu viền; cũng nhận từ một đến bốn giá trị. Nếu bỏ qua, màu viền mặc định là màu chữ của phần tử (currentColor).
<style>
p { margin: 6px 0; padding: 8px; font: 14px sans-serif; border-style: solid; border-width: 5px; }
p.one { border-color: red; }
p.two { border-color: green; }
p.three { border-color: red green blue yellow; }
</style>
<p class="one">border-color: red</p>
<p class="two">border-color: green</p>
<p class="three">border-color: red green blue yellow</p>Viền từng phía
Trong CSS có các thuộc tính định kiểu viền cho từng phía (trên, phải, dưới, trái): border-top-style, border-right-style, border-bottom-style, border-left-style. Tương tự có border-top-width, border-top-color..., hoặc viết gộp border-top, border-left...
<style>
p {
padding: 14px; font: 14px sans-serif; border-width: 4px; border-color: #e63946;
border-top-style: dotted;
border-right-style: solid;
border-bottom-style: dotted;
border-left-style: solid;
}
</style>
<p>Trên và dưới chấm, trái và phải liền</p>Cách viết rút gọn
Để rút ngắn mã, có thể chỉ định tất cả thuộc tính viền trong một thuộc tính border, theo thứ tự độ rộng kiểu màu. Ví dụ thiết lập cho thẻ p có viền 5 px liền màu đỏ:
p {
border: 5px solid red;
}Viền bo tròn
Thuộc tính border-radius bo tròn các góc của đường viền. Giá trị lớn dần cho góc tròn hơn; 50% trên hình vuông cho hình tròn.
<style>
p { padding: 10px; margin: 8px 0; font: 14px sans-serif; border: 2px solid red; border-radius: 5px; }
.nut { display: inline-block; padding: 10px 24px; border: 2px solid #1abc9c; border-radius: 30px; font: bold 14px sans-serif; color: #1abc9c; }
.tron { width: 70px; height: 70px; border: 3px solid #264653; border-radius: 50%; display: inline-block; }
</style>
<p>border: 2px solid red; border-radius: 5px;</p>
<span class="nut">Nút viên thuốc (30px)</span>
<span class="tron"></span>Mẹo: Khi viền, nền và bo góc thường xuất hiện cùng nhau (thẻ sản phẩm, nút bấm, chip), hãy tập thói quen viết ba dòng liền kề:
border: 1px solid ...; border-radius: ...; background: ...;.
Vừa học xong nền và viền, hãy làm các bài sau để dựng banner nền chuyển màu, khung nét đứt và hộp viền bốn cạnh bốn màu.
4. Định dạng văn bản
Giáo trình: Chương 3 — mục "Định dạng văn bản" (Màu sắc văn bản, Căn chỉnh, Trang trí, Chuyển đổi, Thụt đầu dòng, Khoảng cách chữ, Khoảng cách từ, Chiều cao dòng, Hướng văn bản, Bóng văn bản, Font chữ).
Văn bản là thứ người dùng đọc nhiều nhất trên một trang web, nên định dạng chữ quyết định phần lớn cảm giác "dễ đọc" hay "mệt mắt". Mục này gồm hai nhóm: các thuộc tính văn bản (color, text-*, letter-spacing, word-spacing, line-height, direction) và các thuộc tính font (font-*).
Màu sắc văn bản
Dùng thuộc tính color để xác định màu cho văn bản. Thuộc tính này được kế thừa: đặt color cho body thì mọi phần tử con đều dùng màu đó, trừ khi bị ghi đè.
<style>
body { color: blue; font-family: sans-serif; }
h1 { color: green; }
</style>
<h1>Tiêu đề màu xanh lá</h1>
<p>Đoạn văn kế thừa màu xanh dương từ body.</p>Lưu ý: Màu chữ phải tương phản đủ với màu nền. Chữ xám nhạt trên nền trắng khó đọc, nhất là với người kém thị lực. Quy tắc nhanh: nền tối thì chữ sáng, nền sáng thì chữ tối.
Căn chỉnh văn bản
Thuộc tính text-align căn lề văn bản: left, right, center. Khi đặt thành justify, các dòng được kéo giãn để có chiều rộng bằng nhau (căn đều hai bên).
<style>
body { font-family: sans-serif; margin: 8px; }
h1 { text-align: center; font-size: 20px; margin: 4px 0; }
h2 { text-align: left; font-size: 18px; margin: 4px 0; }
h3 { text-align: right; font-size: 16px; margin: 4px 0; }
div { text-align: justify; font-size: 14px; border: 1px dashed #aaa; padding: 6px; }
</style>
<h1>text-align: center</h1>
<h2>text-align: left</h2>
<h3>text-align: right</h3>
<div>text-align: justify kéo giãn khoảng trắng để các dòng trong đoạn văn dài có chiều rộng bằng nhau, tạo hai mép trái phải thẳng như trang báo giấy. Hãy thu hẹp khung xem trước để thấy các dòng đều nhau.</div>Trang trí văn bản
Thuộc tính text-decoration thiết lập (hoặc loại bỏ) trang trí văn bản: overline (gạch trên), line-through (gạch ngang giữa), underline (gạch chân), none (bỏ trang trí, thường dùng để bỏ gạch chân của liên kết).
<style>
body { font-family: sans-serif; }
h2 { text-decoration: overline; }
h3 { text-decoration: line-through; }
h4 { text-decoration: underline; }
</style>
<h2>Gạch trên (overline)</h2>
<h3>Gạch ngang (line-through)</h3>
<h4>Gạch chân (underline)</h4>Cảnh báo: Không nên gạch chân văn bản không phải là một liên kết, vì điều này thường gây nhầm lẫn cho người đọc: người dùng quen với quy ước "chữ gạch chân là bấm được".
Chuyển đổi văn bản
Thuộc tính text-transform xác định chữ hoa/chữ thường: uppercase (toàn chữ hoa), lowercase (toàn chữ thường), capitalize (viết hoa chữ cái đầu mỗi từ). Mã HTML vẫn giữ nguyên chữ gốc; chỉ cách hiển thị thay đổi, nên bạn có thể đổi kiểu hiển thị mà không phải sửa nội dung.
<style>
body { font-family: sans-serif; }
p.uppercase { text-transform: uppercase; }
p.lowercase { text-transform: lowercase; }
p.capitalize { text-transform: capitalize; }
</style>
<p class="uppercase">thiết kế web với html và css</p>
<p class="lowercase">THIẾT KẾ WEB VỚI HTML VÀ CSS</p>
<p class="capitalize">thiết kế web với html và css</p>Thụt đầu dòng
Thuộc tính text-indent xác định độ thụt vào của dòng đầu tiên trong một đoạn văn bản, thường dùng để mô phỏng cách trình bày đoạn văn trong sách.
<style>
p { text-indent: 50px; font: 15px/1.5 sans-serif; }
</style>
<p>Chỉ dòng đầu tiên của đoạn này bị thụt vào 50px, các dòng sau vẫn thẳng với mép trái của khung nội dung. Đây là cách trình bày quen thuộc của sách in.</p>Khoảng cách chữ
Thuộc tính letter-spacing xác định khoảng cách giữa các ký tự. Giá trị dương làm chữ thưa ra, giá trị âm làm chữ sát lại. Ví dụ minh họa tăng hoặc giảm khoảng trắng giữa các ký tự:
<style>
body { font-family: sans-serif; }
h1 { letter-spacing: 3px; }
h2 { letter-spacing: -3px; }
</style>
<h1>Chữ thưa 3px</h1>
<h2>Chữ sát -3px</h2>Khoảng cách từ
Thuộc tính word-spacing xác định khoảng cách giữa các từ (không phải ký tự). Ví dụ:
<style>
body { font-family: sans-serif; }
h1 { word-spacing: 10px; }
h2 { word-spacing: -5px; }
</style>
<h1>Các từ cách xa nhau hơn</h1>
<h2>Các từ sát nhau hơn</h2>Hãy phân biệt hai thuộc tính: letter-spacing tác động giữa từng chữ cái, word-spacing tác động giữa các từ. Nhầm hai thuộc tính này là lỗi rất hay gặp ở người mới học.
Chiều cao dòng
Thuộc tính line-height dùng để tăng/giảm khoảng cách giữa các dòng. Giá trị mặc định là normal (tương đương khoảng 1.2 lần cỡ chữ). Giá trị không đơn vị như 1.8 nghĩa là "1,8 lần cỡ chữ hiện tại" và được khuyên dùng vì tự co giãn theo cỡ chữ của phần tử con.
<style>
p { width: 260px; float: left; margin: 4px 10px; background: #f1faee; font: 14px sans-serif; }
p.small { line-height: 0.8; }
p.big { line-height: 1.8; }
</style>
<p class="small">line-height: 0.8. Các dòng chữ chồng sát vào nhau, khó đọc nếu đoạn dài.</p>
<p class="big">line-height: 1.8. Các dòng cách nhau thoáng hơn, đoạn văn dài đọc dễ chịu hơn nhiều.</p>Mẹo: Với đoạn văn dài,
line-heighttừ 1.5 đến 1.8 thường dễ đọc nhất. Giáo trình dùngline-height: 1.5chobodytrong cả ba bài thực hành.
Hướng văn bản
Thuộc tính direction thay đổi hướng văn bản. Giá trị mặc định là ltr (trái sang phải). Để văn bản viết theo chiều từ phải sang trái (như tiếng Ả Rập, tiếng Do Thái), dùng rtl:
<style>
p { font: 15px sans-serif; border: 1px solid #ccc; padding: 6px; }
p.rtl { direction: rtl; }
</style>
<p>direction: ltr (mặc định) — dấu chấm cuối câu.</p>
<p class="rtl">direction: rtl — dấu chấm cuối câu.</p>Hãy để ý vị trí dấu chấm cuối câu và phía mà đoạn văn dồn tới: với rtl, đoạn văn bám theo mép phải của khung.
Bóng văn bản
Thuộc tính text-shadow thêm bóng cho văn bản. Hai số đầu là độ lệch ngang và độ lệch dọc; tùy chọn thêm độ nhòe (blur) và màu. Ví dụ của giáo trình chỉ định bóng ngang 3 px, bóng dọc 2 px, màu đỏ:
<style>
body { font-family: sans-serif; }
h1 { text-shadow: 3px 2px red; }
h2 { text-shadow: 2px 2px 6px rgba(0, 0, 0, .45); }
</style>
<h1>Bóng đỏ lệch 3px 2px</h1>
<h2>Bóng mờ nhòe 6px</h2>Font chữ
Để thiết lập font chữ cho một trang HTML hoặc cho từng phần tử, dùng năm thuộc tính sau:
- font-family: chọn kiểu chữ (typeface).
- font-style: hiển thị chữ nghiêng (
italichoặcoblique). - font-variant: tạo chữ hoa nhỏ (
small-caps). - font-weight: tăng giảm độ đậm của font.
- font-size: xác định kích cỡ font.
font-family
Thuộc tính font-family chọn font chữ. Các font được hầu hết trình duyệt hỗ trợ gồm: Arial, Verdana, Helvetica, Tahoma, Trebuchet MS (nhóm sans-serif); Times New Roman, Georgia, Garamond (nhóm serif); Courier New (nhóm monospace).
Khi dùng font-family, nên xác định nhiều hơn một giá trị. Nếu tên font có dấu cách thì phải đặt trong dấu nháy kép, ví dụ "Times New Roman". Nếu trình duyệt không hỗ trợ font đầu tiên thì thử font kế tiếp,... Nên bắt đầu bằng font mong muốn và kết thúc bằng một họ font tổng quát (generic family) (serif, sans-serif, monospace) để trình duyệt chọn font tương tự khi không có font nào khả dụng.
p {
font-family: "Times New Roman", Times, serif;
}<style>
p { font-size: 18px; margin: 6px 0; }
.a { font-family: Arial, Helvetica, sans-serif; }
.b { font-family: Georgia, "Times New Roman", serif; }
.c { font-family: "Courier New", monospace; }
.d { font-family: "Font-Khong-Ton-Tai", sans-serif; }
</style>
<p class="a">Arial: sans-serif, không chân</p>
<p class="b">Georgia: serif, có chân</p>
<p class="c">Courier New: monospace, độ rộng chữ đều nhau</p>
<p class="d">Font không tồn tại, rơi về sans-serif</p>font-style, font-variant, font-weight
font-style nhận normal, italic hoặc oblique: normal là hiển thị bình thường; italic và oblique khá giống nhau, đều hiển thị dạng nghiêng, tuy nhiên oblique ít được hỗ trợ hơn. font-variant nhận normal và small-caps (chữ hoa nhỏ). font-weight quy định độ đậm nhạt, nhận: normal, bold, bolder, lighter và các số 100, 200, ..., 900 (400 là bình thường, 700 là đậm).
<style>
body { font: 16px Georgia, serif; }
p { margin: 4px 0; }
p.normal { font-style: normal; }
p.italic { font-style: italic; }
p.oblique { font-style: oblique; }
p.small { font-variant: small-caps; }
p.thick { font-weight: bold; }
p.w300 { font-weight: 300; }
p.w900 { font-weight: 900; }
</style>
<p class="normal">font-style: normal</p>
<p class="italic">font-style: italic</p>
<p class="oblique">font-style: oblique</p>
<p class="small">font-variant: small-caps — Thiết kế web</p>
<p class="thick">font-weight: bold</p>
<p class="w300">font-weight: 300</p>
<p class="w900">font-weight: 900</p>font-size
Để thiết lập kích cỡ chữ dùng font-size. Thuộc tính có thể nhận giá trị tuyệt đối hoặc tương đối: các từ khóa xx-small, x-small, small, medium, large, x-large, xx-large, smaller, larger, hoặc các đơn vị px, em, rem, in, %.
<p style="font-size:20px;">Doan van nay co Font Size la 20 pixel.</p>
<p style="font-size:small;">Doan van nay co Font Size la small</p>
<p style="font-size:large;">Doan van nay co Font Size la large</p>Để cho phép người dùng tăng giảm cỡ văn bản trong menu của trình duyệt, nhiều lập trình viên dùng đơn vị em thay cho pixel; W3C khuyến nghị dùng em. 1 em bằng kích cỡ font hiện tại. Kích cỡ văn bản mặc định là 16 px, nên 1 em mặc định là 16 px. Ví dụ 2em bằng 32 px và 0.75em bằng 12 px.
Ví dụ JavaScript sau tính nhanh kích cỡ thật (px) từ em/rem, giống cách trình duyệt làm:
const coSoMacDinh = 16; // px
for (const em of [0.75, 1, 1.5, 2]) {
console.log(em + "em = " + em * coSoMacDinh + "px");
}
// em lồng nhau: phần tử con tính theo cỡ chữ của phần tử cha
const cha = 20; // px
console.log("0.5em trong khối cha 20px = " + 0.5 * cha + "px");Mở rộng: Đơn vị
remtính theo cỡ chữ của phần tử gốchtmlnên không bị cộng dồn khi lồng nhau nhưem. Các đơn vị kích thước sẽ được học kỹ ở buổi 8 (Thiết kế bố cục).
Viết rút gọn với font
Để giảm lượng mã, dùng thuộc tính font thiết lập mọi thuộc tính liên quan đến font theo thứ tự:
font-style font-variant font-weight font-size font-family
Trong đó font-size và font-family là bắt buộc; nếu không nêu các giá trị khác thì dùng giá trị mặc định (nếu có).
<div style="font:italic small-caps bold 15px georgia;">Nội dung văn bản</div>
<p style="font: 18px/1.6 Arial, sans-serif;">font: cỡ chữ 18px, line-height 1.6 (viết sau dấu gạch chéo)</p>Ví dụ thực tế: Trang của trung tâm tin học thường đặt
font-family: "Open Sans", Arial, sans-serif; font-size: 16px; line-height: 1.5; color: #333;một lần ởbody. Toàn bộ trang kế thừa, và chỉ tiêu đề cần chỉnh riêng.
Thử một vòng nhỏ để ôn lại cả mục: sửa các giá trị bên dưới và quan sát.
<style>
.bai-viet { font-family: Georgia, serif; color: #333; line-height: 1.7; max-width: 440px; }
.bai-viet h2 { text-transform: uppercase; letter-spacing: 2px; text-align: center; color: #1abc9c; text-shadow: 1px 1px 2px rgba(0,0,0,.2); }
.bai-viet p { text-indent: 24px; text-align: justify; }
.bai-viet em { font-style: italic; color: #e63946; }
</style>
<div class="bai-viet">
<h2>Học CSS</h2>
<p>CSS giúp trang web đẹp và dễ đọc. Chỉ vài thuộc tính văn bản đã đủ biến đoạn chữ thô thành một <em>bài viết</em> gọn gàng, thoáng mắt như trang báo.</p>
</div>Vừa học xong các thuộc tính văn bản và font, hãy làm các bài sau để căn lề, nhấn mạnh chữ và chọn font cho đoạn mô tả.
5. Định dạng bảng biểu
Giáo trình: Chương 3 — mục "Định dạng bảng biểu".
Bảng là công cụ hiển thị dữ liệu rõ ràng và hiệu quả (buổi 4 đã học cấu trúc table, tr, th, td). CSS quyết định bảng trông thế nào. Các thuộc tính chính:
| Thuộc tính | Tác dụng |
|---|---|
border |
thiết lập đường viền cho bảng, ô |
border-collapse |
gộp các viền của ô thành một viền chung (collapse) hay để riêng (separate) |
caption-side |
vị trí tiêu đề bảng (top, bottom) |
empty-cells |
có hiển thị viền và nền của ô khi ô trống hay không (show, hide) |
table-layout |
thuật toán bố cục bảng (auto, fixed) |
width, height |
độ rộng và chiều cao, nhận % hoặc px |
text-align |
căn nội dung ô theo chiều ngang (left, right, center) |
vertical-align |
căn nội dung ô theo chiều dọc (top, bottom, middle; mặc định middle) |
padding |
khoảng cách giữa viền và nội dung trong ô |
border-spacing |
khoảng cách giữa các viền của các ô |
Ví dụ đầy đủ một bảng điểm: viền gộp, ô đệm 15px, tiêu đề căn trái, nội dung ô căn xuống đáy.
<style>
table { border-collapse: collapse; width: 100%; font-family: sans-serif; }
th, td { border: 1px solid #1abc9c; padding: 15px; text-align: left; }
th { background: #1abc9c; color: white; }
td { height: 50px; vertical-align: bottom; }
caption { caption-side: bottom; font-size: 13px; color: #555; padding-top: 6px; }
</style>
<table>
<caption>Bảng 1. Điểm môn Thiết kế Web</caption>
<thead><tr><th>Mã SV</th><th>Họ tên</th><th>Điểm</th></tr></thead>
<tbody>
<tr><td>11230001</td><td>Nguyễn Văn An</td><td>8.5</td></tr>
<tr><td>11230002</td><td>Trần Thị Bình</td><td>9.0</td></tr>
</tbody>
</table>border-collapse quyết định cách vẽ viền của bảng. Hãy so sánh hai giá trị cạnh nhau: với separate (mặc định) mỗi ô có viền riêng nên thấy đường viền kép, còn collapse gộp thành một đường mảnh.
<style>
table { margin: 6px; font: 14px sans-serif; float: left; }
td { border: 2px solid #264653; padding: 8px 14px; }
.a { border-collapse: separate; border-spacing: 8px; }
.b { border-collapse: collapse; }
</style>
<table class="a"><tr><td>separate</td><td>+ spacing 8px</td></tr><tr><td>A</td><td>B</td></tr></table>
<table class="b"><tr><td>collapse</td><td>viền gộp</td></tr><tr><td>A</td><td>B</td></tr></table>Thuộc tính border-spacing xác định khoảng cách giữa các đường viền của các ô trong bảng; nhận một hoặc hai giá trị (có đơn vị độ dài). Một giá trị: áp dụng cho cả khoảng cách ngang và dọc. Hai giá trị: lần lượt là khoảng cách ngang và khoảng cách dọc. Lưu ý border-spacing chỉ có tác dụng khi border-collapse: separate.
Mẹo: Với bảng điểm dài, kỹ thuật dòng kẻ vằn (zebra) bằng
tr:nth-child(even)giúp mắt đi đúng hàng. Đây là bộ chọn lớp giả bạn đã học ở buổi 6, bài tập 7.4 sẽ luyện kỹ thuật này.
<style>
table { border-collapse: collapse; width: 100%; font: 14px sans-serif; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }
thead th { background: #264653; color: white; }
tbody tr:nth-child(even) { background: #f1faee; }
tbody tr:hover { background: #ffe8a3; }
</style>
<table>
<thead><tr><th>Học phần</th><th>Số tín chỉ</th><th>Điểm</th></tr></thead>
<tbody>
<tr><td>Thiết kế Web</td><td>3</td><td>8.5</td></tr>
<tr><td>Cơ sở dữ liệu</td><td>3</td><td>9.0</td></tr>
<tr><td>Lập trình Java</td><td>3</td><td>7.5</td></tr>
<tr><td>Mạng máy tính</td><td>2</td><td>8.0</td></tr>
</tbody>
</table>6. Định dạng danh sách
Giáo trình: Chương 3 — mục "Định dạng danh sách".
Một danh sách có dấu đầu dòng hoặc được đánh số giúp văn bản dễ đọc và thân thiện hơn. CSS có năm thuộc tính thường dùng cho danh sách:
- list-style-type: kiểm soát hình dạng dấu đầu dòng (bullet): hình tròn, hình vuông, hay dạng số.
- list-style-position: dấu đầu dòng nằm bên trong hay bên ngoài luồng hiển thị nội dung.
- list-style-image: dùng một hình ảnh làm dấu đầu dòng.
- marker-offset: khoảng cách giữa dấu đầu dòng và nội dung. Đây là thuộc tính của CSS2, đã bị loại khỏi chuẩn và không còn trình duyệt nào hỗ trợ; hiện nay dùng
paddinghoặcmargincủaliđể thay thế. - list-style: khai báo một lần tất cả các thuộc tính trên.
list-style-type
Để thiết lập hình dạng dấu đầu dòng trong danh sách không có thứ tự (ul) và định dạng số trong danh sách có thứ tự (ol), dùng list-style-type.
Các giá trị cho danh sách không có thứ tự:
- none: không hiển thị dấu.
- disc (mặc định): một dấu chấm tròn.
- circle: một vòng tròn trống.
- square: một hình vuông.
Các giá trị cho danh sách có sắp xếp:
| Giá trị | Miêu tả | Ví dụ |
|---|---|---|
decimal |
Số tự nhiên | 1, 2, 3, 4, 5 |
decimal-leading-zero |
Dạng số, bắt đầu từ 01 | 01, 02, 03, 04, 05 |
lower-alpha |
Dạng chữ cái thường | a, b, c, d, e |
upper-alpha |
Dạng chữ cái hoa | A, B, C, D, E |
lower-roman |
Dạng số La Mã thường | i, ii, iii, iv, v |
upper-roman |
Dạng số La Mã hoa | I, II, III, IV, V |
lower-greek |
Dạng chữ Hy Lạp thường | alpha, beta, gamma |
<style>
ul, ol { float: left; margin: 4px 12px; font: 14px sans-serif; }
.u1 { list-style-type: disc; }
.u2 { list-style-type: circle; }
.u3 { list-style-type: square; }
.u4 { list-style-type: none; }
.o1 { list-style-type: decimal-leading-zero; }
.o2 { list-style-type: upper-alpha; }
.o3 { list-style-type: lower-roman; }
.o4 { list-style-type: lower-greek; }
</style>
<ul class="u1"><li>disc</li><li>disc</li></ul>
<ul class="u2"><li>circle</li><li>circle</li></ul>
<ul class="u3"><li>square</li><li>square</li></ul>
<ul class="u4"><li>none</li><li>none</li></ul>
<ol class="o1"><li>leading-zero</li><li>mục hai</li></ol>
<ol class="o2"><li>upper-alpha</li><li>mục hai</li></ol>
<ol class="o3"><li>lower-roman</li><li>mục hai</li></ol>
<ol class="o4"><li>lower-greek</li><li>mục hai</li></ol>list-style-position
Thuộc tính list-style-position xác định dấu nằm bên trong hay bên ngoài luồng nội dung: inside hoặc outside. Giá trị mặc định là outside, khi đó dấu đầu dòng nằm bên ngoài hộp nội dung của mục danh sách. Sự khác biệt hiện rõ khi mục dài và xuống dòng:
<style>
ul { width: 210px; float: left; margin: 6px 14px; padding-left: 24px; border: 1px dashed #999; font: 14px sans-serif; }
li { background: #e9f5db; margin: 3px 0; }
ul.a { list-style-position: outside; }
ul.b { list-style-position: inside; }
</style>
<ul class="a"><li>outside: dấu nằm ngoài, dòng thứ hai thẳng hàng với dòng đầu của chữ</li></ul>
<ul class="b"><li>inside: dấu nằm trong hộp nội dung, dòng thứ hai chạy sát mép dưới dấu</li></ul>list-style-image và list-style
Muốn tạo điểm nhấn, dùng hình ảnh thay cho dấu đầu dòng mặc định bằng list-style-image. Cú pháp tương tự background-image: xác định URL tới nơi lưu hình. Nếu không tìm thấy hình thì dấu đầu dòng mặc định sẽ được dùng. Nếu khoảng cách mặc định giữa dấu và nội dung dài hay ngắn hơn mong muốn, điều chỉnh bằng padding hoặc margin của li.
ul.khoa-hoc {
list-style-image: url('/images/check.png');
}
li {
padding-left: 6px; /* thay cho marker-offset đã bị loại bỏ */
}Thuộc tính list-style có thể xác định mọi style của danh sách trong một khai báo duy nhất, và thứ tự các giá trị là tùy ý:
<style>
ul { list-style: square inside url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Ccircle cx='6' cy='6' r='5' fill='%231abc9c'/%3E%3C/svg%3E"); font: 15px sans-serif; }
ul li { padding: 3px 0; }
ol.sach { list-style: upper-roman outside; font: 15px sans-serif; }
</style>
<ul><li>Dấu là hình tròn xanh ngọc (nhúng bằng data URI)</li><li>Nếu ảnh không tải được, dùng square</li></ul>
<ol class="sach"><li>Chương một</li><li>Chương hai</li></ol>Bộ đếm CSS (CSS counters)
Về việc đánh số, có thể dùng CSS counters (bộ đếm). Đây là các biến do CSS duy trì, có giá trị được tăng lên bởi các quy tắc CSS để đếm số lần chúng được sử dụng; nhờ đó có thể điều chỉnh cách hiển thị nội dung dựa trên vị trí của nó trong tài liệu. Ba thuộc tính:
- counter-reset: tạo ra hoặc đặt lại bộ đếm.
- counter-increment: tăng giá trị của bộ đếm.
- content: chèn một nội dung (dùng với
::before/::after).
Bộ đếm phải được tạo bằng counter-reset trước, rồi mới tăng. Hàm counter() chèn giá trị bộ đếm vào nội dung. Ví dụ dưới đây tạo bộ đếm section, tăng ở mỗi h2 và thêm chuỗi Section 1: , Section 2: ... vào đầu h2:
<style>
body { counter-reset: section; font-family: sans-serif; }
h2::before {
counter-increment: section;
content: "Section " counter(section) ": ";
color: #e63946;
}
</style>
<h2>Giới thiệu</h2>
<h2>Cú pháp</h2>
<h2>Thực hành</h2>Ví dụ tiếp theo tạo hai cấp bộ đếm: section cho mỗi h1, và subsection được đặt lại ở mỗi h1 để các h2 đánh số lại từ 1 trong từng chương:
<style>
body { counter-reset: section; font-family: sans-serif; }
h1 { counter-reset: subsection; font-size: 20px; margin: 8px 0 2px; }
h2 { font-size: 15px; margin: 2px 0 2px 16px; font-weight: normal; }
h1::before {
counter-increment: section;
content: "Section " counter(section) ". ";
}
h2::before {
counter-increment: subsection;
content: counter(section) "." counter(subsection) " ";
}
</style>
<h1>HTML</h1>
<h2>Phần tử</h2>
<h2>Thuộc tính</h2>
<h1>CSS</h1>
<h2>Bộ chọn</h2>
<h2>Màu sắc</h2>Bộ đếm còn hữu ích khi tạo danh sách phân cấp, vì một thể hiện mới của bộ đếm được tạo tự động trong các phần tử con. Hàm counters() chèn một chuỗi phân cách giữa các mức của bộ đếm lồng nhau:
<style>
ol { counter-reset: section; list-style-type: none; font: 15px sans-serif; }
li::before {
counter-increment: section;
content: counters(section, ".") " ";
color: #1abc9c; font-weight: bold;
}
</style>
<ol>
<li>Chương 1
<ol><li>Mục 1.1</li><li>Mục 1.2
<ol><li>Tiểu mục 1.2.1</li></ol>
</li></ol>
</li>
<li>Chương 2</li>
</ol>Cảnh báo: Quên
counter-resetthì bộ đếm vẫn hoạt động (CSS tự tạo) nhưng phạm vi và thứ tự đánh số có thể sai ý. Hãy luôncounter-resetở phần tử cha chứa các phần tử được đếm.
7. Định dạng liên kết
Giáo trình: Chương 3 — mục "Định dạng liên kết".
Để định dạng liên kết (màu chữ, font chữ...) dùng nhiều thuộc tính CSS thông thường như color, font-family, background...
a {
color: hotpink;
}Ngoài ra, để định dạng các trạng thái khác nhau của liên kết, dùng bốn lớp giả:
- :link: liên kết chưa được truy cập (người dùng chưa từng mở đường dẫn này).
- :visited: liên kết đã được truy cập.
- :hover: khi người dùng đưa con trỏ chuột lên liên kết.
- :active: khi người dùng đang nhấn chuột vào liên kết.
<style>
body { font: 18px sans-serif; }
a:link { color: #000000; }
a:visited { color: #006600; }
a:hover { color: #FFCC00; }
a:active { color: #FF00CC; }
</style>
<p><a href="#muc1">Liên kết 1 (rê chuột lên để đổi màu)</a></p>
<p><a href="#muc2">Liên kết 2 (nhấn giữ chuột để thấy màu :active)</a></p>Lưu ý: Trạng thái :hover PHẢI theo sau các trạng thái :link và :visited, và trạng thái :active phải theo sau trạng thái :hover trong định nghĩa CSS. Ghi nhớ bằng cụm LoVe HAte (L-V-H-A). Nếu đảo thứ tự, quy tắc đứng sau sẽ ghi đè quy tắc đứng trước (vì độ đặc hiệu bằng nhau) và hiệu ứng có thể biến mất.
Các liên kết trong ví dụ trên đều có gạch chân. Để bỏ gạch chân, dùng text-decoration: none. Cách phổ biến là bỏ gạch chân khi bình thường và hiện khi rê chuột hay nhấn:
<style>
body { font: 18px sans-serif; }
a:link { text-decoration: none; }
a:visited { text-decoration: none; }
a:hover { text-decoration: underline; }
a:active { text-decoration: underline; }
</style>
<p><b><a href="#default">Đường dẫn</a></b></p>Ghép các kỹ thuật đã học (màu, nền, bo góc, bỏ gạch chân) bạn dựng được thanh menu và nút liên kết:
<style>
nav { background: #0b132b; padding: 10px; font-family: sans-serif; }
nav a { color: #e0e6f0; text-decoration: none; padding: 8px 14px; border-radius: 6px; margin-right: 4px; display: inline-block; }
nav a:hover { background: #1abc9c; color: #fff; }
nav a:active { background: #148f77; }
</style>
<nav><a href="#trangchu">Trang chủ</a><a href="#khoahoc">Khóa học</a><a href="#lienhe">Liên hệ</a></nav>Mẹo: Người dùng bàn phím di chuyển bằng phím Tab nên hãy thêm cả
:focuscho liên kết (cùng kiểu với:hover). Đừng chỉ dựa vào màu để phân biệt liên kết với văn bản thường; gạch chân hoặc đổi độ đậm giúp người mù màu nhận ra.
Vừa học xong định dạng bảng, danh sách và liên kết, hãy làm các bài sau để làm bảng điểm viền gọn, bảng kẻ vằn, thanh menu ngang và liên kết đổi màu khi rê chuột.
8. Định dạng biểu mẫu
Giáo trình: Chương 3 — mục "Định dạng biểu mẫu" (form "Đăng ký khóa học": width, padding, bộ chọn thuộc tính, nút submit/reset, accent-color, select, :focus, textarea/resize, biểu tượng trong input, transition).
CSS cải thiện đáng kể diện mạo của biểu mẫu HTML. Định dạng biểu mẫu nhằm cải thiện giao diện và trải nghiệm người dùng: tùy chỉnh và làm đẹp ô nhập liệu, nút và nhãn để chúng hấp dẫn, dễ dùng hơn, đồng thời bảo đảm tính nhất quán với thiết kế tổng thể của trang Web. Hình 3-21 của giáo trình so sánh một biểu mẫu trước và sau khi áp dụng CSS: trước là các ô trắng nhàm chán của trình duyệt, sau là khối màu xanh ngọc, nhãn trắng, ô nhập vuông vắn và hai nút đồng bộ màu.
Hãy bắt đầu từ form đơn giản của giáo trình, chưa có CSS (Hình 3-22):
<form>
<h1>Đăng ký khóa học</h1>
<div class="form-block">
<div class="form-subblock user-info">
<div>
<label for="last_name">Họ đệm</label>
<input type="text" id="last_name" size="15">
</div>
<div>
<label class="form-sub-label" for="first_name">Tên</label>
<input type="text" id="first_name" size="15">
</div>
</div>
</div>
</form>Độ rộng và khoảng đệm của ô nhập
Dùng thuộc tính width để xác định độ rộng của trường input. Quy tắc input { width: 100%; } áp dụng cho mọi input. Nếu chỉ muốn định dạng một kiểu, dùng bộ chọn thuộc tính (đã học ở buổi 6):
input[type=text]— chỉ chọn trường văn bản.input[type=password]— chỉ chọn trường mật khẩu.input[type=number]— chỉ chọn trường số.
Dùng padding để thêm không gian bên trong trường văn bản; khi có nhiều ô đặt liền nhau, thêm margin để tạo khoảng cách bên ngoài.
Làm đẹp cả khối form
Ví dụ CSS cho biểu mẫu trên: nền trang xám nhạt, khối form màu xanh ngọc, hai nhóm flex để các ô nằm cạnh nhau, nhãn trắng hơi mờ (opacity: 85%) và ô nhập có chữ cùng tông màu chủ đạo.
<style>
body {
background-color: #f1f1f1;
font-family: sans-serif;
}
h1 {
text-align: center;
}
.form-block {
background-color: #1abc9c;
}
.form-subblock,
.form-block-button {
display: flex;
}
.form-subblock > div,
.form-block-button > div {
flex-grow: 1;
display: flex;
flex-direction: column;
padding: 20px
}
.form-block label {
color: #fff;
opacity: 85%;
padding-bottom: 5px;
font-size: 15px
}
.form-block input {
padding: 5px;
color: #00a886;
font-size: 18px
}
</style>
<form>
<h1>Đăng ký khóa học</h1>
<div class="form-block">
<div class="form-subblock user-info">
<div>
<label for="last_name">Họ đệm</label>
<input type="text" id="last_name" size="15">
</div>
<div>
<label class="form-sub-label" for="first_name">Tên</label>
<input type="text" id="first_name" size="15">
</div>
</div>
</div>
</form>Đoạn CSS dùng display: flex và flex-grow: 1 để hai ô chia đều chiều ngang; đây là Flexbox, bạn sẽ học kỹ ở buổi 9. Ở buổi này, hãy tập trung vào phần trang trí: background-color, color, padding, font-size, opacity.
Nút bấm submit và reset
Các thuộc tính background, color, border... giúp phần tử biểu mẫu trở nên đẹp hơn. Với hai nút submit và reset:
input[type=submit] {
padding: 10px;
font-size: 18px;
border: 1px solid #1abc9c;
background-color: #1abc9c;
color: white;
margin-left: 20px;
}
input[type=reset] {
padding: 10px;
font-size: 18px;
border: 1px solid #1abc9c;
background-color: white;
color: #00896d;
}Hai nút cùng cỡ chữ và viền màu chủ đạo nhưng đảo màu nền/chữ: nút chính (submit) đặc, nút phụ (reset) rỗng. Đó là quy tắc thiết kế "nút chính nổi bật hơn nút phụ".
accent-color, select và :focus
Thuộc tính accent-color là thuộc tính mới trong CSS, dùng để đặt màu chủ đạo cho các điều khiển biểu mẫu như checkbox, radio, range và progress. Thuộc tính color đổi màu chữ trong ô nhập; để ô chọn select (ví dụ chọn giới tính) to hơn, thêm height hoặc padding.
.form-block input, .form-block select {
padding: 5px;
border: 0px;
color: #00896d;
accent-color: #00896d;
}
select {
padding: 5px;
color: #00a886;
font-size: 18px
}Theo mặc định, một số trình duyệt thêm đường viền xanh quanh input khi nó được focus (nhấp vào). Có thể bỏ hành vi này bằng outline: none. Dùng lớp giả :focus để thay đổi cách hiển thị ô nhập khi nó được chọn (bằng chuột hoặc bàn phím):
.form-block input:focus, .form-block select:focus {
outline-width: 0;
}Cảnh báo: Chỉ bỏ
outlinekhi bạn thay bằng một dấu hiệu focus khác rõ ràng (đổi viền, đổ bóng, đổi nền). Nếu không, người dùng bàn phím sẽ không biết mình đang đứng ở ô nào, và đó là lỗi về khả năng tiếp cận (accessibility).
Vùng nhập textarea và resize
Với textarea, dùng thuộc tính resize để cấm người dùng kéo thay đổi kích thước (resize: none). Bạn cũng nên đặt font-family vì mặc định textarea dùng font đơn cách (monospace).
.form-subblock textarea {
border: none;
height: 100px;
resize: none;
font-size: 18px;
font-family: Arial;
color: #00896d;
}Biểu tượng bên trong input và hiệu ứng transition
Muốn có biểu tượng bên trong input, dùng background-image và định vị bằng background-position; cần thêm padding lớn bên trái để dành chỗ cho biểu tượng. Ví dụ ô tìm kiếm của giáo trình:
nav div.search input {
outline: none;
font-size: 18px;
background-image: url('/public/images/search.png');
background-repeat: no-repeat;
background-size: 24px 24px;
background-position: 5px center;
padding-left: 35px;
color: #00a886;
}Ta cũng có thể làm ô nhập có hiệu ứng chuyển động bằng thuộc tính transition: ví dụ ô tìm kiếm rộng ra khi được chọn. Bản dưới đây ghép mọi kỹ thuật của mục (hình tìm kiếm là SVG nhúng, :focus, transition, accent-color, resize). Hãy bấm vào ô tìm kiếm để thấy nó giãn ra:
<style>
body { font-family: sans-serif; background: #f1f1f1; margin: 10px; }
nav { background: #264653; padding: 10px; }
nav input {
width: 150px; outline: none; font-size: 16px; border: 0; border-radius: 4px;
background-color: #fff;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='10' cy='10' r='6' fill='none' stroke='%2300896d' stroke-width='2'/%3E%3Cpath d='M15 15l6 6' stroke='%2300896d' stroke-width='2'/%3E%3C/svg%3E");
background-repeat: no-repeat; background-size: 24px 24px; background-position: 5px center;
padding: 6px 6px 6px 35px; color: #00a886;
transition: width 0.3s ease;
}
nav input:focus { width: 260px; box-shadow: 0 0 0 3px rgba(26,188,156,.5); }
.form-block { background: #1abc9c; padding: 14px; margin-top: 12px; }
.form-block label { color: #fff; display: block; margin: 8px 0 4px; font-size: 15px; }
.form-block input[type=text], .form-block select, .form-block textarea {
width: 100%; box-sizing: border-box; padding: 6px; border: 0; font-size: 16px; color: #00896d;
}
.form-block input:focus, .form-block select:focus, .form-block textarea:focus { outline: 3px solid #fff; }
.form-block input, .form-block select { accent-color: #00896d; }
.form-block textarea { height: 60px; resize: none; font-family: Arial; }
input[type=submit] { padding: 8px 16px; font-size: 16px; border: 1px solid #00896d; background: #00896d; color: white; margin-top: 10px; }
input[type=reset] { padding: 8px 16px; font-size: 16px; border: 1px solid #fff; background: white; color: #00896d; margin-left: 8px; }
</style>
<nav><input type="text" placeholder="Tìm khóa học"></nav>
<form class="form-block">
<label for="ht">Họ và tên</label><input type="text" id="ht">
<label for="gt">Giới tính</label>
<select id="gt"><option>Nam</option><option>Nữ</option></select>
<label><input type="checkbox" checked> Nhận bản tin</label>
<label for="yc">Các yêu cầu khác</label><textarea id="yc"></textarea>
<input type="submit" value="Đăng ký"><input type="reset" value="Làm lại">
</form>Mở rộng: Giáo trình giới thiệu thêm công cụ của khoa tại fit.neu.edu.vn/smartdoc để thử "CSS transition, transform và animation".
transitioncó bốn phần chính: thuộc tính cần chuyển (width), thời gian (0.3s), hàm thời gian (ease) và độ trễ (tùy chọn).
9. Sử dụng biến
Giáo trình: Chương 3 — mục "Sử dụng biến" (CSS Variables,
--ten, hàmvar()).
Sử dụng biến trong CSS (CSS Variables) giúp quản lý các giá trị một cách linh hoạt và tái sử dụng dễ dàng trong toàn bộ tệp CSS. Lợi ích:
- Tái sử dụng: dùng một giá trị nhiều lần trong toàn bộ tệp CSS.
- Dễ dàng bảo trì: đổi giá trị của biến ở một nơi sẽ tự động cập nhật ở mọi nơi dùng biến đó.
- Tùy chỉnh theo chủ đề: dễ đổi chủ đề của trang Web bằng cách đổi giá trị các biến.
Biến được khai báo (thường trong bộ chọn :root, tức phần tử gốc nên mọi nơi đều dùng được) với tên bắt đầu bằng hai dấu gạch ngang:
:root {
--primary-color: #1abc9c;
--primary-dark-color: #00a886;
}Để sử dụng biến, dùng hàm var(), cú pháp var(--custom-name, value). Trong hai tham số, custom-name là bắt buộc: đó là tên thuộc tính tùy chỉnh và phải bắt đầu bằng hai dấu gạch ngang. Tham số value là tùy chọn, là giá trị dự phòng (fallback), được dùng khi thuộc tính tùy chỉnh chưa được định nghĩa hoặc không hợp lệ.
input[type=reset] {
padding: 10px;
font-size: 18px;
border: 1px solid var(--primary-color);
background-color: white;
color: var(--primary-dark-color);
}Dưới đây là một trang nhỏ dùng biến cho toàn bộ màu chủ đạo. Bấm các nút để đổi chủ đề: mã JavaScript chỉ đổi hai biến mà toàn trang đổi màu theo.
<style>
:root {
--primary-color: #1abc9c;
--primary-dark-color: #00a886;
}
body { font-family: sans-serif; margin: 10px; }
header { background: var(--primary-color); color: white; padding: 18px; text-align: center; }
.btn { padding: 10px 18px; border: 1px solid var(--primary-color); background: white; color: var(--primary-dark-color); border-radius: 6px; font-size: 15px; cursor: pointer; }
.btn:hover { background: var(--primary-color); color: white; }
.ghi-chu { border-left: 5px solid var(--primary-dark-color); padding: 8px 12px; margin: 12px 0; background: #f6f6f6; color: var(--chua-khai-bao, #444); }
</style>
<header><h2>Trung tâm Tin học NEU</h2></header>
<div class="ghi-chu">Viền trái dùng biến; màu chữ dùng biến chưa khai báo nên rơi về giá trị dự phòng #444.</div>
<button class="btn">Nút mẫu</button>
<button onclick="doiChuDe('#e76f51','#c1442b')">Chủ đề cam</button>
<button onclick="doiChuDe('#3a86ff','#1d5fd1')">Chủ đề xanh</button>
<script>
function doiChuDe(a, b) {
const r = document.documentElement.style;
r.setProperty('--primary-color', a);
r.setProperty('--primary-dark-color', b);
console.log('Đã đổi chủ đề:', r.getPropertyValue('--primary-color'), r.getPropertyValue('--primary-dark-color'));
}
doiChuDe('#1abc9c', '#00a886');
</script>Vì biến được kế thừa như nhiều thuộc tính khác, bạn còn có thể khai báo lại biến trong một phạm vi hẹp để đổi chủ đề cục bộ:
<style>
:root { --nen: #e8f6f3; --chu: #145a4c; }
.the { background: var(--nen); color: var(--chu); padding: 14px; margin: 8px 0; border-radius: 8px; font: 15px sans-serif; }
.the.toi { --nen: #1b2a41; --chu: #cce3f5; }
</style>
<div class="the">Thẻ dùng chủ đề sáng mặc định</div>
<div class="the toi">Thẻ khai báo lại hai biến thành chủ đề tối</div>Cùng một quy tắc .the, nhưng nhờ khai báo lại biến trong .toi mà thẻ thứ hai tự mang màu khác. Đó là nền tảng của chế độ sáng/tối (light/dark mode) trên các website hiện đại.
// Mô phỏng ý tưởng biến CSS bằng JavaScript: một nơi định nghĩa, nhiều nơi dùng
const theme = { "--primary-color": "#1abc9c", "--primary-dark-color": "#00a886" };
const dung = (ten, duPhong) => theme[ten] ?? duPhong;
console.log("nút:", dung("--primary-color"));
console.log("chữ:", dung("--primary-dark-color"));
console.log("chưa khai báo:", dung("--khong-co", "#444"));
theme["--primary-color"] = "#e76f51";
console.log("sau khi đổi một nơi:", dung("--primary-color"));Mẹo: Đặt tên biến theo vai trò (
--primary-color,--text-muted) thay vì theo giá trị (--xanh-ngoc). Khi đổi thương hiệu từ xanh sang cam, tên vai trò vẫn đúng còn tên theo giá trị trở nên sai.
Vừa học xong biểu mẫu và biến, hãy làm các bài sau để làm đẹp ô nhập, hiệu ứng :focus, dùng biến cho màu chủ đạo và tạo nút đủ trạng thái.
Thực hành theo giáo trình
Giáo trình: Chương 3 — mục "Thực hành" (Bài 3.1 Tạo một trang Web chào mừng đơn giản; Bài 3.2 Tạo một trang Web giới thiệu bản thân; Bài 3.3 Tạo một trang Web đăng ký khóa học) và mục "Bài tập tự thực hành" (Bài 3.4–3.7).
Cả ba bài thực hành đều theo cùng quy trình bốn bước của giáo trình: (1) tạo trang HTML, (2) tạo tệp CSS, (3) liên kết tệp CSS với HTML, (4) kiểm tra kết quả. Khi làm trên máy, bạn lưu hai tệp index.html và style.css cùng thư mục; ở các khung chạy thử dưới đây, để gọn, CSS được đặt trong style của cùng trang, còn bước liên kết được ghi ra riêng.
Bài 3.1. Tạo một trang Web chào mừng đơn giản
Mục tiêu: làm quen với việc tách CSS ra tệp riêng và liên kết vào HTML.
Bước 1: Tạo trang HTML cơ bản. Tạo index.html với một tiêu đề và một đoạn văn:
<html>
<head>
<title>Website nhúng CSS</title>
</head>
<body>
<h1>Chào mừng bạn ghé thăm Website</h1>
<p>Đây là Website đầu tiên mà tôi nhúng CSS vào nhằm mục đích thử nghiệm.</p>
</body>
</html>Bước 2: Tạo tệp CSS. Tạo style.css để đổi giao diện: tiêu đề màu xanh cỡ 36px, đoạn văn màu đỏ cỡ 18px.
h1 {
color: blue;
font-size: 36px;
}
p {
color: red;
font-size: 18px;
}Bước 3: Liên kết tệp CSS với tệp HTML. Thêm đoạn sau vào thẻ head của tệp HTML, để HTML lấy thông tin thiết kế từ tệp CSS:
<link rel="stylesheet" href="style.css">Bước 4: Kiểm tra kết quả. Mở index.html bằng trình duyệt. Bản dưới đây tương đương (CSS đặt trong style):
<html>
<head>
<title>Website nhúng CSS</title>
<style>
h1 { color: blue; font-size: 36px; }
p { color: red; font-size: 18px; }
</style>
</head>
<body>
<h1>Chào mừng bạn ghé thăm Website</h1>
<p>Đây là Website đầu tiên mà tôi nhúng CSS vào nhằm mục đích thử nghiệm.</p>
</body>
</html>Bài 3.2. Tạo một trang Web giới thiệu bản thân
Mục tiêu: dùng bộ chọn thẻ, màu nền, màu chữ, font, padding, margin trên một trang có cấu trúc ngữ nghĩa (header, main, section, footer).
Bước 1: Tạo trang HTML index.html giới thiệu thông tin cá nhân (Chu Văn Huy, nhà phát triển Web) gồm các phần Thông tin cá nhân, Kinh nghiệm làm việc, Liên hệ.
Bước 2: Tạo tệp CSS style.css. Giáo trình đưa phần đầu và dặn "tự hoàn thiện phần còn lại". Mẫu hoàn chỉnh (phần cuối do bạn tự bổ sung):
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Open Sans', sans-serif;
font-size: 16px;
line-height: 1.5;
color: #333;
}
header {
background-color: #333;
color: #fff;
padding: 20px;
}
h1 {
font-size: 36px;
margin-bottom: 20px;
}
/* … tự hoàn thiện phần còn lại: main, section, h2, ul, footer */Bước 3: Liên kết tệp CSS bằng link rel="stylesheet" href="style.css" trong head.
Bước 4: Kiểm tra kết quả. Trang hoàn chỉnh có thể như sau:
<html>
<head>
<meta charset="utf-8">
<title>Giới thiệu bản thân</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Open Sans', sans-serif; font-size: 16px; line-height: 1.5; color: #333; }
header { background-color: #333; color: #fff; padding: 20px; }
h1 { font-size: 36px; margin-bottom: 20px; }
main { padding: 20px; }
section { margin-bottom: 24px; }
h2 { font-size: 22px; color: #1abc9c; border-bottom: 2px solid #1abc9c; margin-bottom: 8px; }
ul { padding-left: 24px; }
footer { background: #333; color: #ccc; padding: 12px 20px; font-size: 14px; }
</style>
</head>
<body>
<header>
<h1>Giới thiệu bản thân</h1>
</header>
<main>
<section>
<h2>Thông tin cá nhân</h2>
<p>Tên: Chu Văn Huy</p>
<p>Tuổi: 37</p>
<p>Nghề nghiệp: Nhà phát triển Web</p>
</section>
<section>
<h2>Kinh nghiệm làm việc</h2>
<ul>
<li>Công ty iSEAS (2015-2017)</li>
<li>Công ty FPT Software (2017-nay)</li>
</ul>
</section>
<section>
<h2>Liên hệ</h2>
<p>Email: [email protected]</p>
<p>Số điện thoại: 0909.888999</p>
</section>
</main>
<footer>
<p>© 2023 Chu Văn Huy</p>
</footer>
</body>
</html>Bài 3.3. Tạo một trang Web đăng ký khóa học
Mục tiêu: định dạng biểu mẫu nhiều khối: nhãn, ô nhập, select, nút submit với hiệu ứng :hover.
Bước 1: Tạo trang HTML index.html "Đăng ký khóa học Trung tâm Tin học NEU" với các phần: Thông tin cá nhân (họ tên, email, điện thoại), Thông tin khóa học (khóa học, ngày bắt đầu, thời gian), Phương thức thanh toán, nút Đăng ký.
Bước 2: Tạo tệp CSS style.css (xem bên trong thẻ style của trang bên dưới): đặt lại margin/padding, font nền; header nền #333; form dạng flex cột; nhãn display: block; ô nhập rộng 100%, bo góc 5px, viền #ccc; nút submit nền #333, hover #555.
Bước 3: Liên kết tệp CSS vào head như hai bài trước.
Bước 4: Kiểm tra kết quả:
<html>
<head>
<meta charset="utf-8">
<title>Đăng ký khóa học Trung tâm Tin học NEU</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Open Sans', sans-serif; font-size: 16px; line-height: 1.5; color: #333; }
header { background-color: #333; color: #fff; padding: 20px; }
h1 { font-size: 36px; margin-bottom: 20px; }
main { padding: 20px; }
section { margin-bottom: 40px; }
h2 { font-size: 24px; margin-bottom: 20px; }
form { display: flex; flex-direction: column; align-items: flex-start; }
label { display: block; margin-bottom: 5px; }
input[type="text"], input[type="email"], input[type="tel"], select,
input[type="date"], input[type="month"] {
width: 100%; margin-bottom: 10px; padding: 10px; border-radius: 5px; border: 1px solid #ccc;
}
input[type="submit"] { background-color: #333; color: #fff; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; }
input[type="submit"]:hover { background-color: #555; }
</style>
</head>
<body>
<header>
<h1>Đăng ký khóa học</h1>
</header>
<main>
<section>
<h2>Thông tin cá nhân</h2>
<form>
<label for="name">Họ và tên:</label>
<input type="text" id="name" name="name" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="phone">Số điện thoại:</label>
<input type="tel" id="phone" name="phone" required>
</form>
</section>
<section>
<h2>Thông tin khóa học</h2>
<form>
<label for="course">Khóa học:</label>
<select id="course" name="course" required>
<option value="">Chọn khóa học</option>
<option value="web-design">Thiết kế Web với HTML, CSS & JavaScript</option>
<option value="web-development">Phát triển Web với PHP & MySQL</option>
<option value="web-aspnet">Phát triển Web với ASP.NET & SQL Server</option>
</select>
<label for="date">Ngày bắt đầu:</label>
<input type="date" id="date" name="date" required>
<label for="time">Thời gian:</label>
<select id="time" name="time" required>
<option value="">Chọn thời gian</option>
<option value="morning">Sáng</option>
<option value="afternoon">Chiều</option>
<option value="evening">Tối</option>
</select>
</form>
</section>
<section>
<h2>Phương thức thanh toán</h2>
<form>
<label for="payment">Chọn phương thức:</label>
<select id="payment" name="payment" required>
<option value="">Chọn phương thức thanh toán</option>
<option value="credit-card">Thẻ tín dụng</option>
<option value="cash">Tiền mặt</option>
</select>
</form>
</section>
<section>
<form>
<input type="submit" value="Đăng ký">
</form>
</section>
</main>
<footer>
<p>© 2023 Trung tâm Tin học NEU</p>
</footer>
</body>
</html>Lưu ý: Bài 3.3 cho thấy ba kỹ thuật hay gặp: (1) nhóm nhiều bộ chọn bằng dấu phẩy để dùng chung một khối quy tắc; (2) dùng
box-sizing: border-boxđểwidth: 100%cộng cả padding và viền mà không tràn khung; (3)cursor: pointervà:hoverđể báo hiệu nút bấm được.
Bài tập tự thực hành (Bài 3.4–3.7)
- Bài 3.4. Sử dụng màu sắc. Tạo trang có bố cục đơn giản và dùng màu sắc tạo điểm nhấn: chọn màu hợp nội dung, dùng
background-color,color,border-color; dùng màu chuyển sắc (gradient) cho vùng cần nhấn mạnh; đặt màu chữ phù hợp với màu nền. - Bài 3.5. Tạo và định dạng bảng, văn bản. Tạo một bảng đơn giản và định dạng bằng
border,background-color,text-align,padding. - Bài 3.6. Sửa form đã thiết kế. Làm đẹp form đã làm ở Chương 2: dùng
border-radius,width,height; thêm icon cho trường nhập liệu (ví dụ email, điện thoại) bằngbackground-imagenhư kỹ thuật ô tìm kiếm ở trên. - Bài 3.7. Tạo form đăng nhập. Thiết kế hộp đăng nhập với
border,background,padding; dùng lớp giả:hoverđể đổi màu khi rê chuột qua hộp đăng nhập.
Gợi ý khung cho Bài 3.7 để bạn bắt đầu (hãy sửa theo ý thích):
<style>
body { font-family: sans-serif; background: #eef2f3; }
.dang-nhap { width: 280px; margin: 20px auto; padding: 20px; background: #fff; border: 1px solid #ccc; border-radius: 10px; transition: background-color .3s, box-shadow .3s; }
.dang-nhap:hover { background: #f1faee; box-shadow: 0 6px 16px rgba(0,0,0,.15); }
.dang-nhap h2 { text-align: center; margin: 0 0 12px; color: #1abc9c; }
.dang-nhap input { width: 100%; box-sizing: border-box; padding: 9px; margin-bottom: 10px; border: 1px solid #bbb; border-radius: 5px; }
.dang-nhap button { width: 100%; padding: 10px; border: 0; border-radius: 5px; background: #1abc9c; color: #fff; font-size: 16px; }
</style>
<div class="dang-nhap">
<h2>Đăng nhập</h2>
<input type="text" placeholder="Tên đăng nhập">
<input type="password" placeholder="Mật khẩu">
<button type="button">Đăng nhập</button>
</div>Câu hỏi ôn tập
Giáo trình: Chương 3 — mục "Câu hỏi ôn tập lý thuyết" (câu 3.1–3.10; đáp án đối chiếu Phụ lục). Các câu 3.1–3.5 ôn lại cách nhúng CSS và chú thích (buổi 6), các câu 3.6–3.10 thuộc nội dung màu sắc và định dạng của buổi này.
3.1. Mã HTML chính xác để tham chiếu đến CSS bên ngoài là gì? A. <style src="mystyle.css"> · B. <stylesheet>mystyle.css</stylesheet> · C. <link rel="stylesheet" type="text/css" href="mystyle.css"> · D. <link rel="stylesheet" type="text/css" url="mystyle.css">
Đáp án: C. Thẻ link dùng thuộc tính href (không phải url hay src).
3.2. Vị trí nào trong tài liệu HTML là nơi chính xác để tham chiếu đến CSS bên ngoài? A. Trong phần body · B. Cuối của tài liệu HTML · C. Trong phần head · D. Trong phần footer
Đáp án: C. Thẻ link đặt trong head để trang được tạo kiểu ngay khi tải.
3.3. Thẻ HTML nào được sử dụng để định nghĩa một CSS nội bộ? A. <script> · B. <style> · C. <css> · D. <internal>
Đáp án: B. CSS nội bộ nằm trong thẻ style (thường ở head).
3.4. Thuộc tính nào được sử dụng để tạo CSS nội tuyến? A. style · B. font · C. styles · D. class
Đáp án: A. Thuộc tính style đặt trực tiếp trên phần tử.
3.5. Đâu là cách để chèn chú thích vào tệp CSS? A. //this is a comment · B. //this is a comment // · C. /* this is a comment */ · D. ' this is a comment
Đáp án: C. CSS chỉ có chú thích /* ... */; // là của JavaScript.
3.6. Đâu là cách để thêm màu nền cho tất cả các phần tử h1? A. all.h1 {background-color:#FFFFFF;} · B. h1.all {background-color:#FFFFFF;} · C. h1 {background-color:#FFFFFF;} · D. h1: all {background-color:#FFFFFF;}
Đáp án: C. Bộ chọn thẻ h1 chọn mọi h1; các lựa chọn còn lại sai cú pháp bộ chọn.
3.7. Thuộc tính CSS nào được sử dụng để thay đổi màu văn bản của một phần tử? A. text-color · B. color · C. fgcolor · D. font-color
Đáp án: B. Màu chữ dùng color; background-color mới là màu nền.
3.8. Thuộc tính CSS nào thay đổi kích thước văn bản? A. font-size · B. text-style · C. text-size · D. font-style
Đáp án: A. font-style chỉ chọn chữ thường hay nghiêng.
3.9. Cú pháp CSS chính xác để in đậm tất cả các phần tử p là gì? A. p {font-weight:bold;} · B. <p style="font-size:bold;"> · C. p {text-size:bold;} · D. <p style="text-size:bold;">
Đáp án: A. Độ đậm là font-weight; font-size và text-size không nhận bold.
3.10. Đâu là cú pháp CSS chính xác? A. body {color: black;} · B. {body;color:black;} · C. body:color=black; · D. {body:color=black;}
Đáp án: A. Dạng đúng là bộ chọn { thuộc tính: giá trị; }.
Để nhớ lâu, hãy tự gõ lại hai đáp án 3.7 và 3.9 vào một trang thử và so sánh với đoạn sau (đoạn "sai" bị trình duyệt bỏ qua):
<style>
p.dung { font-weight: bold; color: #2d6a4f; }
p.sai { font-size: bold; text-color: red; }
</style>
<p class="dung">font-weight: bold và color: đúng, chữ đậm và xanh</p>
<p class="sai">font-size: bold và text-color: không tồn tại hoặc sai giá trị, trình duyệt bỏ qua</p>Sai lầm thường gặp
| Sai lầm | Hậu quả | Cách đúng |
|---|---|---|
Viết text-color: red hoặc font-color: red |
Trình duyệt bỏ qua, chữ không đổi màu | Dùng color: red |
Dùng opacity để làm nền mờ |
Chữ và viền bên trong cũng mờ theo | Dùng rgba()/hsla() cho background-color |
Viết mã hex thiếu hoặc thừa ký tự (#1abc9) |
Khai báo không hợp lệ, bị bỏ qua | Dùng #RGB (3) hoặc #RRGGBB (6 ký tự) |
Đặt border-style mà quên, hoặc chỉ viết border-width: 3px |
Không thấy viền vì kiểu mặc định là none |
Viết đủ border: 3px solid #333 |
background: red sau background-image: url(...) |
Hình nền bị xóa vì rút gọn đặt lại các giá trị khác | Đặt rút gọn trước, hoặc dùng background-color |
Đảo thứ tự a:hover trước a:link |
Hiệu ứng rê chuột biến mất | Theo thứ tự :link, :visited, :hover, :active |
| Gạch chân chữ không phải liên kết | Người đọc tưởng là liên kết | Dùng đậm hoặc đổi màu để nhấn mạnh |
font-family: Times New Roman không có nháy |
Có thể bị bỏ qua hoặc chọn sai font | Đặt "Times New Roman" và thêm họ dự phòng serif |
Bỏ outline của ô nhập mà không thay thế |
Người dùng bàn phím không biết ô nào đang chọn | Thay bằng viền, đổ bóng hoặc nền khi :focus |
Viết var(primary-color) thiếu -- |
Biến không được nhận, mất màu | Viết var(--primary-color) |
Dùng marker-offset để chỉnh khoảng cách dấu danh sách |
Không có tác dụng (đã bị loại khỏi chuẩn) | Dùng padding/margin của li |
Tóm tắt
- Có bốn cách chỉ định màu: Hex (
#RRGGBB), rgb() (0–255 hoặc %), hsl() (hue 0–360, saturation và lightness theo %) và tên màu (140 tên). Độ trong suốt dùngopacity(cả phần tử) hoặcrgba()/hsla()(chỉ màu). - Nền:
background-color,background-image,background-repeat,background-size,background-position,background-attachment; rút gọnbackgroundtheo thứ tự màu, ảnh, lặp, cố định, vị trí. - Viền:
border-style(kiểu),border-width(độ rộng),border-color(màu), viền từng phía, rút gọnborder, bo trònborder-radius. - Văn bản:
color,text-align,text-decoration,text-transform,text-indent,letter-spacing,word-spacing,line-height,direction,text-shadow; font gồmfont-family,font-style,font-variant,font-weight,font-sizevà rút gọnfont. - Bảng:
border-collapse,border-spacing,caption-side,empty-cells,table-layout,vertical-align,padding. Danh sách:list-style-type/position/image,list-style, bộ đếmcounter-reset/counter-increment/contentvớicounter()vàcounters(). Liên kết: bốn trạng thái:link,:visited,:hover,:activetheo đúng thứ tự. - Biểu mẫu:
width,padding, bộ chọn thuộc tínhinput[type=...],accent-color,:focus,resize, biểu tượng bằngbackground-image,transition. Biến CSS: khai báo--tentrong:root, dùngvar(--ten, dự-phòng).