Menu

CSS selector: các loại, combinator và attribute selector

CSS selector chọn ra những phần tử mà một quy tắc sẽ định dạng. Tìm hiểu mọi loại selector, bốn combinator (descendant, child, adjacent sibling, general sibling), attribute selector, cách nhóm selector và thử selector trực tiếp.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

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

SelectorVí dụKhớp với
Universal*Mọi phần tử
TypepMọi thẻ <p>
Class.tipPhần tử có class="tip" (cùng các class khác)
ID#main-titlePhần tử có id="main-title"
Attribute[type="email"]Phần tử có thuộc tính khớp
Pseudo-classa:hover, li:first-childPhần tử ở một trạng thái hoặc vị trí nhất định
Pseudo-elementp::first-line, .x::beforeMột phần của phần tử
Nhómh1, h2, h3Bất cứ thứ gì khớp với một selector trong danh sách
Kết hợpp.tipThẻ <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.

CombinatorCú phápKhớp với B khi
DescendantA B (dấu cách)B nằm ở bất kỳ đâu bên trong A
ChildA > BPhần tử cha của B là A
Adjacent siblingA + BB đứng ngay sau A, cùng phần tử cha
General siblingA ~ BB đứ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ó:

SelectorKhớ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ải class="tip". Hãy viết .tip.
  • Có dấu cách trong selector kết hợp. p .note khô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 a vừ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.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu