Lớp học giả

Podcast CSS – 015: Lớp học được gán biệt danh

Giả sử bạn đã nhận được một biểu mẫu đăng ký email và muốn trường biểu mẫu email có đường viền màu đỏ nếu chứa địa chỉ email không hợp lệ. Bạn làm thế nào để thực hiện điều đó? Bạn có thể sử dụng lớp giả lập CSS :invalid. Đây là một trong nhiều lớp giả do trình duyệt cung cấp.

Lớp giả (pseudo-class) cho phép bạn áp dụng kiểu dựa trên thay đổi về trạng thái và các yếu tố bên ngoài. Tức là thiết kế của bạn có thể phản ứng với hoạt động đầu vào của người dùng, chẳng hạn như một địa chỉ email không hợp lệ. Các thao tác đó được đề cập trong mô-đun bộ chọn và mô-đun này sẽ hướng dẫn bạn chi tiết hơn.

Không giống như các phần tử giả mà bạn có thể tìm hiểu thêm trong mô-đun trước, các lớp giả sẽ dẫn đến những trạng thái cụ thể của một phần tử, thay vì định kiểu thường cho các phần của phần tử đó.

Trạng thái tương tác

Các lớp giả sau đây được áp dụng do tương tác của người dùng với trang của bạn.

:hover

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 2

Nguồn

Nếu người dùng có một thiết bị trỏ như chuột hoặc bàn di chuột và họ đặt thiết bị đó trên một phần tử, thì bạn có thể kết nối với trạng thái đó bằng :hover để áp dụng kiểu. Đây là một cách hữu ích để gợi ý rằng có thể tương tác với một phần tử.

:active

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 1

Nguồn

Trạng thái này được kích hoạt khi một phần tử đang được tương tác (chẳng hạn như lượt nhấp) trước khi huỷ lượt nhấp. Nếu bạn sử dụng một thiết bị trỏ như chuột, thì trạng thái này là khi lượt nhấp bắt đầu và chưa được thả ra.

:focus, :focus-within:focus-visible

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 1

Nguồn

Nếu một phần tử có thể nhận được tâm điểm (như <button>), bạn có thể phản ứng với trạng thái đó bằng lớp giả lập :focus.

Bạn cũng có thể phản ứng nếu một phần tử con của phần tử đó nhận được tâm điểm bằng :focus-within.

Các phần tử có thể lấy tiêu điểm (chẳng hạn như các nút) sẽ hiển thị vòng lấy tiêu điểm khi chúng được lấy tiêu điểm, ngay cả khi được nhấp vào. Trong trường hợp này, nhà phát triển sẽ áp dụng CSS sau:

button:focus {
    outline: none;
}

CSS này sẽ xoá vòng lấy tiêu điểm mặc định của trình duyệt khi một phần tử nhận được tâm điểm, gây ra vấn đề về khả năng hỗ trợ tiếp cận đối với những người dùng thao tác trên trang web bằng bàn phím. Nếu không có kiểu tiêu điểm, các thành phần sẽ không thể theo dõi vị trí hiện tại của tiêu điểm khi sử dụng phím tab (thẻ). Với :focus-visible, bạn có thể trình bày kiểu tâm điểm khi một phần tử nhận được tâm điểm qua bàn phím, đồng thời sử dụng quy tắc outline: none để ngăn phần tử đó tương tác với phần tử đó.

button:focus {
    outline: none;
}

button:focus-visible {
    outline: 1px solid black;
}

:target

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 1.3

Nguồn

Lớp giả :target chọn một phần tử có id khớp với một mảnh URL. Giả sử bạn có HTML sau:

<article id="content">
    …
</article>

Bạn có thể đính kèm kiểu vào phần tử đó khi url chứa #content.

#content:target {
    background: yellow;
}

Điều này rất hữu ích khi bạn làm nổi bật các khu vực có thể đã được liên kết cụ thể, chẳng hạn như nội dung chính trên trang web thông qua đường liên kết bỏ qua.

Tiểu bang lịch sử

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 1

Nguồn

Bạn có thể áp dụng lớp giả lập :link cho bất kỳ phần tử <a> nào có giá trị href chưa được truy cập.

:visited

Bạn có thể tạo kiểu cho đường liên kết mà người dùng đã truy cập bằng cách sử dụng lớp giả lập :visited. Đây là trạng thái ngược với :link, nhưng bạn có ít thuộc tính CSS hơn để sử dụng vì lý do bảo mật. Bạn chỉ có thể tạo kiểu cho color, background-color, border-color, outline-color cũng như màu của SVG fillstroke.

Tầm quan trọng của đơn đặt hàng

Nếu bạn xác định kiểu :visited, thì kiểu đó có thể bị ghi đè bằng một lớp giả liên kết với mức độ đặc hiệu tối thiểu là bằng nhau. Do đó, bạn nên sử dụng quy tắc LVHA để định kiểu cho các đường liên kết với các lớp giả theo thứ tự cụ thể: :link, :visited, :hover, :active.

a:link {}
a:visited {}
a:hover {}
a:active {}

Trạng thái biểu mẫu

Các lớp giả sau đây có thể chọn các thành phần biểu mẫu, ở các trạng thái khác nhau mà các thành phần này có thể ở trong quá trình tương tác với chúng.

:disabled:enabled

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 3.1

Nguồn

Nếu một thành phần biểu mẫu, chẳng hạn như <button> bị trình duyệt vô hiệu hoá, bạn có thể kết nối với trạng thái đó bằng lớp giả lập :disabled. Lớp giả lập :enabled có sẵn cho trạng thái đối diện, mặc dù các phần tử biểu mẫu cũng là :enabled theo mặc định, do đó, bạn có thể sẽ không thấy mình tiếp cận được lớp giả này.

:checked:indeterminate

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 3.1

Nguồn

Lớp giả :checked có sẵn khi một thành phần biểu mẫu hỗ trợ, chẳng hạn như hộp đánh dấu hoặc nút chọn ở trạng thái đã đánh dấu.

Trạng thái :checked là trạng thái nhị phân(true hoặc false), nhưng các hộp đánh dấu sẽ có trạng thái ở giữa khi không được đánh dấu hoặc bỏ đánh dấu. Đây được gọi là trạng thái :indeterminate.

Ví dụ về trạng thái này là khi bạn có chế độ kiểm soát "chọn tất cả" có chức năng đánh dấu tất cả các hộp đánh dấu trong một nhóm. Nếu sau đó người dùng bỏ đánh dấu một trong những hộp đánh dấu này, thì hộp đánh dấu gốc sẽ không còn thể hiện "tất cả" đang được đánh dấu, vì vậy cần chuyển sang trạng thái không xác định.

Phần tử <progress> cũng có trạng thái không xác định và có thể tạo kiểu. Một trường hợp sử dụng phổ biến là tạo giao diện có sọc để cho biết không biết cần thêm bao nhiêu nữa.

:placeholder-shown

Hỗ trợ trình duyệt

  • 47
  • 79
  • 51
  • 9

Nguồn

Nếu một trường biểu mẫu có thuộc tính placeholderkhông có giá trị, thì bạn có thể sử dụng lớp giả lập :placeholder-shown để đính kèm kiểu vào trạng thái đó. Ngay khi có nội dung trong trường, cho dù nội dung đó có placeholder hay không, trạng thái này sẽ không còn áp dụng nữa.

Trạng thái xác thực

Hỗ trợ trình duyệt

  • 10
  • 12
  • 4
  • 5

Nguồn

Bạn có thể phản hồi quá trình xác thực biểu mẫu HTML bằng các lớp giả lập như :valid, :invalid:in-range. Các lớp giả (pseudo-class) :valid:invalid rất hữu ích cho các ngữ cảnh, chẳng hạn như trường email cần so khớp pattern để trở thành trường hợp lệ. Trạng thái giá trị hợp lệ này có thể hiển thị cho người dùng, giúp họ hiểu rằng họ có thể chuyển sang trường tiếp theo một cách an toàn.

Lớp giả :in-range sẽ có sẵn nếu dữ liệu đầu vào có minmax, chẳng hạn như dữ liệu đầu vào dạng số giá trị nằm trong các giới hạn đó.

Với các biểu mẫu HTML, bạn có thể xác định việc một trường là bắt buộc bằng thuộc tính required. Lớp giả :required sẽ có sẵn cho các trường bắt buộc. Bạn có thể chọn các trường không bắt buộc bằng lớp giả :optional.

Chọn phần tử theo chỉ mục, thứ tự và lần xuất hiện

Có một nhóm các lớp giả giúp chọn các mục dựa trên vị trí của chúng trong tài liệu.

:first-child:last-child

Hỗ trợ trình duyệt

  • 4
  • 12
  • 3
  • 3.1

Nguồn

Nếu muốn tìm mục đầu tiên hoặc cuối cùng, bạn có thể sử dụng :first-child:last-child. Các lớp giả này sẽ trả về phần tử đầu tiên hoặc phần tử cuối cùng trong một nhóm các thành phần đồng cấp.

:only-child

Hỗ trợ trình duyệt

  • 2
  • 12
  • 1,5
  • 3.1

Nguồn

Bạn cũng có thể chọn các phần tử không có thành phần đồng cấp với lớp giả :only-child.

:first-of-type:last-of-type

Hỗ trợ trình duyệt

  • 1
  • 12
  • 3.5
  • 3.1

Nguồn

Bạn có thể chọn :first-of-type:last-of-type mà lúc đầu, có vẻ như chúng làm tương tự như :first-child:last-child, nhưng hãy xem xét HTML này:

<div class="my-parent">
    <p>A paragraph</p>
    <div>A div</div>
    <div>Another div</div>
</div>

Và CSS này:

.my-parent div:first-child {
    color: red;
}

Không có phần tử nào có màu đỏ vì phần tử con đầu tiên là một đoạn văn bản chứ không phải là một div. Lớp giả :first-of-type hữu ích trong ngữ cảnh này.

.my-parent div:first-of-type {
    color: red;
}

Mặc dù <div> đầu tiên là thành phần con thứ hai, nhưng vẫn là thành phần đầu tiên thuộc loại bên trong phần tử .my-parent. Vì vậy, với quy tắc này, mã sẽ có màu đỏ.

:nth-child:nth-of-type

Hỗ trợ trình duyệt

  • 1
  • 12
  • 3.5
  • 3.1

Nguồn

Bạn không bị giới hạn ở con đầu tiên, con cuối cùng và loại. Các lớp giả :nth-child:nth-of-type cho phép bạn chỉ định một phần tử nằm tại một chỉ mục nhất định. Quá trình lập chỉ mục trong bộ chọn CSS bắt đầu từ 1.

Bạn cũng có thể truyền nhiều chỉ mục vào các lớp giả lập này. Nếu muốn chọn tất cả các phần tử đồng đều, bạn có thể sử dụng :nth-child(even).

Bạn cũng có thể tạo các bộ chọn phức tạp hơn để tìm các mục trong những khoảng thời gian giãn cách đều đặn bằng cách sử dụng siêu cú pháp An+B.

li:nth-child(3n+3) {
    background: yellow;
}

Bộ chọn này chọn mọi mục thứ ba, bắt đầu từ mục 3. n trong biểu thức này là chỉ mục, bắt đầu từ 0, 3 (3n) là số lượng bạn nhân chỉ mục đó với.

Giả sử bạn có 7 mục <li>. Mục đầu tiên được chọn là 3 vì 3n+3 chuyển thành (3 * 0) + 3. Vòng lặp tiếp theo sẽ chọn mục 6 vì n hiện đã tăng lên 1, vì vậy, (3 * 1) + 3). Biểu thức này dùng được cho cả :nth-child:nth-of-type.

Bạn có thể thử dùng loại bộ chọn này trên trình kiểm thử con thứ n hoặc công cụ bộ chọn số lượng này.

:only-of-type

Hỗ trợ trình duyệt

  • 1
  • 12
  • 3.5
  • 3.1

Nguồn

Cuối cùng, bạn có thể tìm thấy phần tử duy nhất thuộc một loại nhất định trong một nhóm đồng cấp bằng :only-of-type. Cách này sẽ hữu ích nếu bạn muốn chọn danh sách chỉ có một mục hoặc nếu bạn muốn tìm phần tử in đậm duy nhất trong một đoạn.

Tìm các phần tử trống

Đôi khi, bạn nên xác định các phần tử hoàn toàn trống và có một lớp giả cho trường hợp này.

:empty

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 3.1

Nguồn

Nếu một phần tử không có phần tử con nào thì lớp giả :empty sẽ áp dụng cho phần tử đó. Tuy nhiên, thành phần con không chỉ là phần tử HTML hay nút văn bản: chúng còn có thể là khoảng trắng, điều này có thể gây nhầm lẫn khi bạn gỡ lỗi HTML sau đây và thắc mắc tại sao :empty không hoạt động:

<div>
</div>

Lý do là sẽ có một số khoảng trắng giữa <div> mở và đóng, vì vậy, khoảng trống sẽ không hoạt động.

Lớp giả lập :empty có thể hữu ích nếu bạn có ít quyền kiểm soát đối với HTML và muốn ẩn các phần tử trống, chẳng hạn như trình chỉnh sửa nội dung WYSIWYG. Ở đây, người chỉnh sửa đã thêm một đoạn văn trống, bị lạc.

<article class="post">
 <p>Donec ullamcorper nulla non metus auctor fringilla.</p>
 <p></p>
 <p>Curabitur blandit tempus porttitor.</p>
</article>

Với :empty, bạn có thể tìm và ẩn nội dung đó.

.post :empty {
    display: none;
}

Tìm và loại trừ nhiều phần tử

Một số lớp giả giúp bạn viết CSS nhỏ gọn hơn.

:is()

Hỗ trợ trình duyệt

  • 88
  • 88
  • 78
  • 14

Nguồn

Nếu muốn tìm tất cả các phần tử con h2, liimg trong phần tử .post, bạn nên viết một danh sách bộ chọn như sau:

.post h2,
.post li,
.post img {
    …
}

Với lớp giả lập :is(), bạn có thể viết một phiên bản nhỏ gọn hơn:

.post :is(h2, li, img) {
    …
}

Lớp giả lập :is không chỉ nhỏ gọn hơn danh sách bộ chọn mà còn dễ hiểu hơn. Trong hầu hết các trường hợp, nếu xảy ra lỗi hoặc bộ chọn không được hỗ trợ trong danh sách bộ chọn, thì toàn bộ danh sách bộ chọn sẽ không hoạt động nữa. Nếu có lỗi trong các bộ chọn đã chuyển trong lớp giả lập :is, thì hệ thống sẽ bỏ qua bộ chọn không hợp lệ, nhưng hãy sử dụng những bộ chọn hợp lệ.

:not()

Hỗ trợ trình duyệt

  • 1
  • 12
  • 1
  • 3.1

Nguồn

Bạn cũng có thể loại trừ các mục có lớp giả lập :not(). Ví dụ: bạn có thể sử dụng thuộc tính này để tạo kiểu cho tất cả các đường liên kết chưa có thuộc tính class.

a:not([class]) {
    color: blue;
}

Lớp giả (pseudo-class) :not cũng có thể giúp bạn cải thiện khả năng hỗ trợ tiếp cận. Ví dụ: <img> phải có alt, ngay cả khi đó là giá trị trống, vì vậy, bạn có thể viết quy tắc CSS để thêm đường viền màu đỏ đậm vào hình ảnh không hợp lệ:

img:not([alt]) {
    outline: 10px red;
}

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ề lớp giả

Lớp giả hoạt động như thể một lớp đã được áp dụng động cho một phần tử, trong khi phần tử giả hoạt động trên chính phần tử đó.

Đúng
Hãy chú ý đến việc sử dụng : đơn hoặc kép làm ký tự phân biệt chính trong bộ chọn
Sai
Phần tử giả dùng cho các phần, còn lớp giả dành cho trạng thái.

Lớp nào sau đây là lớp giả lập hàm?

:is()
🎉
:target
Các lớp giả lập chức năng có () phía sau để cho biết rằng các lớp này chấp nhận tham số.
:empty
Các lớp giả lập chức năng có () phía sau để cho biết rằng các lớp này chấp nhận tham số.
:not()
🎉

Các lớp giả (pseudo-class) nào sau đây là do tương tác của người dùng?

:hover
🎉
:press
Hãy thử lại!
:squeeze
Hãy thử lại!
:target
🎉
:focus-within
🎉

Đâu là lớp giả lập trạng thái <form>?

:enabled
🎉
:fresh
Hãy thử lại!
:indeterminate
🎉
:checked
🎉
:in-range
🎉
:loading
Hãy thử lại!
:valid
🎉