Lớp học giả

The CSS Podcast – 015: Lớp giả lập

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

Lớp giả cho phép bạn áp dụng kiểu dựa trên các thay đổi về trạng thái và các yếu tố bên ngoài. Điều này có nghĩa là thiết kế của bạn có thể phản ứng với dữ liệu đầu vào của người dùng, chẳng hạn như địa chỉ email không hợp lệ. Các thành phần này đượ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 về các thành phần đó.

Không giống như phần tử giả, bạn có thể tìm hiểu thêm về phần tử này trong mô-đun trước, lớp giả sẽ liên kết với các trạng thái cụ thể mà một phần tử có thể ở trong đó, thay vì chỉ định kiểu 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 một lượt tương tác của người dùng với trang của bạn.

:hover

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Source

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ị đó lên một phần tử, thì bạn có thể 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

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Trạng thái này được kích hoạt khi một phần tử đang được tương tác tích cực (chẳng hạn như một lượt nhấp) trước khi lượt nhấp được nhả. Nếu bạn sử dụng 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 nhả.

:focus, :focus-within:focus-visible

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Nếu một phần tử có thể nhận tâm điểm (chẳng hạn như <button>), bạn có thể phản ứng với trạng thái đó bằng lớp giả :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 tiêu điểm bằng :focus-within.

Các thành phần có thể lấy tiêu điểm, chẳng hạn như nút, sẽ hiển thị vòng tròn tiêu điểm khi chúng nằm trong 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 xoá vòng tiêu điểm trình duyệt mặc định khi một phần tử nhận được tiêu điểm, gây ra vấn đề về khả năng hỗ trợ tiếp cận cho những người dùng điều hướng trang web bằng bàn phím. Nếu không có kiểu tiêu điểm, thì các thành phần hiển thị sẽ không thể theo dõi vị trí tiêu điểm hiện tại khi sử dụng phím tab. Với :focus-visible, bạn có thể hiển thị một kiểu tiêu điểm khi một phần tử nhận được tiêu điểm thông qua bàn phím, đồng thời sử dụng quy tắc outline: none để ngăn chặn việc này khi thiết bị con trỏ tương tác với phần tử đó.

button:focus {
    outline: none;
}

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

:target

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.3.

Source

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 hữu ích để làm nổi bật những 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 một đường liên kết bỏ qua.

Trạng thái trước đây

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Bạn có thể áp dụng lớp giả :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 một đường liên kết mà người dùng đã truy cập bằng cách sử dụng lớp giả :visited. Đây là trạng thái đối lập 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 và màu của SVG fillstroke.

Thứ tự rất quan trọng

Nếu bạn xác định một kiểu :visited, thì kiểu đó có thể bị ghi đè bằng một lớp giả mạo đường liên kết có độ cụ thể ít nhất bằng nhau. Do đó, bạn nên sử dụng quy tắc LVHA để tạo kiểu cho các đường liên kết bằng 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 phần tử biểu mẫu, trong nhiều trạng thái mà các phần tử này có thể ở trong khi tương tác với chúng.

:disabled:enabled

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Nếu trình duyệt tắt một phần tử biểu mẫu, chẳng hạn như <button>, bạn có thể nối với trạng thái đó bằng lớp giả :disabled. Lớp giả :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ể không tìm thấy lớp giả này.

:checked:indeterminate

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Lớp giả :checked có sẵn khi một phần tử 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(đúng hoặc sai), nhưng hộp đánh dấu có trạng thái ở giữa khi không được đánh dấu hoặc bỏ đánh dấu. Trạng thái này được gọi là trạng thái :indeterminate.

Ví dụ về trạng thái này là khi bạn có một thành phần điều khiển "chọn tất cả" đánh dấu vào tất 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 các hộp đánh dấu này, thì hộp đánh dấu gốc sẽ không còn biểu thị "tất cả" được đánh dấu nữa, nên sẽ được đặt vào 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 có thể được 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 bao nhiêu nữa.

:placeholder-shown

Browser Support

  • Chrome: 47.
  • Edge: 79.
  • Firefox: 51.
  • Safari: 9.

Source

Nếu một trường biểu mẫu có thuộc tính placeholderkhông có giá trị, bạn có thể sử dụng lớp giả :placeholder-shown để đính kèm kiểu vào trạng thái đó. Ngay khi có nội dung trong trường, cho dù trường đó 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

Browser Support

  • Chrome: 10.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

Bạn có thể phản hồi quy trình xác thực biểu mẫu HTML bằng các lớp giả như :valid, :invalid:in-range. Các lớp giả :valid:invalid rất hữu ích cho các ngữ cảnh như trường email có pattern cần được so khớp để trở thành trường hợp 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ả lập :in-range 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 biểu mẫu HTML, bạn có thể xác định rằng một trường là bắt buộc bằng thuộc tính required. Lớp giả lập :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 các phần tử theo chỉ mục, thứ tự và tần suất xuất hiện

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

:first-child:last-child

Browser Support

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 3.
  • Safari: 3.1.

Source

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 phần tử đồng cấp.

:only-child

Browser Support

  • Chrome: 2.
  • Edge: 12.
  • Firefox: 1.5.
  • Safari: 3.1.

Source

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

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

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

Bạn có thể chọn :first-of-type:last-of-type. Ban đầu, các thẻ này có vẻ như thực hiện cùng một chức năng như :first-child:last-child, nhưng hãy xem xét đoạn mã HTML sau:

<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 tô màu đỏ vì phần tử con đầu tiên là một đoạn văn chứ không phải div. Lớp giả :first-of-type sẽ 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à phần tử con thứ hai, nhưng vẫn là phần tử con đầu tiên thuộc loại bên trong phần tử .my-parent, vì vậy, theo quy tắc này, phần tử con này sẽ có màu đỏ.

:nth-child:nth-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

Bạn cũng không bị giới hạn ở các phần tử con và loại đầu tiên và cuối cùng. Các lớp giả :nth-child:nth-of-type cho phép bạn chỉ định một phần tử ở một chỉ mục nhất định. Việc 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ả này. Nếu muốn chọn tất cả các phần tử chẵn, bạn có thể sử dụng :nth-child(even).

Bạn cũng có thể tạo bộ chọn phức tạp hơn để tìm các mục ở khoảng thời gian đều đặn bằng cách sử dụng ngữ pháp vi mô 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ần bạn nhân chỉ mục đó.

Giả sử bạn có 7 mục <li>. Mục đầu tiên được chọn là 3 vì 3n+3 dịch sang (3 * 0) + 3. Lặp lại 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 hoạt động cho cả :nth-child:nth-of-type.

Bạn có thể thử nghiệm với loại bộ chọn này trên trình kiểm thử phần tử con thứ n hoặc công cụ bộ chọn số lượng này.

:only-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

Cuối cùng, bạn có thể tìm thấy phần tử duy nhất của một loại nhất định trong một nhóm phần tử đồng cấp bằng :only-of-type. Điều 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 văn.

Tìm phần tử trống

Đôi khi, việc xác định các phần tử hoàn toàn trống có thể hữu ích và cũng có một lớp giả cho việc đó.

:empty

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Nếu một phần tử không có phần tử con, thì lớp giả lập :empty sẽ áp dụng cho các phần tử đó. Tuy nhiên, phần tử con không chỉ là phần tử HTML hoặc nút văn bản: chúng cũng 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 và tự hỏi tại sao HTML đó không hoạt động với :empty:

<div>
</div>

Lý do là 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ả :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, một người chỉnh sửa đã thêm một đoạn văn bản trống, lạc lõng.

<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 thấy và ẩn phần đó.

.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()

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 78.
  • Safari: 14.

Source

Nếu muốn tìm tất cả phần tử con h2, liimg trong phần tử .post, bạn có thể nghĩ đến việc viế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 gọn gàng hơn:

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

Lớp giả :is không chỉ nhỏ gọn hơn danh sách bộ chọn mà còn dễ dùng hơn. Trong hầu hết các trường hợp, nếu có 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 bộ chọn đã truyền trong lớp giả :is, thì lớp này sẽ bỏ qua bộ chọn không hợp lệ nhưng sử dụng các bộ chọn hợp lệ.

:not()

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Bạn cũng có thể loại trừ các mục bằng 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 không có thuộc tính class.

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

Lớp giả :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 mộ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

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ả là dành cho các phần, Lớp giả là dành cho trạng thái.

Lớp giả lập nào sau đây là hoạt động?

:is()
🎉
:target
Các lớp giả lập chức năng có () theo sau để cho biết 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ó () theo sau để cho biết các lớp này chấp nhận tham số.
:not()
🎉

Lớp giả lập 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
🎉

Câu nào sau đây 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
🎉