Đăng nhậpDùng miễn phí

Tin học 12 · Chủ đề 4. Giải quyết vấn đề với sự trợ giúp của máy tính

Bài 17. Các mức ưu tiên của bộ chọn

Khi nhiều bộ chọn CSS cùng tác động lên một phần tử, trình duyệt chọn theo đâu? Bài học cho biết cách xác định mức ưu tiên của bộ chọn để giải quyết xung đột về kiểu dáng.

Nhớ nhanh

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.

Định nghĩa
  • 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 đó.
Thứ tự ưu tiên từ thấp đến cao
  • 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 style củ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

Các bước xác định
  1. 1.

    Với mỗi bộ chọn trùng khớp, đếm các thành phần để được bộ bốn số (a;b;c;d)(a;b;c;d):

    • aa: bằng 1 nếu khai báo trong thuộc tính style của thẻ, ngược lại bằng 0.
    • bb: số bộ chọn định danh (id).
    • cc: số bộ chọn lớp, bộ chọn lớp giả, bộ chọn thuộc tính.
    • dd: 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. 2.
    So sánh các bộ (a;b;c;d)(a;b;c;d) 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. 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ọnaabbccddBộ (a;b;c;d)(a;b;c;d)
p0001(0;0;0;1)
p em .chu0012(0;0;1;2)
.chu0010(0;0;1;0)
.a .b0020(0;0;2;0)
#dau0100(0;1;0;0)
#dau .chu0110(0;1;1;0)
trong style="..."1000(1;0;0;0)

3. Ví dụ minh hoạ

Ví dụ 1

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ộ (0;0;0;1)(0;0;0;1); .lua có (0;0;1;0)(0;0;1;0); #chinh có (0;1;0;0)(0;1;0;0). So sánh từ trái sang phải, cột aa bằng nhau; đến cột bb, giá trị của #chinh là 1 nên cao nhất. Vậy chữ hiển thị màu đỏ.

Ví dụ 2

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ộ (0;0;1;0)(0;0;1;0). 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 đỏ.

Ví dụ 3

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ộ (1;0;0;0)(1;0;0;0); vì a=1a=1 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.

Lỗi thường gặp
  • Nhầm dấu chấm và dấu thăng: .chu là bộ chọn lớp, còn #chu là 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ộ (a;b;c;d)(a;b;c;d) vì quên đếm thành phần trong bộ chọn kết hợp, chẳng hạn div.chu có c=1c=1, d=1d=1.
Câu hỏi 1

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à (0;0;1;1)(0;0;1;1); #nd là (0;1;0;0)(0;1;0;0); div #nd là (0;1;0;1)(0;1;0;1); .a.b.c là (0;0;3;0)(0;0;3;0). So sánh từ trái sang phải, hai bộ #nd và div #nd đều có b=1b=1, nhưng div #nd còn có thêm d=1d=1 nên cao hơn #nd. Vậy div #nd thắng và màu chữ của luật đó được dùng.

Câu hỏi 2

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 110110 điểm, lớn hơn một bộ chọn id là 100100 đ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ộ (a;b;c;d)(a;b;c;d) mới cho kết quả đúng.

Gặp bài khó? Chụp ảnh để CEAO giảiAI giải từng bước, đề kiểm tra theo bài, thẻ ghi nhớ. Đăng ký miễn phí.
Thử ngay