Tìm hiểu về quy tắc !important, độ ưu tiên và selector giả trong CSS

1. Vai trò và cách thức hoạt động của quy tắc !important

Trong CSS, quy tắc !important được sử dụng để ghi đè các tính toán độ ưu tiên thông thường. Khi một thuộc tính được gán !important, nó sẽ được ưu tiên hiển thị hơn các khai báo tiêu chuẩn khác. Tuy nhiên, nếu có hai quy tắc cùng chứa !important cùng áp dụng lên một phần tử, trình duyệt sẽ quay lại so sánh độ ưu tiên (specificity) của các bộ chọn đó để quyết định kết quả cuối cùng. Bạn có thể áp dụng !important trong các tình huống thực tế sau: A. Ghi đè CSS nội tuyến (Inline Styles): Khi một phần tử HTML đã được gán style trực tiếp bằng thuộc tính style="...", việc thay đổi thông qua file CSS bên ngoài thường không có tác dụng trừ khi bạn sử dụng !important.
<style>
    .text-primary {
        color: #3498db !important;
    }
</style>

<body>
    <p class="text-primary" style="color: #e74c3c;">Đoạn văn này sẽ có màu xanh (blue) thay vì màu đỏ.</p>
</body>
B. Ghi đè các bộ chọn có độ ưu tiên cao hơn: Ví dụ bên dưới cho thấy một Class Selector có !important sẽ thắng một ID Selector.
<style>
    #main-title {
        font-size: 16px;
    }

    .large-text {
        font-size: 24px !important;
    }
</style>

<body>
    <h1 id="main-title" class="large-text">Tiêu đề sẽ có kích thước 24px</h1>
</body>
Để ghi đè một thuộc tính vốn đã có !important, bạn có hai phương án:
  • Sử dụng một bộ chọn có độ ưu tiên cao hơn và cũng kèm theo !important.
  • Viết một quy tắc tương đương ở vị trí thấp hơn trong file CSS (quy tắc xuất hiện sau sẽ thắng).

2. Cách tính toán độ ưu tiên (Specificity) trong CSS

Độ ưu tiên là tập hợp các trọng số quyết định quy tắc CSS nào sẽ được áp dụng cho phần tử. Trọng số này được tính dựa trên các cấp độ sau (từ cao xuống thấp):
  1. Inline Style: Trọng số 1,0,0,0.
  2. ID Selector: Trọng số 0,1,0,0.
  3. Class, Attribute Selector, Pseudo-class: Trọng số 0,0,1,0.
  4. Element, Pseudo-element: Trọng số 0,0,0,1.
  5. Universal Selector (*), Combinators (+, >, ~): Trọng số 0,0,0,0.
Hãy thử phân tích trọng số của các ví dụ sau:
  • div h1: Gồm 2 phần tử → 0,0,0,2
  • #header h1: Gồm 1 ID và 1 phần tử → 0,1,0,1
  • h1: Gồm 1 phần tử → 0,0,0,1
  • div h1 #title-node: Gồm 1 ID và 2 phần tử → 0,1,0,2
  • div h1.active-link: Gồm 1 Class và 2 phần tử → 0,0,1,2
Khi so sánh, chúng ta so sánh từng cột từ trái sang phải. Giá trị ở cột cao hơn (ví dụ ID) sẽ luôn thắng giá trị ở cột thấp hơn (ví dụ Class) bất kể số lượng Class có nhiều đến đâu.

3. Phân biệt E:nth-last-of-type và E:last-child

Cả hai bộ chọn này đều dùng để nhắm mục tiêu vào các phần tử ở cuối danh sách, nhưng logic hoạt động hoàn toàn khác nhau:
  • E:last-child: Đại diện cho phần tử E nếu nó là con cuối cùng của phần tử cha, bất kể loại phần tử đó là gì. Nếu phần tử cuối cùng không phải là E, bộ chọn này sẽ không khớp.
  • E:nth-last-of-type(n): Bộ chọn này ít khắt khe hơn. Nó tìm kiếm trong danh sách các phần tử cùng loại (type) với E và chọn phần tử thứ n tính từ dưới lên. Nó bỏ qua các phần tử khác loại nằm xen kẽ.
Ví dụ, nếu bạn có cấu trúc gồm một <div> chứa 3 thẻ <p> và 1 thẻ <span> ở cuối cùng, thì p:last-child sẽ không chọn được gì, trong khi p:nth-last-of-type(1) sẽ chọn được thẻ <p> thứ 3.

Thẻ: css web-development css-selectors frontend

Đăng vào ngày 6 tháng 11 lúc 12:41