Thác

Podcast CSS – 004: The Cascade

CSS là viết tắt của các biểu định kiểu phân tầng. Tầng là thuật toán giải quyết xung đột khi nhiều quy tắc CSS áp dụng cho một phần tử HTML. Đây là lý do văn bản của nút được tạo kiểu bằng CSS sau sẽ có màu xanh dương.

button {
  color: red;
}

button {
  color: blue;
}

Việc hiểu thuật toán phân tầng giúp bạn hiểu cách trình duyệt giải quyết các xung đột như thế này. Thuật toán phân tầng được chia thành 4 giai đoạn riêng biệt.

  1. Vị trí và thứ tự xuất hiện: thứ tự xuất hiện của các quy tắc CSS
  2. Đặc điểm: một thuật toán giúp xác định bộ chọn CSS nào có kết quả khớp mạnh nhất
  3. Nguồn gốc: thứ tự thời điểm CSS xuất hiện và nguồn gốc của CSS, cho dù đó là một kiểu trình duyệt, CSS trong một tiện ích của trình duyệt hay CSS do bạn sáng tạo
  4. Tầm quan trọng: một số quy tắc CSS có trọng số cao hơn các quy tắc khác, đặc biệt là với loại quy tắc !important

Vị trí và thứ tự xuất hiện

Thứ tự xuất hiện và cách các quy tắc CSS của bạn xuất hiện sẽ được phân tầng cân nhắc khi tính toán giải quyết xung đột.

Bản minh hoạ ở đầu bài học này là ví dụ dễ hiểu nhất về vị trí. Có hai quy tắc có các bộ chọn có đặc điểm giống nhau, vì vậy quy tắc cuối cùng được khai báo là chiến thắng.

Kiểu có thể đến từ nhiều nguồn trên một trang HTML, chẳng hạn như thẻ <link>, một thẻ <style> nhúng và CSS cùng dòng như được xác định trong thuộc tính style của một phần tử.

Nếu bạn có một <link> bao gồm CSS ở đầu trang HTML thì một <link> khác bao gồm CSS ở cuối trang: <link> ở dưới cùng sẽ có tính cụ thể nhất. Điều tương tự cũng xảy ra với các phần tử <style> được nhúng. Chúng càng cụ thể càng tốt về phía dưới trang.

Nút này có nền màu xanh dương, do CSS xác định và có trong phần tử <link />. Quy tắc CSS đặt thành màu tối sẽ nằm trong biểu định kiểu liên kết thứ hai và được áp dụng do vị trí phía sau.

Thứ tự này cũng áp dụng cho các phần tử <style> được nhúng. Nếu được khai báo trước <link>, thì CSS của biểu định kiểu đã liên kết sẽ có tính cụ thể nhất.

Phần tử <style> được khai báo trong <head>, còn phần tử <link /> được khai báo trong <body>. Tức là phần tử này có tính cụ thể cao hơn phần tử <style>

Thuộc tính style cùng dòng với CSS được khai báo trong đó sẽ ghi đè tất cả CSS khác, bất kể vị trí của thuộc tính đó, trừ phi nội dung khai báo đã xác định !important.

Vị trí cũng áp dụng theo thứ tự của quy tắc CSS. Trong ví dụ này, phần tử sẽ có nền màu tím vì background: purple được khai báo cuối cùng. Vì nền xanh lục được khai báo trước nền tím nên hiện tại, trình duyệt sẽ bỏ qua nền này.

.my-element {
  background: green;
  background: purple;
}

Việc chỉ định hai giá trị cho cùng một thuộc tính có thể là một cách đơn giản để tạo bản dự phòng cho các trình duyệt không hỗ trợ một giá trị cụ thể. Trong ví dụ tiếp theo, font-size được khai báo hai lần. Nếu trình duyệt hỗ trợ clamp() thì nội dung khai báo font-size trước đó sẽ bị loại bỏ. Nếu trình duyệt không hỗ trợ clamp(), nội dung khai báo ban đầu sẽ được áp dụng và kích thước phông chữ sẽ là 1, 5rem

.my-element {
  font-size: 1.5rem;
  font-size: clamp(1.5rem, 1rem + 3vw, 2rem);
}

Kiểm tra mức độ hiểu biết của bạn

Kiểm tra kiến thức của bạn về thác

Nếu bạn có HTML sau trên trang của mình:

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="/styles.css" />
  </head>
  <body>
    <button>I am a button</button>
    <style>
      button {
        background: pink;
      }
    </style>
  </body>
</html>

Bên trong styles.css, là quy tắc CSS sau:

button {
  background: yellow;
}

Nền của nút có màu gì?

hồng
Nguồn gốc <style> được nhúng nằm ở phía dưới trang so với thẻ <link>, vì vậy, mặc dù đặc điểm của button là như nhau, nhưng vị trí của quy tắc định kiểu giúp quy tắc này giành chiến thắng.
vàng
Đối với tài liệu HTML, nền nút màu vàng có thể đã được đọc trước, nhưng sau đó chúng tôi mới phát hiện một quy tắc mới có cùng đặc điểm nên quy tắc này không áp dụng cho nút.

Mức độ cụ thể

Tính cụ thể là một thuật toán xác định bộ chọn CSS nào cụ thể nhất, sử dụng hệ thống tính điểm hoặc trọng số để thực hiện các phép tính đó. Bằng cách tạo một quy tắc cụ thể hơn, bạn có thể khiến quy tắc đó được áp dụng ngay cả khi một số CSS khác khớp với bộ chọn xuất hiện sau đó trong CSS.

Trong bài học tiếp theo, bạn có thể tìm hiểu thông tin chi tiết về cách tính mức độ cụ thể, tuy nhiên, hãy lưu ý một vài điều sẽ giúp bạn tránh quá nhiều vấn đề về tính cụ thể.

Khi CSS nhắm mục tiêu một lớp trên một phần tử, quy tắc đó sẽ cụ thể hơn và do đó được coi là quan trọng hơn cần được áp dụng, so với việc CSS chỉ nhắm mục tiêu phần tử đó. Điều này có nghĩa là với CSS sau đây, h1 sẽ có màu đỏ mặc dù cả hai quy tắc đều khớp và quy tắc cho bộ chọn h1 xuất hiện sau đó trong biểu định kiểu.

<h1 class="my-element">Heading</h1>
.my-element {
  color: red;
}

h1 {
  color: blue;
}

id giúp CSS cụ thể hơn nữa, vì vậy, các kiểu được áp dụng cho một mã sẽ ghi đè các kiểu được áp dụng theo nhiều cách khác. Đây là một lý do thường khiến bạn không nên đính kèm kiểu vào id. Việc này có thể gây khó khăn cho việc ghi đè kiểu đó bằng một kiểu khác.

Mức độ cụ thể được tích luỹ

Như bạn có thể tìm hiểu trong bài học tiếp theo, mỗi loại bộ chọn sẽ được tặng điểm cho biết mức độ cụ thể của bộ chọn đó. Các điểm cho tất cả các bộ chọn bạn đã sử dụng để nhắm mục tiêu một phần tử sẽ được cộng lại với nhau. Điều này có nghĩa là nếu bạn nhắm mục tiêu một phần tử có danh sách bộ chọn, chẳng hạn như a.my-class.another-class[href]:hover, bạn sẽ nhận được một phần tử khá khó ghi đè bằng CSS khác. Vì lý do này và để giúp CSS dễ sử dụng lại, bạn nên giữ cho bộ chọn đơn giản nhất có thể. Sử dụng tính đặc trưng làm công cụ để truy xuất các phần tử khi bạn cần, nhưng hãy luôn cân nhắc việc tái cấu trúc các danh sách bộ chọn cụ thể, dài nếu có thể.

Điểm gốc

CSS mà bạn viết không phải là CSS duy nhất được áp dụng cho trang. Dòng phân cấp này tính đến nguồn gốc của CSS. Nguồn gốc này bao gồm biểu định kiểu nội bộ của trình duyệt, các kiểu do tiện ích của trình duyệt hoặc hệ điều hành thêm vào và CSS mà bạn tạo. Thứ tự cụ thể của những nguồn gốc này, từ ít cụ thể nhất đến cụ thể nhất như sau:

  1. Kiểu cơ sở tác nhân người dùng. Đây là các kiểu mà trình duyệt của bạn áp dụng cho các phần tử HTML theo mặc định.
  2. Kiểu người dùng cục bộ. Những thay đổi này có thể đến từ cấp hệ điều hành, chẳng hạn như cỡ chữ cơ bản hoặc ưu tiên giảm chuyển động. Chúng cũng có thể đến từ tiện ích của trình duyệt, chẳng hạn như tiện ích của trình duyệt cho phép người dùng viết CSS tùy chỉnh của riêng họ cho một trang web.
  3. Dịch vụ so sánh giá (CSS) được tạo. CSS mà bạn là tác giả.
  4. Tác giả: !important. Mọi !important mà bạn thêm vào nội dung khai báo đã tạo.
  5. Kiểu người dùng cục bộ !important. Mọi !important thuộc cấp hệ điều hành hoặc CSS cấp tiện ích của trình duyệt.
  6. Tác nhân người dùng !important. Bất kỳ !important nào được xác định trong CSS mặc định, do trình duyệt cung cấp.
Hình ảnh minh hoạ thứ tự các nguồn gốc như được giải thích trong danh sách.

Nếu bạn có một loại quy tắc !important trong CSS mà bạn đã tạo và người dùng có một loại quy tắc !important trong CSS tuỳ chỉnh của họ, thì CSS nào chiến thắng?

Kiểm tra mức độ hiểu biết của bạn

Kiểm tra kiến thức của bạn về nguồn gốc thác

Kiểm tra kiến thức của bạn về các nguồn gốc tầng, hãy xem xét các quy tắc kiểu sau đây từ nhiều nguồn gốc:

Kiểu tác nhân người dùng

h1 { margin-block-start: 0.83em; }

Tự thân khởi nghiệp

h1 { margin-block-start: 20px; }

Kiểu Tác giả trang

h1 { margin-block-start: 2ch; }

@media (max-width: 480px) {
  h1 { margin-block-start: 1ch; }
}

Kiểu tuỳ chỉnh của người dùng

h1 { margin-block-start: 2rem !important; }

Sau đó, với HTML sau đây:

<h1>Lorem ipsum</h1>

margin-block-start cuối cùng của h1 là gì?

20px
Tự thân khởi nghiệp là một phần của nguồn gốc được tạo, thua đi kiểu người dùng cục bộ quan trọng.
0,83 em
Kiểu gốc kiểu tác nhân người dùng sẽ thua kiểu người dùng cục bộ quan trọng.
2 mét
Kiểu tuỳ chỉnh của người dùng !important này có nguồn gốc cụ thể nhất.
2 kênh
Kiểu tác giả này là một phần trong nguồn gốc của tác giả, thua kiểu quan trọng dành cho người dùng cục bộ.
1 kênh
Kiểu tác giả này là một phần trong nguồn gốc của tác giả, thua kiểu quan trọng dành cho người dùng cục bộ.

Mức độ quan trọng

Không phải quy tắc CSS nào cũng được tính toán giống nhau hoặc có tính đặc trưng giống nhau.

Thứ tự tầm quan trọng, từ ít quan trọng nhất đến quan trọng nhất như sau:

  1. loại quy tắc thông thường, chẳng hạn như font-size, background hoặc color
  2. animation loại quy tắc
  3. !important loại quy tắc (theo cùng thứ tự như điểm gốc)
  4. transition loại quy tắc

Các loại quy tắc ảnh động và chuyển đổi đang hoạt động có tầm quan trọng cao hơn quy tắc thông thường. Trong trường hợp chuyển đổi, mức độ quan trọng cao hơn so với các loại quy tắc !important. Nguyên nhân là do khi một ảnh động hoặc hiệu ứng chuyển đổi được kích hoạt, hành vi dự kiến của nó là làm thay đổi trạng thái hình ảnh.

Sử dụng Công cụ cho nhà phát triển để tìm hiểu lý do một số CSS không áp dụng

Công cụ của trình duyệt thường sẽ hiển thị tất cả CSS có thể khớp với một phần tử, và những phần tử không được sử dụng sẽ bị gạch bỏ.

Hình ảnh Công cụ cho nhà phát triển của trình duyệt có CSS bị ghi đè bị gạch bỏ

Nếu CSS mà bạn muốn áp dụng không xuất hiện, thì tức là CSS đó không khớp với phần tử. Trong trường hợp đó, bạn cần phải tìm kiếm ở nơi khác, có thể là lỗi chính tả trong tên lớp hoặc tên phần tử hay một số CSS không hợp lệ.

Kiểm tra mức độ hiểu biết của bạn

Kiểm tra kiến thức của bạn về thác

Cascade có thể được dùng cho...

Giải quyết xung đột khi nhiều kiểu áp dụng cho một phần tử.
Đây là một trong những mục tiêu chính của chương trình là giải quyết xung đột.
Đảm bảo mỗi thuộc tính chỉ có một giá trị kiểu tại thời điểm vẽ.
Văn bản chỉ có thể có một màu và Cascade là phương pháp để xác định xem văn bản đó phải là màu nào.
Quy tắc tính điểm và trọng số.
Việc tính điểm và tính trọng số là một phần của giai đoạn phân loại của The Cascade.
Thuộc tính kiểu sắp xếp và lọc.
Sắp xếp và lọc là các giai đoạn của The Cascade nhằm giúp bạn hiểu rõ các khía cạnh của cách giải quyết xung đột.

Tài nguyên