Podcast CSS – 015: Lớp học giả
Giả sử bạn có 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ệ.
Bạn làm được như thế nào?
Bạn có thể sử dụng lớp giả :invalid
CSS,
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. 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ư địa chỉ email không hợp lệ. Những vấn đề này được đề cập trong mô-đun bộ chọn, và học phần này sẽ hướng dẫn bạn một cách chi tiết hơn.
Không giống như phần tử giả, bạn có thể tìm hiểu thêm trong mô-đun trước, lớp giả kết nối với các trạng thái cụ thể mà phần tử có thể chứa thay vì thường tạo kiểu cho các phần của phần tử đó.
Các trạng thái tương tác
Các lớp giả sau đây được áp dụng do hoạt động tương tác của người dùng với trang của bạn.
:hover
Nếu người dùng có một thiết bị trỏ như chuột hoặc bàn di chuột,
và đặt lên trên một phần tử
bạn có thể chuyển sang 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
Trạng thái này được kích hoạt khi bạn đang tương tác với một phần tử – chẳng hạn như lượt nhấp — trước khi lượt nhấp được huỷ bỏ. Nếu một thiết bị trỏ như chuột được sử dụng, trạng thái này là khi lượt nhấp bắt đầu và chưa được phát hành.
:focus
, :focus-within
và :focus-visible
Nếu một phần tử có thể nhận tiêu đ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, như nút, sẽ hiển thị vòng lấy nét khi chúng được lấy nét — ngay cả khi được nhấp vào. Trong loại tình huống này, nhà phát triển sẽ áp dụng CSS sau:
button:focus {
outline: none;
}
CSS này sẽ xoá vòng tiêu điểm mặc định của trình duyệt khi một phần tử nhận tiêu điểm,
dẫn đến vấn đề 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,
họ 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.
Với :focus-visible
bạn có thể trình bày kiểu lấy 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 khi một thiết bị con trỏ tương tác với quy tắc đó.
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid black;
}
:target
:target
pseudo-class chọn một phần tử có id
khớp với một phân đoạn URL.
Giả sử bạn có HTML sau:
<article id="content">
…
</article>
Bạn có thể đính kèm kiểu cho phần tử đó khi URL chứa #content
.
#content:target {
background: yellow;
}
Điều này rất hữu ích khi 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 đường liên kết bỏ qua.
Các tiểu bang lịch sử
:link
:link
có thể áp dụng lớp giả 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
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 fill
và stroke
.
Vấn đề về đơn đặt hàng
Nếu bạn xác định kiểu :visited
,
nó có thể bị ghi đè bằng một lớp giả của đường liên kết với độ cụ thể ít nhất là bằng nhau.
Do đó,
Bạn nên sử dụng quy tắc LVHA cho việc định kiểu các đường liên kết có lớp giả theo thứ tự cụ thể:
:link
, :visited
, :hover
, :active
.
a:link {}
a:visited {}
a:hover {}
a:active {}
Các trạng thái trên biểu mẫu
Các lớp giả sau đây có thể chọn các phần tử biểu mẫu, ở các trạng thái khác nhau mà các phần tử này có thể ở trong quá trình tương tác với chúng.
:disabled
và :enabled
Nếu là một phần tử biểu mẫu,
chẳng hạn như <button>
sẽ bị trình duyệt tắt,
bạn có thể chuyển sang trạng thái đó bằng
Lớp giả :disabled
.
:enabled
có sẵn lớp pseudo cho trạng thái ngược lại
mặc dù các thành phần biểu mẫu cũng là :enabled
theo mặc định,
do đó, bạn có thể không tiếp cận được với lớp giả này.
:checked
và :indeterminate
:checked
lớp giả khả dụng khi có 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 đang ở 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 vẫn 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
.
Một ví dụ về trạng thái này là khi bạn có tuỳ chọn "chọn tất cả" để chọn tất cả các hộp đánh dấu trong một nhóm. Sau đó, nếu người dùng chọn bỏ chọn một trong các hộp kiểm này, hộp đánh dấu gốc sẽ không thể hiện "tất cả" nữa đang được kiểm tra, do đó nên được đưa 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 và có thể được tạo kiểu.
Một trường hợp sử dụng phổ biến là tạo đường kẻ sọc để thể hiện việc không biết cần thêm bao nhiêu nữa.
:placeholder-shown
Nếu một trường biểu mẫu có thuộc tính placeholder
và không có giá trị,
:placeholder-shown
bạn có thể dùng lớp giả để đính kèm kiểu cho trạng thái đó.
Ngay khi có nội dung trên trường,
cho dù ứng dụng có placeholder
hay không,
trạng thái này sẽ không còn được áp dụng.
Trạng thái xác thực
Bạn có thể phản hồi xác thực biểu mẫu HTML bằng các lớp giả như
:valid
!
:invalid
và
:in-range
.
Các lớp giả :valid
và :invalid
rất hữu ích cho các ngữ cảnh
chẳng hạn như trường email có pattern
cần được so khớp,
trở thành trường hợp lệ.
Người dùng có thể thấy trạng thái giá trị hợp lệ này,
giúp họ hiểu rằng họ có thể chuyển sang lĩnh vực tiếp theo một cách an toàn.
Lớp giả :in-range
có sẵn nếu một đầu vào có min
và max
,
chẳng hạn như nhập vào số và 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
.
:required
lớp giả 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à số lần xuất hiện của chúng
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
và :last-child
Nếu bạn muốn tìm mục đầu tiên hoặc mục cuối cùng,
bạn có thể sử dụng
:first-child
và
: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
Bạn cũng có thể chọn các phần tử không có đồng cấp,
với
Lớp giả :only-child
.
:first-of-type
và :last-of-type
Bạn có thể chọn
:first-of-type
và
:last-of-type
lúc đầu,
trông giống như chúng làm điều tương tự như :first-child
và :last-child
, nhưng hãy xem xét 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 phần tử nào được tô màu đỏ vì phần tử con đầu tiên là một đoạn chứ không phải một div.
Lớp giả :first-of-type
rất 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à con thứ hai,
đây vẫn là phần tử đầu tiên thuộc loại này trong phần tử .my-parent
.
khi áp dụng quy tắc này, mã sẽ có màu đỏ.
:nth-child
và :nth-of-type
Bạn không bị giới hạn ở con đầu tiên và con cuối cùng cũng như loại dữ liệu.
:nth-child
và
:nth-of-type
lớp giả cho phép bạn chỉ định một phần tử nằm trong 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ả 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 các bộ chọn phức tạp hơn để tìm các mục theo khoảng thời gian thường xuyên, bằng cách dùng cú 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,
giá trị này bắt đầu từ 0 và 3 (3n
) là số tiền bạn nhân với chỉ số đó.
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ần lặp tiếp theo sẽ chọn mục 6 vì n
hiện đã tăng lên 1
,
nên (3 * 1) + 3)
.
Biểu thức này dùng được cho cả :nth-child
và :nth-of-type
.
Bạn có thể thử dùng loại bộ chọn này trên người kiểm thử con thứ n hoặc điều này công cụ chọn số lượng.
:only-of-type
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 anh chị em cùng với
:only-of-type
.
Điều này rất 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 phần tử trống
Đôi khi có thể hữu ích khi xác định các phần tử hoàn toàn trống, và cũng có một lớp giả cho việc đó.
:empty
Nếu một phần tử không có phần tử con thì phần tử
Lớp giả :empty
sẽ áp dụng cho các lớp này.
Tuy nhiên, phần tử con không chỉ là các phần tử HTML hoặc 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 HTML này không hoạt động với :empty
:
<div>
</div>
Lý do là có một số khoảng trắng giữa phần mở và đóng <div>
,
vì vậy 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 soạn thảo nội dung WYSIWYG.
Ở đây, người chỉnh sửa đã thêm một đoạn trống, không liên quan.
<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 thông tin đó.
.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()
Nếu bạn muốn tìm tất cả phần tử con h2
, li
và img
trong phần tử .post
,
bạn có thể nghĩ đến việc viết một danh sách bộ chọn như sau:
.post h2,
.post li,
.post img {
…
}
Với :is()
giả, 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ả :is
không chỉ nhỏ gọn hơn danh sách bộ chọn mà còn dễ truy cập 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,
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 đã truyền trong lớp giả :is
,
thì hệ thống sẽ bỏ qua bộ chọn không hợp lệ nhưng hãy sử dụng các bộ chọn hợp lệ.
:not()
Bạn cũng có thể loại trừ các mục có
Lớp giả :not()
.
Ví dụ: bạn có thể dùng đối tượng này để tạo kiểu cho mọi đườ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,
để 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 kiến thức
Kiểm tra kiến thức 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 các phần tử giả tự hoạt động trên chính phần tử đó.
Lớp nào sau đây là lớp giả chức năng?
:target
:empty
:is()
:not()
Lớp giả nào sau đây là do tương tác của người dùng?
:target
:squeeze
:press
:hover
:focus-within
Phần nào sau đây là lớp giả trạng thái <form>
?
:in-range
:indeterminate
:valid
:checked
:fresh
:enabled
:loading