CSS selector là gì
Selector là phần đứng trước cặp ngoặc nhọn trong một quy tắc CSS. Nó quyết định các khai báo áp dụng lên những phần tử nào.
p.note { color: #2563eb; }
/* selector: p.note declaration: color: #2563eb */
Năm selector cơ bản này đã đủ cho phần lớn stylesheet thực tế:
Tổng quan các loại selector
| Selector | Ví dụ | Khớp với |
|---|---|---|
| Universal | * | Mọi phần tử |
| Type | p | Mọi thẻ <p> |
| Class | .tip | Phần tử có class="tip" (cùng các class khác) |
| ID | #main-title | Phần tử có id="main-title" |
| Attribute | [type="email"] | Phần tử có thuộc tính khớp |
| Pseudo-class | a:hover, li:first-child | Phần tử ở một trạng thái hoặc vị trí nhất định |
| Pseudo-element | p::first-line, .x::before | Một phần của phần tử |
| Nhóm | h1, h2, h3 | Bất cứ thứ gì khớp với một selector trong danh sách |
| Kết hợp | p.tip | Thẻ <p> đồng thời có class đó |
Class và ID có trang riêng: CSS class selector. Các pseudo-class như :nth-child() và :not() được giải thích ở trang pseudo-class.
Combinator: descendant và child
Combinator (bộ kết hợp) nối hai selector theo quan hệ của chúng trong cây HTML. Có tất cả bốn loại.
| Combinator | Cú pháp | Khớp với B khi |
|---|---|---|
| Descendant | A B (dấu cách) | B nằm ở bất kỳ đâu bên trong A |
| Child | A > B | Phần tử cha của B là A |
| Adjacent sibling | A + B | B đứng ngay sau A, cùng phần tử cha |
| General sibling | A ~ B | B đứng đâu đó sau A, cùng phần tử cha |
Dấu cách và dấu > là cặp hay bị nhầm nhất. Descendant selector đi sâu tới mọi cấp, còn child selector chỉ dừng ở một cấp:
Sibling combinator: + và ~
Sibling combinator chỉ nhìn về phía sau. Không có combinator "anh em đứng trước", nhưng :has() có thể diễn đạt điều đó: h2:has(+ p) khớp với một thẻ h2 có thẻ p đứng ngay sau.
Attribute selector
Cặp ngoặc vuông dùng để so khớp theo thuộc tính và giá trị của nó:
| Selector | Khớp với |
|---|---|
[disabled] | Có thuộc tính đó, giá trị bất kỳ |
[type="email"] | Giá trị đúng bằng email |
[href^="https"] | Giá trị bắt đầu bằng https |
[href$=".pdf"] | Giá trị kết thúc bằng .pdf |
[class*="icon"] | Giá trị chứa icon ở bất kỳ vị trí nào |
[lang|="en"] | Giá trị là en hoặc bắt đầu bằng en- |
[data-state="open" i] | Khớp chính xác, không phân biệt hoa thường |
Attribute selector trên các thuộc tính data-* là cách gọn gàng để định dạng trạng thái do JavaScript đặt, mà không cần đặt thêm tên class.
Thử bất kỳ selector nào
Gõ một selector vào ô nhập. Mọi phần tử khớp sẽ có viền màu hổ phách, và số lượng hiện ngay bên dưới.
Thử #demo a, ul > li, h2 ~ *, a[href^="https"], li:not(.active).
Selector kết hợp và descendant: dấu cách rất quan trọng
p.note và p .note chỉ khác nhau một dấu cách nhưng mang nghĩa khác hẳn.
Trình duyệt đọc selector thế nào
Khi nhiều quy tắc cùng khớp một phần tử và cùng đặt một thuộc tính, selector có độ ưu tiên (specificity) cao hơn sẽ thắng; nếu bằng nhau, quy tắc viết sau thắng. Một ID nặng hơn bất kỳ số lượng class nào, và một class nặng hơn bất kỳ số lượng type selector nào; trang !important có bảng specificity đầy đủ.
Nhóm selector có một điểm cần lưu ý: nếu một selector trong danh sách thường không hợp lệ, cả quy tắc sẽ bị bỏ qua. Với a, b:unknown { }, ngay cả các liên kết cũng không được định dạng. Bọc danh sách trong :is() sẽ khiến nó "dễ tính" hơn, nên :is(a, b:unknown) vẫn định dạng được các liên kết.
Lỗi thường gặp
- Thiếu dấu chấm hoặc dấu thăng.
tip { }nhắm tới thẻ<tip>, không phảiclass="tip". Hãy viết.tip. - Có dấu cách trong selector kết hợp.
p .notekhông phải làp.note. - Tưởng
>chạm tới cả cấp cháu. Dùng dấu cách nếu muốn đi sâu mọi cấp. - Một lỗi gõ làm hỏng cả nhóm. Với
h1, h2:hovr, h3, không phần tử nào được định dạng. - Selector quá dài.
body div.wrapper ul li avừa khó đọc vừa khó ghi đè. Thường thì một class là đủ.
Câu hỏi thường gặp
CSS selector là gì?
Là phần đứng trước dấu { trong một quy tắc CSS, cho biết các khai báo áp dụng lên những phần tử nào. Trong p.note { color: blue; }, selector p.note khớp với mọi thẻ <p> có class note.
Dấu cách và dấu > trong CSS selector khác nhau thế nào?
Dấu cách là descendant combinator: nav a khớp với mọi liên kết nằm ở bất kỳ đâu bên trong nav, ở mọi cấp lồng nhau. > là child combinator: nav > a chỉ khớp với những liên kết có phần tử cha trực tiếp là nav.
Dấu + trong CSS có nghĩa là gì?
+ là adjacent sibling combinator. h2 + p khớp với thẻ <p> đứng ngay sau một thẻ <h2> có cùng phần tử cha. ~ thì lỏng hơn: h2 ~ p khớp với mọi thẻ <p> anh em đứng phía sau.
Làm sao chọn phần tử theo thuộc tính trong CSS?
Đặt thuộc tính trong cặp ngoặc vuông: [disabled] khớp với phần tử có thuộc tính đó, [type="email"] khớp với đúng một giá trị, [href^="https"] với giá trị bắt đầu bằng một chuỗi, [href$=".pdf"] với giá trị kết thúc bằng chuỗi đó, còn [class*="btn"] với giá trị có chứa chuỗi đó.
CSS có chọn được phần tử cha không?
Có, bằng pseudo-class :has(), được hỗ trợ trên các phiên bản Chrome, Firefox và Safari hiện nay. li:has(> a.active) khớp với những mục danh sách chứa trực tiếp một liên kết đang active.