The CSS Podcast – 003: Specificity (Podcast về CSS – 003: Tính cụ thể)
Giả sử bạn đang làm việc với HTML và CSS sau:
<button class="branding">Hello, Specificity!</button>
.branding {
color: blue;
}
button {
color: red;
}
Có hai quy tắc nhắm đến cùng một phần tử ở đây. Mỗi quy tắc chứa một phần khai báo muốn đặt màu cho nút: một quy tắc cố gắng tô màu nút màu đỏ và quy tắc còn lại cố gắng tô màu nút màu xanh dương. Nội dung khai báo nào được áp dụng cho phần tử?
Việc hiểu thuật toán về mức độ cụ thể của CSS là chìa khoá để hiểu cách CSS quyết định giữa các phần khai báo cạnh tranh.
Tính cụ thể là một trong những giai đoạn khác biệt của thác nước, đã được đề cập trong mô-đun cuối cùng về thác nước.
Tính điểm mức độ cụ thể
Mỗi quy tắc bộ chọn trong một nguồn gốc sẽ được tính điểm. Bạn có thể coi mức độ cụ thể là tổng điểm và mỗi loại bộ chọn sẽ nhận được điểm cho tổng điểm đó. Nội dung khai báo từ các quy tắc có mức độ cụ thể cao nhất sẽ chiến thắng.
Với tính cụ thể trong một dự án thực tế, việc cân bằng là đảm bảo các quy tắc CSS mà bạn dự kiến áp dụng thực sự áp dụng, đồng thời thường giữ điểm số ở mức thấp để tránh sự phức tạp. Độ cụ thể chỉ nên ở mức chúng ta cần, thay vì nhắm đến độ cụ thể cao nhất có thể. Trong tương lai, có thể bạn sẽ cần áp dụng một số CSS thực sự quan trọng hơn. Nếu chọn độ cụ thể cao nhất, bạn sẽ làm cho công việc đó trở nên khó khăn.
Mức độ cụ thể không phải là số thập phân mà là một bộ ba bao gồm 3 thành phần: A
, B
và C
.
A
: mức độ cụ thể giống như mã nhận dạngB
: tính cụ thể giống như lớpC
: mức độ cụ thể giống phần tử
Phương thức này thường được biểu thị bằng ký hiệu (A,B,C)
. Ví dụ: (1,0,2)
.
Ký hiệu A-B-C
thay thế cũng thường được sử dụng.
So sánh các đặc điểm
Độ cụ thể được so sánh bằng cách so sánh ba thành phần theo thứ tự: độ cụ thể có giá trị A lớn hơn sẽ cụ thể hơn; nếu hai giá trị A bằng nhau, thì độ cụ thể có giá trị B lớn hơn sẽ cụ thể hơn; nếu hai giá trị B cũng bằng nhau, thì độ cụ thể có giá trị C lớn hơn sẽ cụ thể hơn; nếu tất cả các giá trị bằng nhau, thì hai độ cụ thể sẽ bằng nhau.
Ví dụ: (1,0,0)
được coi là có độ đặc trưng cao hơn (0,4,3)
vì giá trị A
trong (1,0,0)
(là 1
) lớn hơn giá trị A
trong (0,4,3)
(là 0
).
Bộ chọn ảnh hưởng đến mức độ cụ thể
Mỗi phần trong bộ ba độ cụ thể bắt đầu bằng giá trị 0
, vì vậy, độ cụ thể mặc định là (0,0,0)
.
Mỗi phần của bộ chọn làm tăng mức độ cụ thể, tuỳ thuộc vào loại bộ chọn, giá trị của A
, B
hoặc C
sẽ tăng lên.
Bộ chọn chung
Chọn bộ chọn chung (*
)
thêm không có tính cụ thể, để giá trị của bộ chọn ở mức độ cụ thể ban đầu là (0,0,0)
.
* {
color: red;
}
Bộ chọn phần tử hoặc phần tử giả
Bộ chọn phần tử (loại) hoặc phần tử mô phỏng sẽ thêm tính cụ thể giống phần tử, làm tăng thành phần C
thêm 1
.
Các ví dụ sau đây có đặc điểm chung là (0,0,1)
.
Bộ chọn loại
div {
color: red;
}
Bộ chọn phần tử giả
::selection {
color: red;
}
Bộ chọn lớp, lớp giả lập hoặc thuộc tính
Bộ chọn lớp, lớp giả hoặc thuộc tính sẽ thêm tính cụ thể giống như lớp, làm tăng thành phần B
thêm 1
.
Các ví dụ sau đây có độ cụ thể là (0,1,0)
.
Bộ chọn lớp
.my-class {
color: red;
}
Bộ chọn lớp giả
:hover {
color: red;
}
Bộ chọn thuộc tính
[href='#'] {
color: red;
}
Bộ chọn mã nhận dạng
Bộ chọn Mã nhận dạng sẽ thêm tính cụ thể giống mã nhận dạng, làm tăng thành phần A
thêm 1, miễn là bạn sử dụng bộ chọn mã nhận dạng (#myID
) chứ không phải bộ chọn thuộc tính ([id="myID"]
).
Trong ví dụ sau, độ đặc trưng là (1,0,0)
#myID {
color: red;
}
Bộ chọn khác
CSS có nhiều bộ chọn. Không phải từ khoá nào cũng làm tăng tính cụ thể.
Ví dụ: chính lớp giả lập :not()
không đóng góp gì vào việc tính toán độ cụ thể.
Tuy nhiên, các bộ chọn được truyền vào dưới dạng đối số sẽ được thêm vào phép tính độ cụ thể.
div:not(.my-class) {
color: red;
}
Mẫu này có độ đặc trưng là (0,1,1) vì mẫu này có một bộ chọn loại (div
) và một lớp bên trong :not()
.
Kiểm tra mức độ hiểu biết
Kiểm tra kiến thức của bạn về cách tính điểm mức độ cụ thể
a[href="#"]
có đặc điểm gì?
(0,1,0)
(0,0,1)
(0,1,1)
Các yếu tố không ảnh hưởng đến mức độ cụ thể
Có một số quan niệm sai lầm thường gặp về các yếu tố sau đây ảnh hưởng đến mức độ cụ thể.
Thuộc tính kiểu nội tuyến
CSS được áp dụng trực tiếp cho thuộc tính style
của một phần tử không ảnh hưởng đến mức độ cụ thể vì đây là một bước khác trong loạt được đánh giá trước mức độ cụ thể.
<div style="color: red"></div>
Để ghi đè nội dung khai báo này từ trong một trang kiểu, bạn phải sử dụng cách khai báo thắng trong một bước trước đó của loạt.
Ví dụ: bạn có thể thêm !important
vào đó để thuộc nguồn gốc !important
do tác giả tạo.
Nội dung khai báo !important
!important
ở cuối phần khai báo CSS không ảnh hưởng đến mức độ cụ thể, nhưng đặt phần khai báo đó vào một nguồn gốc khác, cụ thể là !important
do tác giả tạo.
Trong ví dụ sau, tính cụ thể của .my-class
không liên quan đến việc khai báo !important
để giành chiến thắng.
.my-class {
color: red !important;
color: white;
}
Khi hai nội dung khai báo là !important
, thì tính cụ thể lại xuất hiện, vì bước gốc từ thác nước chưa thể xác định được người chiến thắng.
.branding {
color: blue !important;
}
button {
color: red !important;
}
Mức độ cụ thể theo bối cảnh
Khi sử dụng bộ chọn phức tạp hoặc phức hợp, mỗi phần của bộ chọn đó sẽ tăng thêm mức độ cụ thể. Hãy xem xét mã HTML mẫu sau:
<a class="my-class another-class" href="#">A link</a>
Đường liên kết này có hai lớp.
Quy tắc trong CSS sau đây có độ cụ thể là (0,0,1)
:
a {
color: red;
}
Nếu bạn tham chiếu một trong các lớp trong bộ chọn, thì bộ chọn đó hiện có tính cụ thể là (0,1,1)
:
a.my-class {
color: green;
}
Thêm lớp khác vào bộ chọn, giờ đây, bộ chọn này có đặc điểm là (0,2,1)
:
a.my-class.another-class {
color: rebeccapurple;
}
Thêm thuộc tính href
vào bộ chọn, thuộc tính này hiện có độ cụ thể là (0,3,1)
:
a.my-class.another-class[href] {
color: goldenrod;
}
Cuối cùng,hãy thêm một lớp giả :hover
vào tất cả các lớp đó, bộ chọn sẽ kết thúc bằng một đặc điểm của (0,4,1)
:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
Kiểm tra mức độ hiểu biết
Kiểm tra kiến thức của bạn về cách tính điểm mức độ cụ thể
Bộ chọn nào sau đây có độ cụ thể là (0,2,1)
?
article:hover a[href]
article > section
article.card.dark
Tăng tính cụ thể một cách thực tế
Giả sử bạn có một số CSS như sau:
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Với HTML có dạng như sau:
<button class="my-button" onclick="alert('hello')">Click me</button>
Nút có nền màu xám, vì bộ chọn thứ hai có tính chất cụ thể là (0,1,1)
.
Lý do là lớp này có một bộ chọn loại (button
) là (0,0,1)
và một bộ chọn thuộc tính ([onclick]
) là (0,1,0)
.
Quy tắc trước đó – .my-button
– bằng (0,1,0)
vì quy tắc này có một bộ chọn lớp, mức độ cụ thể thấp hơn (0,1,1)
.
Nếu muốn tăng cường quy tắc này, bạn có thể lặp lại bộ chọn lớp như sau:
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Bây giờ, nút này sẽ có nền màu xanh dương, vì bộ chọn mới nhận được một giá trị cụ thể (0,2,0)
Mức độ cụ thể giống nhau sẽ quay lại bước tiếp theo trong trình tự
Hãy tiếp tục với ví dụ về nút và chuyển đổi CSS thành:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
Nút có nền màu xám, vì cả hai bộ chọn đều có độ cụ thể giống hệt nhau là (0,1,0)
.
Nếu bạn chuyển đổi các quy tắc theo thứ tự nguồn, thì nút này sẽ chuyển sang màu xanh dương.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
Điều này là do cả hai bộ chọn đều có cùng mức độ cụ thể. Trong trường hợp này, trình tự sẽ quay lại bước thứ tự xuất hiện.