Specificity trong CSS

Specificity trong CSS là gì?

Nếu có hai hay nhiều quy tắc CSS (CSS rule) xung đột trỏ đến cùng một phần tử, trình duyệt sẽ tuân theo một số nguyên tắc để xác định độ ưu tiên cho các quy tắc, quy tắc nào có độ ưu tiên cao nhất sẽ được áp dụng.

Ta có ví dụ sau để dễ hình dung: 

Ở đoạn code dưới đây, phần xét background-color cho phần tử div đã cùng lúc bị xét 2 lần ở cả selector id #test có màu nền là màu đỏ và selector div có màu nền là màu vàng, chạy kết quả sẽ cho ra output có nền màu đỏ do id #test có mức độ ưu tiên cao hơn đối tượng còn lại.

<!DOCTYPE html>
<html>
<head>
<style>
#test {
  background-color: red;
}

div {
  background-color: yellow;
}
</style>
</head>
<body>
<div id="test">Đây là phần tử div</div>
</body>
</html>

Để dễ hình dung hơn, bạn hãy tưởng tượng Specificity như là một bảng xếp hạng các CSS rule, CSS rule nào hạng cao hơn thì nó được áp dụng vào phần tử.

Vậy xếp hạng đó như thế nào? Hãy cùng Quantrimang.com tìm hiểu trong hệ thống phân cấp Specificity (Specificity Hierarchy) dưới đây.

Bảng xếp hạng Specificity - Specificity Hierarchy

Nếu có 2 hay nhiều CSS rule cùng nhắm vào một phần tử thì khi đó trình duyệt sẽ chỉ tuân theo một nguyên tắc, xem trong list CSS rule đâu là quy tắc cao nhất để chọn ra và apply vào phần tử.

Ở đây chúng ta sẽ có bảng xếp hạng cho CSS rule để trình duyệt tuân theo khi áp dụng CSS, được sắp xếp theo thứ tự ưu tiên từ trên xuống dưới:

  • Inline style: thiết lập các thuộc tính CSS trực tiếp bên trong một phần tử.
    Ví dụ: <h1 style="color: #ffffff;">
  • ID: thiết lập các thuộc tính CSS cho một phần tử được định danh duy nhất trong một trang.
    Ví dụ: #menu, #header
  • Class, attribute, pseudo-class: ví dụ class như .menu, .header..., attribute như a[target] và pseudo-class như :hover, :focus...
  • Element, pseudo-element: element như là h1, h2, div, p... và pseudo-element như là ::before, ::after, ::selection.

Cách tính Specificity

Tính toán giá trị của CSS Specificity để biết được rule nào được áp dụng vào phần tử, giúp chúng ta không bị mắc lỗi khi viết CSS.

Specificity được tính là những con số nguyên dương. Cụ thể như sau:

  • Inline style là 1000.
  • ID là 100.
  • Class, attribute, pseudo-class là 10.
  • Element, pseudo-element là 1.

Ví dụ:

A: h1
B: #content h1
C: <div id="content"><h1 style="color: #ffffff">Heading</h1></div>
  • A là 1 (một phần tử (element) là h1).
  • B là 101 (một ID là content, là một element là h1).
  • C là 1000 (inline style).

Bởi vì 1 < 101 < 1000, quy tắc (C) có độ ưu tiên cao nhất, nên màu nền cho phần tử h1 là màu trắng (#ffffff).

Các quy tắc cho Specificity

1. Nếu có các Specificity bằng nhau, quy tắc viết sau cùng sẽ được áp dụng

Trường hợp ta có hai CSS rule hạng ngang nhau như thế này:

<!DOCTYPE html>
<html>
<head>
<style>
h1 {
  background-color: red;
}

h1 {
  background-color: purple;
}
</style>
</head>
<body>

<h1 style="color:white">Website Quản Trị Mạng - Heading 1</h1>

</body>
</html>

Rõ ràng là giá trị specificity của phần tử là như nhau (đều là element h1) lúc này chúng ta sẽ theo luật selector nào gần phần tử đó nhất sẽ được áp dụng. Vậy nên kết quả sẽ là:

2. ID selector sẽ có giá trị specificity cao hơn Attribute selector

Trường hợp ta có các CSS rule như thế này:

<!DOCTYPE html>
<html>
<head>
<style>
div#a {
  background-color: purple;
}
#a {
  background-color: green;
}
div[id=a] {
  background-color: blue;
}
</style>
</head>
<body>

<div id="a" style="color:white">
  <h1>Website Quản Trị Mạng</h1>
</div>

</body>
</html>

Theo luật, ID selector sẽ được áp dụng. Kết quả là:

3. Class selector sẽ có giá trị specificity cao hơn element selector

Một class selector như .intro sẽ "đánh bại" mọi element đơn như h1, p, div...

<!DOCTYPE html>
<html>
<head>
<style>
.intro {
background-color: yellow;
}
h1 {
background-color: red;
}
</style>
</head>
<body>

<h1 class="intro">Website Quản Trị Mạng</h1>

</body>
</html>

4. Selector ngữ cảnh cụ thể sẽ có có giá trị specificity cao hơn

Ví dụ, trong tình huống sau:

Từ tệp CSS bên ngoài:

<style>
#content h1 {background-color: red;}
</style>

Trong file HTML:

<style>
#content h1 {
  background-color: yellow;
}
</style>

Quy tắc thứ hai sẽ được ưu tiên áp dụng.

5. Universal selector (*) và giá trị thừa kế (inherited) có specificity là 0

Universal selector hay ký hiệu chọn toàn bộ của CSS (*) sẽ chọn mọi đối tượng thuộc bất kỳ loại nào.

/* Chọn tất cả đối tượng */
* {
  color: green;
}

Universal selector có specificity là 0 và các thuộc tính có giá trị là thừa kế (inherited) cũng có specificity là 0.

Bài trước: Unit - Đơn vị đo trong CSS

Bài tiếp: Rounded Corner trong CSS

Thứ Năm, 02/05/2019 10:55
51 👨 108