Thác

The CSS Podcast – 004: Loạt cascade

CSS là viết tắt của Cascading Style Sheets (Biểu định kiểu xếp chồng). Loạt 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. Đó là lý do văn bản của nút được tạo kiểu bằng CSS sau đây sẽ có màu xanh dương.

button {
  color: red;
}

button {
  color: blue;
}

Việc hiểu thuật toán thác nước sẽ 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 thác nước đượ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ụ thể: thuật toán xác định bộ chọn CSS nào có độ khớp cao 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à kiểu trình duyệt, CSS từ tiện ích trình duyệt hay CSS do bạn tạo
  4. Tầm quan trọng: một số quy tắc CSS được tính trọng số nhiều 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 xuất hiện của các quy tắc CSS được tính đến trong quá trình giải quyết xung đột. Đây là bước cuối cùng của trình tự và sẽ luôn dẫn đến một khai báo chiến thắng. Tuy nhiên, vị trí chỉ được xem xét nếu vẫn còn kiểu xung đột sau khi xem xét mọi bước khác của trình tự.

Bản minh hoạ ngay từ đầu bài học này là ví dụ đơn giản nhất về vị trí. Có hai quy tắc nguồn gốc tác giả không quan trọng, cả hai đều không phân lớp và đến từ các quy tắc có bộ chọn có mức độ cụ thể giống hệt nhau, vì vậy, quy tắc cuối cùng được khai báo sẽ 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>, thẻ <style> được nhúng, quy tắc @import và CSS nội tuyến như được xác định trong thuộc tính style của phần tử.

Nếu bạn có một <link> chứa CSS ở đầu trang HTML, và một <link> khác chứa CSS ở cuối trang: các kiểu trong <link> dưới cùng sẽ có mức độ ưu tiên cao hơn. Điều tương tự cũng xảy ra với các phần tử <style> được nhúng hoặc các nội dung khai báo xung đột trong một thuộc tính style. Khi mọi bước khác của trình tự đều bằng nhau, kiểu cuối cùng sẽ thắng.

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

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>, CSS của bảng định kiểu được liên kết sẽ có mức độ ưu tiên cao hơn.

Phần tử <style> được khai báo trong <head>, còn phần tử <link /> được khai báo trong <body>. Điều này có nghĩa là phần tử này có độ cụ thể cao hơn phần tử <style>

Thứ tự của bộ chọn liên quan đến các thuộc tính style không quan trọng, vì các xung đột đó được giải quyết bằng bước đính kèm phần tử của trình tự. Tuy nhiên, nhiều nội dung khai báo trong cùng một thuộc tính kiểu vẫn có thể dựa vào vị trí để xác định nội dung chiến thắng.

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 sau cùng. Vì nền màu xanh lục được khai báo trước nền màu tím, nên trình duyệt hiện bỏ qua nền màu xanh lục.

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

Việc có thể 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 phương án dự phòng cho những 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 clamp() được hỗ trợ trong trình duyệt, 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(), thì nội dung khai báo ban đầu sẽ được thực hiện 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

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

Nếu bạn có mã HTML sau trên trang:

<!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;
}

Màu nền của nút là màu gì?

màu hồng
Nguồn gốc <style> được nhúng nằm ở phía dưới trang hơn so với thẻ <link>. Vì vậy, mặc dù mức độ cụ thể của button là như nhau, nhưng vị trí của quy tắc kiểu khiến nó 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 đó, một quy tắc mới hơn có cùng đặc điểm đã được phát hiện, khiến quy tắc này không áp dụng cho nút.

Mức độ cụ thể

Độ 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 trọng số hoặc tính điểm để thực hiện các phép tính đó. Bằng cách làm cho quy tắc trở nên cụ thể hơn, bạn có thể áp dụng quy tắc đó 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 độ cụ thể. Tuy nhiên, hãy lưu ý một vài điều để tránh gặp phải quá nhiều vấn đề về độ cụ thể.

CSS nhắm đến một lớp trên một phần tử sẽ giúp quy tắc đó trở nên cụ thể hơn, do đó được coi là quan trọng hơn để áp dụng so với CSS chỉ nhắm đến 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 tệp định kiểu.

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

h1 {
  color: blue;
}

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

Mức độ cụ thể là 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 được thưởng điểm cho biết mức độ cụ thể của bộ chọn đó, điểm của tất cả bộ chọn mà 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 đến một phần tử bằng danh sách bộ chọn như a.my-class.another-class[href]:hover, bạn sẽ thấy một nội dung khá khó ghi đè bằng CSS khác. Vì lý do này và để giúp CSS có thể sử dụng lại nhiều hơn, bạn nên giữ cho bộ chọn càng đơn giản càng tốt. Hãy sử dụng tính cụ thể làm công cụ để truy cập vào các phần tử khi cần, nhưng luôn cân nhắc việc tái cấu trúc các danh sách bộ chọn dài, cụ thể 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 một trang. Lệnh xếp tầng này sẽ tính đến nguồn gốc của CSS. Nguồn gốc này bao gồm trang kiểu nội bộ của trình duyệt, các kiểu do tiện ích trình duyệt hoặc hệ điều hành thêm vào và CSS do bạn tạo. Thứ tự mức độ cụ thể của các nguồn gốc này, từ ít cụ thể nhất đến cụ thể nhất như sau:

  1. Kiểu cơ sở của tác nhân người dùng. Đây là các kiểu mà trình duyệt áp dụng cho các phần tử HTML theo mặc định.
  2. Kiểu người dùng cục bộ. Các tuỳ chọn này có thể đến từ cấp hệ điều hành, chẳng hạn như cỡ chữ cơ sở hoặc tuỳ chọn giảm chuyển động. Các tệp này cũng có thể đến từ các 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 tuỳ chỉnh của riêng họ cho một trang web.
  3. CSS do tác giả tạo. CSS do bạn tạo.
  4. Tác giả !important. Mọi !important mà bạn thêm vào phần khai báo do bạn tạo.
  5. Kiểu người dùng cục bộ !important. Mọi !important đến từ cấp hệ điều hành hoặc CSS cấp tiện ích trình duyệt.
  6. Tác nhân người dùng !important. Mọi !important được xác định trong CSS mặc định do trình duyệt cung cấp.

Hình minh hoạ trực quan về thứ tự của các nguồn gốc cũng được giải thích trong danh sách.

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

Kiểm tra mức độ hiểu biết

Kiểm tra kiến thức của bạn về nguồn gốc của hiệu ứng thác nước

Kiểm tra kiến thức của bạn về nguồn gốc của hiệu ứng lũ lụt, hãy cân nhắc 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ự khởi động

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

Kiểu của 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 đó, hãy xem đoạn mã HTML sau:

<h1>Lorem ipsum</h1>

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

20px
Bootstrap là một phần của nguồn gốc do tác giả tạo, bị mất đi kiểu người dùng cục bộ quan trọng.
0,83em
Nguồn gốc kiểu tác nhân người dùng thua kiểu người dùng cục bộ quan trọng.
2rem
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 của nguồn gốc do tác giả tạo, thua kiểu người dùng cục bộ quan trọng.
1ch
Kiểu tác giả này là một phần của nguồn gốc do tác giả tạo, thua kiểu người dùng cục bộ quan trọng.

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 cung cấp cùng một mức độ cụ thể.

Thứ tự quan trọng, từ ít quan trọng đế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. Loại quy tắc animation
  3. Loại quy tắc !important (tuân theo thứ tự giống như nguồn gốc)
  4. Loại quy tắc transition

Các loại quy tắc chuyển đổi và ảnh động đang hoạt động có tầm quan trọng cao hơn so với các quy tắc thông thường. Trong trường hợp chuyển đổi có tầm quan trọng cao hơn các loại quy tắc !important. Điều này là do khi một ảnh động hoặc hiệu ứng chuyển đổi trở nên hoạt động, hành vi dự kiến của ảnh động hoặc hiệu ứng chuyển đổi đó là 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ụ phát triển 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ử, trong đó những CSS không được sử dụng sẽ bị gạch ngang.

Browser DevTools (Công cụ phát triển của trình duyệt) có CSS bị ghi đè bị gạch ngang.

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

Kiểm tra mức độ hiểu biết

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

Bạn có thể sử dụng hiệu ứng Thác nước 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 công cụ này, đó là giải quyết xung đột.
Đảm bảo chỉ có một giá trị kiểu cho mỗi thuộc tính tại thời điểm vẽ.
Văn bản chỉ có thể có một màu và The Cascade là một cách để xác định màu đó.
Quy tắc tính điểm và trọng số kiểu.
Việc tính điểm và trọng số là một phần của giai đoạn sắp xếp trong The Cascade.
Sắp xếp và lọc các thuộc tính kiểu.
Sắp xếp và lọc là các giai đoạn của Loạt thác nước để giúp bạn hiểu các khía cạnh của việc giải quyết xung đột.

Tài nguyên