1. Bộ chọn và mức ưu tiên
Trong thiết kế trang web, một phần tử HTML thường được nhiều bộ chọn trong CSS trùng khớp cùng lúc. Nếu các luật đó đưa ra giá trị khác nhau cho một thuộc tính, thì cần biết giá trị nào được thực thi. Đó chính là vấn đề mức ưu tiên của bộ chọn.
- Bộ chọn trong CSS là cú pháp dùng để chọn phần tử HTML sẽ được định kiểu. Các loại thường gặp: bộ chọn thẻ (tên phần tử), bộ chọn lớp, bộ chọn định danh (id), bộ chọn lớp giả, bộ chọn thuộc tính, bộ chọn phần tử giả và bộ chọn toàn cục.
- Mức ưu tiên của bộ chọn cho biết bộ chọn nào được ưu tiên áp dụng khi có xung đột, dựa trên mức độ cụ thể của bộ chọn đó.
- Bộ chọn thẻ và bộ chọn phần tử giả. Ví dụ:
p,div,::before. - Bộ chọn lớp, bộ chọn lớp giả và bộ chọn thuộc tính. Ví dụ:
.tieude,:hover,[type=text]. - Bộ chọn định danh (id). Ví dụ:
#menu. - Khai báo trực tiếp trong thuộc tính
stylecủa thẻ HTML (kiểu inline). - Thuộc tính kèm từ khoá
!important.
2. Cách xác định mức ưu tiên
- 1.
Với mỗi bộ chọn trùng khớp, đếm các thành phần để được bộ bốn số :
- : bằng 1 nếu khai báo trong thuộc tính
stylecủa thẻ, ngược lại bằng 0. - : số bộ chọn định danh (id).
- : số bộ chọn lớp, bộ chọn lớp giả, bộ chọn thuộc tính.
- : số bộ chọn thẻ và bộ chọn phần tử giả. Bộ chọn toàn cục
*không được tính.
- 2.So sánh các bộ từ trái sang phải. Ở cột đầu tiên mà hai bộ khác nhau, bộ có số lớn hơn thì có mức ưu tiên cao hơn.
- 3.Nếu hai bộ bằng nhau, luật được viết sau trong mã nguồn sẽ được áp dụng.
| Bộ chọn | Bộ | ||||
p | 0 | 0 | 0 | 1 | (0;0;0;1) |
p em .chu | 0 | 0 | 1 | 2 | (0;0;1;2) |
.chu | 0 | 0 | 1 | 0 | (0;0;1;0) |
.a .b | 0 | 0 | 2 | 0 | (0;0;2;0) |
#dau | 0 | 1 | 0 | 0 | (0;1;0;0) |
#dau .chu | 0 | 1 | 1 | 0 | (0;1;1;0) |
trong style="..." | 1 | 0 | 0 | 0 | (1;0;0;0) |
3. Ví dụ minh hoạ
Cho đoạn mã sau. Hỏi dòng chữ hiển thị màu gì? Vì sao?
<!DOCTYPE html>
<html>
<head>
<style>
p { color: blue; }
.lua { color: green; }
#chinh { color: red; }
</style>
</head>
<body>
<p id="chinh" class="lua">Xin chao</p>
</body>
</html>
Lời giải
Thẻ p khớp đồng thời cả ba bộ chọn: p có bộ ; .lua có ; #chinh có . So sánh từ trái sang phải, cột bằng nhau; đến cột , giá trị của #chinh là 1 nên cao nhất. Vậy chữ hiển thị màu đỏ.
Hai luật cùng bộ chọn và cùng mức ưu tiên. Kết quả nào được dùng?
<!DOCTYPE html>
<html>
<head>
<style>
.chu { color: red; }
.chu { color: blue; }
</style>
</head>
<body>
<p class="chu">Van ban mau</p>
</body>
</html>
Lời giải
Cả hai luật đều là bộ chọn lớp .chu, cùng bộ . Khi mức ưu tiên bằng nhau, luật viết sau sẽ thắng, nên chữ có màu xanh lam. Nếu đổi thứ tự hai luật, kết quả sẽ thành đỏ.
Nếu khai báo màu ngay trong thẻ, và nếu thêm !important trong tệp CSS, điều gì xảy ra?
<!DOCTYPE html>
<html>
<head>
<style>
p { color: blue; }
.lua { color: green; }
#chinh { color: red; }
</style>
</head>
<body>
<p id="chinh" class="lua" style="color: violet;">Xin chao</p>
</body>
</html>
Lời giải
Khai báo trong style có bộ ; vì nên màu tím được áp dụng, vượt cả bộ chọn id. Nếu một luật trong tệp CSS kèm !important, nó sẽ vượt lên trên cả khai báo inline (trừ khi khai báo inline cũng có !important). Vì thế !important chỉ nên dùng khi thật cần.
- Nhầm dấu chấm và dấu thăng:
.chulà bộ chọn lớp, còn#chulà bộ chọn id; mức ưu tiên của chúng khác nhau. - Tưởng rằng "luật viết sau luôn thắng": sai. Nếu bộ chọn viết trước có mức ưu tiên cao hơn (chẳng hạn id so với lớp) thì nó vẫn thắng.
- Dùng quá nhiều
!important: khi hai luật đều có!important, trình duyệt lại phân định theo mức ưu tiên rồi đến thứ tự, khiến mã rối và khó sửa. - Quên rằng trình duyệt còn có bảng kiểu mặc định với mức ưu tiên thấp nhất; giá trị kế thừa (như
color) chỉ áp dụng khi không có luật nào trực tiếp trùng khớp. - Tính sai bộ vì quên đếm thành phần trong bộ chọn kết hợp, chẳng hạn
div.chucó , .
Các bộ chọn sau cùng tác động lên một phần tử: h1.tieude, #nd, div #nd, .a.b.c. Bộ chọn nào có mức ưu tiên cao nhất? Nếu luật của div #nd đổi màu chữ, màu đó có được dùng không?
Gợi ý trả lời
Tính từng bộ: h1.tieude là ; #nd là ; div #nd là ; .a.b.c là . So sánh từ trái sang phải, hai bộ #nd và div #nd đều có , nhưng div #nd còn có thêm nên cao hơn #nd. Vậy div #nd thắng và màu chữ của luật đó được dùng.
Vì sao không nên cho điểm kiểu "id bằng 100, lớp bằng 10, thẻ bằng 1" để so mức ưu tiên?
Gợi ý trả lời
Vì cách cho điểm có thể sai. Ví dụ 11 bộ chọn lớp cho ra điểm, lớn hơn một bộ chọn id là điểm, nhưng trên thực tế một bộ chọn id luôn thắng mọi số lượng bộ chọn lớp. Chỉ so sánh từng cột của bộ mới cho kết quả đúng.