Trình chọn (Selector)

The CSS Podcast – 002: Bộ chọn

Nếu bạn có một số văn bản mà bạn chỉ muốn lớn hơn và có màu đỏ nếu đó là đoạn đầu tiên của một bài viết, bạn sẽ làm như thế nào?

<article>
  <p>I want to be red and larger than the other text.</p>
  <p>I want to be normal sized and the default color.</p>
</article>

Bạn sử dụng bộ chọn CSS để tìm phần tử cụ thể đó và áp dụng quy tắc CSS, như sau.

article p:first-of-type {
  color: red;
  font-size: 1.5em;
}

CSS cung cấp cho bạn nhiều tuỳ chọn để chọn các phần tử và áp dụng quy tắc cho các phần tử đó, từ rất đơn giản đến rất phức tạp, để giúp giải quyết các tình huống như thế này.

Các phần của quy tắc CSS

Để hiểu cách hoạt động của bộ chọn và vai trò của bộ chọn trong CSS, bạn cần phải biết các phần của quy tắc CSS. Quy tắc CSS là một khối mã, chứa một hoặc nhiều bộ chọn và một hoặc nhiều phần khai báo.

Hình ảnh của một quy tắc CSS có bộ chọn .my-css-rule.

Trong quy tắc CSS này, bộ chọn.my-css-rule. Bộ chọn này tìm tất cả các phần tử có lớp my-css-rule trên trang. Có ba phần khai báo trong dấu ngoặc nhọn. Nội dung khai báo là một cặp thuộc tính và giá trị áp dụng kiểu cho các phần tử được bộ chọn so khớp. Một quy tắc CSS có thể có bao nhiêu phần khai báo và bộ chọn tuỳ ý.

Bộ chọn đơn giản

Nhóm bộ chọn đơn giản nhất nhắm đến các phần tử HTML cùng với các lớp, mã nhận dạng và các thuộc tính khác có thể được thêm vào thẻ HTML.

Bộ chọn chung

Browser Support

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

Source

Bộ chọn chung (còn gọi là ký tự đại diện) khớp với bất kỳ phần tử nào.

* {
  color: hotpink;
}

Quy tắc này khiến mọi phần tử HTML trên trang đều có văn bản màu hồng đậm.

Bộ chọn loại

Browser Support

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

Source

Bộ chọn loại khớp trực tiếp với một phần tử HTML.

section {
  padding: 2em;
}

Quy tắc này khiến mọi phần tử <section> đều có 2empadding ở mọi mặt.

Bộ chọn lớp

Browser Support

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

Source

Một phần tử HTML có thể có một hoặc nhiều mục được xác định trong thuộc tính class. Công cụ chọn lớp sẽ so khớp với mọi phần tử có áp dụng lớp đó.

<div class="my-class"></div>
<button class="my-class"></button>
<p class="my-class"></p>

Mọi phần tử được áp dụng lớp sẽ có màu đỏ:

.my-class {
  color: red;
}

Lưu ý . chỉ xuất hiện trong CSS và không xuất hiện trong HTML. Điều này là do ký tự . hướng dẫn ngôn ngữ CSS so khớp các thành phần thuộc tính lớp. Đây là mẫu phổ biến trong CSS, trong đó một ký tự đặc biệt hoặc một nhóm ký tự được dùng để xác định các loại bộ chọn.

Một phần tử HTML có lớp .my-class sẽ vẫn được so khớp với quy tắc CSS ở trên, ngay cả khi các phần tử đó có một số lớp khác, như sau:

<div class="my-class another-class some-other-class"></div>

Lý do là CSS tìm kiếm một thuộc tính class chứa lớp đã xác định, thay vì khớp chính xác với lớp đó.

Bộ chọn mã nhận dạng

Browser Support

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

Source

Phần tử HTML có thuộc tính id phải là phần tử duy nhất trên trang có giá trị mã nhận dạng đó. Bạn chọn các phần tử bằng bộ chọn mã nhận dạng như sau:

#rad {
  border: 1px solid blue;
}

CSS này sẽ áp dụng đường viền màu xanh dương cho phần tử HTML có idrad, như sau:

<div id="rad"></div>

Tương tự như bộ chọn lớp ., hãy sử dụng ký tự # để hướng dẫn CSS tìm một phần tử khớp với id theo sau.

Bộ chọn thuộc tính

Browser Support

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

Source

Bạn có thể tìm các phần tử có một thuộc tính HTML nhất định hoặc có một giá trị nhất định cho một thuộc tính HTML bằng cách sử dụng bộ chọn thuộc tính. Hướng dẫn CSS tìm kiếm các thuộc tính bằng cách gói bộ chọn bằng dấu ngoặc vuông ([ ]).

[data-type='primary'] {
  color: red;
}

CSS này tìm kiếm tất cả các phần tử có thuộc tính data-type với giá trị là primary, như sau:

<div data-type="primary"></div>

Thay vì tìm một giá trị cụ thể của data-type, bạn cũng có thể tìm các phần tử có thuộc tính này, bất kể giá trị của thuộc tính đó.

[data-type] {
  color: red;
}
<div data-type="primary"></div>
<div data-type="secondary"></div>

Cả hai phần tử <div> này đều có văn bản màu đỏ.

Bạn có thể sử dụng bộ chọn thuộc tính phân biệt chữ hoa chữ thường bằng cách thêm toán tử s vào bộ chọn thuộc tính.

[data-type='primary' s] {
  color: red;
}

Điều này có nghĩa là nếu một phần tử HTML có data-typePrimary thay vì primary, thì phần tử đó sẽ không có văn bản màu đỏ. Bạn có thể làm ngược lại (không phân biệt chữ hoa chữ thường) bằng cách sử dụng toán tử i.

Cùng với các toán tử trường hợp, bạn có quyền sử dụng các toán tử khớp với một phần chuỗi bên trong giá trị thuộc tính.

/* A href that contains "example.com" */
[href*='example.com'] {
  color: red;
}

/* A href that starts with https */
[href^='https'] {
  color: green;
}

/* A href that ends with .com */
[href$='.com'] {
  color: blue;
}
Trong bản minh hoạ này, toán tử `$` trong bộ chọn thuộc tính sẽ lấy loại tệp từ thuộc tính `href`. Điều này cho phép bạn đặt tiền tố cho nhãn (dựa trên loại tệp đó) bằng một phần tử giả.

Bộ chọn nhóm

Bộ chọn không nhất thiết phải chỉ khớp với một phần tử. Bạn có thể nhóm nhiều bộ chọn bằng cách phân tách các bộ chọn đó bằng dấu phẩy:

strong,
em,
.my-class,
[lang] {
  color: red;
}

Ví dụ này mở rộng thay đổi màu sắc cho cả phần tử <strong> và phần tử <em>. Lớp này cũng được mở rộng cho một lớp có tên là .my-class và một phần tử có thuộc tính lang.

Kiểm tra mức độ hiểu biết

Kiểm tra kiến thức của bạn về bộ chọn đơn giản

* {}

Loại bộ chọn đơn giản nào được sử dụng trong đoạn mã trên?

thuộc tính
[] được dùng cho bộ chọn thuộc tính đơn giản.
Mã nhận dạng
# được dùng cho bộ chọn mã nhận dạng đơn giản.
phổ quát
* là bộ chọn đơn giản chung.
lớp
. được dùng cho bộ chọn đơn giản lớp.
div {}

Loại bộ chọn đơn giản nào được sử dụng trong đoạn mã trên?

lớp
. được dùng cho bộ chọn đơn giản lớp.
loại
Tên element được dùng cho bộ chọn đơn giản type.
thuộc tính
Dấu ngoặc vuông [] được dùng cho bộ chọn thuộc tính đơn giản.
Mã nhận dạng
# được dùng cho bộ chọn ID đơn giản.

Lớp giả và phần tử giả

CSS cung cấp các loại bộ chọn hữu ích tập trung vào trạng thái nền tảng cụ thể, chẳng hạn như khi một phần tử được di chuột qua, cấu trúc bên trong một phần tử hoặc các phần của một phần tử.

Lớp giả

Các phần tử HTML có nhiều trạng thái, vì chúng được tương tác hoặc một trong các phần tử con của chúng ở một trạng thái nhất định.

Ví dụ: người dùng có thể di chuột qua một phần tử HTML bằng con trỏ chuột hoặc di chuột qua một phần tử con. Đối với những trường hợp đó, hãy sử dụng lớp giả :hover.

/* Our link is hovered */
a:hover {
  outline: 1px dotted green;
}

/* Sets all even paragraphs to have a different background */
p:nth-child(even) {
  background: floralwhite;
}

Tìm hiểu thêm trong mô-đun lớp giả.

Phần tử giả

Phần tử giả khác với lớp giả vì thay vì phản hồi trạng thái nền tảng, các phần tử giả hoạt động như thể đang chèn một phần tử mới bằng CSS. Về mặt cú pháp, phần tử giả cũng khác với lớp giả, vì thay vì sử dụng một dấu hai chấm (:), chúng ta sử dụng dấu hai chấm kép (::).

.my-element::before {
  content: 'Prefix - ';
}

Như trong bản minh hoạ ở trên, bạn đã đặt tiền tố cho nhãn của đường liên kết bằng loại tệp, bạn có thể sử dụng phần tử giả ::before để chèn nội dung ở đầu phần tử hoặc phần tử giả ::after để chèn nội dung ở cuối phần tử.

Tuy nhiên, phần tử giả không chỉ giới hạn ở việc chèn nội dung. Bạn cũng có thể sử dụng các lớp này để nhắm đến các phần cụ thể của một phần tử. Ví dụ: giả sử bạn có một danh sách. Sử dụng ::marker để tạo kiểu cho từng dấu đầu dòng (hoặc số) trong danh sách

/* Your list will now either have red dots, or red numbers */
li::marker {
  color: red;
}

Bạn cũng có thể sử dụng ::selection để tạo kiểu cho nội dung mà người dùng đã làm nổi bật.

::selection {
  background: black;
  color: white;
}

Tìm hiểu thêm trong mô-đun về phần tử giả.

Kiểm tra mức độ hiểu biết

Kiểm tra kiến thức của bạn về bộ chọn giả

Bộ chọn phần tử giả sử dụng bao nhiêu dấu hai chấm?

:
Một : được dùng để nhắm mục tiêu các lớp giả.
::
Hai :: được dùng để nhắm mục tiêu các phần tử giả.
:::
Mã này không hợp lệ và không nhắm đến mục tiêu nào.
p:hover {
  background: white;
  color: black;
}

Loại bộ chọn giả nào được sử dụng trong đoạn mã trên?

Lớp giả
Một : được dùng để nhắm mục tiêu các lớp giả.
Phần tử giả
Hai :: được dùng để nhắm mục tiêu các phần tử giả.

Bộ chọn phức tạp

Bạn đã thấy một loạt bộ chọn, nhưng đôi khi, bạn sẽ cần kiểm soát chi tiết hơn bằng CSS. Đây là lúc bộ chọn phức tạp sẽ giúp ích.

Tại thời điểm này, bạn cần nhớ rằng mặc dù các bộ chọn sau đây cung cấp cho chúng ta nhiều quyền hơn, nhưng chúng ta chỉ có thể lần lượt chọn xuống, chọn các phần tử con. Chúng ta không thể nhắm mục tiêu lên trên và chọn một phần tử mẹ. Chúng ta sẽ tìm hiểu về thác nước và cách hoạt động của thác nước trong một bài học sau.

Toán tử kết hợp

Toán tử kết hợp là phần nằm giữa hai bộ chọn. Ví dụ: nếu bộ chọn là p > strong, thì toán tử kết hợp là ký tự >. Bộ chọn sử dụng các bộ kết hợp này giúp bạn chọn các mục dựa trên vị trí của các mục đó trong tài liệu.

Toán tử kết hợp con cháu

Để hiểu các toán tử kết hợp con cháu, trước tiên bạn cần hiểu các phần tử mẹ và con.

<p>A paragraph of text with some <strong>bold text for emphasis</strong>.</p>

Phần tử mẹ là <p> chứa văn bản. Bên trong phần tử <p> đó là một phần tử <strong>, giúp nội dung của phần tử đó in đậm. Vì nằm bên trong <p> nên đây là phần tử con.

Một bộ kết hợp con cho phép chúng ta nhắm đến một phần tử con. Thao tác này sử dụng dấu cách () để hướng dẫn trình duyệt tìm các phần tử con:

p strong {
  color: blue;
}

Đoạn mã này chỉ chọn tất cả các phần tử <strong> là phần tử con của phần tử <p>, làm cho các phần tử đó có màu xanh dương theo đệ quy.

Vì bộ kết hợp con cháu là đệ quy, nên khoảng đệm được thêm vào mỗi phần tử con sẽ áp dụng, dẫn đến hiệu ứng so le.

Hiệu ứng này được minh hoạ rõ ràng hơn trong ví dụ trên, sử dụng bộ chọn bộ kết hợp .top div. Quy tắc CSS đó sẽ thêm khoảng đệm bên trái vào các phần tử <div> đó. Vì toán tử kết hợp là đệ quy, nên tất cả các phần tử <div> trong .top sẽ có cùng khoảng đệm được áp dụng cho chúng.

Hãy xem bảng điều khiển HTML trong bản minh hoạ này để biết cách phần tử .top có một số phần tử con <div>, bản thân các phần tử con này cũng có phần tử con <div>.

Toán tử kết hợp anh chị em tiếp theo

Bạn có thể tìm một phần tử ngay sau một phần tử khác bằng cách sử dụng ký tự + trong bộ chọn.

Để thêm khoảng trống giữa các phần tử xếp chồng, hãy sử dụng toán tử kết hợp phần tử đồng cấp tiếp theo để thêm khoảng trống chỉ nếu một phần tử là phần tử đồng cấp tiếp theo của một phần tử con của .top.

Bạn có thể thêm lề vào tất cả phần tử con của .top bằng cách sử dụng bộ chọn sau:

.top * {
  margin-top: 1em;
}

Vấn đề ở đây là vì bạn đang chọn mọi phần tử con của .top, nên quy tắc này có thể tạo ra khoảng trống thừa, không cần thiết. Toán tử kết hợp thành phần đồng cấp tiếp theo, kết hợp với bộ chọn phổ quát, cho phép bạn không chỉ kiểm soát những phần tử nào có khoảng trống, mà còn áp dụng khoảng trống cho bất kỳ phần tử nào. Điều này mang lại cho bạn một số tính linh hoạt lâu dài, bất kể phần tử HTML nào xuất hiện trong .top.

Toán tử kết hợp tiếp theo

Một bộ kết hợp tiếp theo rất giống với bộ chọn thành phần đồng cấp tiếp theo. Tuy nhiên, thay vì ký tự +, hãy sử dụng ký tự ~. Điểm khác biệt là một phần tử chỉ cần tuân theo một phần tử khác có cùng phần tử mẹ, thay vì là phần tử tiếp theo có cùng phần tử mẹ.

Sử dụng bộ chọn tiếp theo cùng với lớp giả lập `:checked` để tạo phần tử nút chuyển CSS thuần tuý.

Toán tử kết hợp tiếp theo này cung cấp ít độ cứng hơn một chút, rất hữu ích trong các ngữ cảnh như mẫu trên, trong đó chúng ta thay đổi màu của nút chuyển tuỳ chỉnh khi hộp đánh dấu liên kết có trạng thái :checked.

Toán tử kết hợp con

Một bộ kết hợp con (còn gọi là phần tử con trực tiếp) cho phép bạn kiểm soát nhiều hơn đối với quá trình đệ quy đi kèm với bộ chọn bộ kết hợp. Bằng cách sử dụng ký tự >, bạn giới hạn bộ chọn bộ kết hợp để chỉ áp dụng cho các phần tử con trực tiếp.

Hãy xem xét ví dụ về bộ chọn thành phần đồng cấp trước và sau. Khoảng trắng được thêm vào mỗi phần tử đồng cấp tiếp theo, nhưng nếu một trong các phần tử đó cũng có phần tử đồng cấp tiếp theo làm phần tử con, thì điều này có thể dẫn đến khoảng trắng không mong muốn.

Để giảm thiểu vấn đề này, hãy thay đổi bộ chọn thành phần đồng cấp tiếp theo để kết hợp với một bộ kết hợp con: > * + *. Giờ đây, quy tắc này chỉ áp dụng cho phần tử con trực tiếp của .top.

Bộ chọn phức hợp

Bạn có thể kết hợp các bộ chọn để tăng độ cụ thể và dễ đọc. Ví dụ: để nhắm đến các phần tử <a> cũng có lớp .my-class, hãy viết như sau:

a.my-class {
  color: red;
}

Thao tác này sẽ không áp dụng màu đỏ cho tất cả đường liên kết và cũng chỉ áp dụng màu đỏ cho .my-class if đường liên kết đó nằm trên phần tử <a>. Để biết thêm thông tin về vấn đề này, hãy xem mô-đun tính năng.

Kiểm tra mức độ hiểu biết

Kiểm tra kiến thức của bạn về bộ chọn phức tạp

Ký hiệu nào sau đây không phải là toán tử kết hợp bộ chọn?

>
Toán tử kết hợp con trực tiếp.
÷
Không hợp lệ, không phải là ký hiệu CSS.
+
Toán tử kết hợp đồng cấp tiếp theo.
*
Bộ chọn đơn giản chung này.
.
Bộ chọn đơn giản của lớp.
section.awesome {
  border: 1px solid hotpink;
}

Bộ chọn ở trên là ví dụ về...

Toán tử kết hợp
Biểu tượng dùng để kết hợp các bộ chọn thành một bộ chọn cụ thể hơn.
Bộ chọn phức hợp
Khi 2 hoặc nhiều bộ chọn được sử dụng cùng nhau, mà không có bộ kết hợp, để tạo một bộ chọn cụ thể hơn.
Dấu chấm hết
Không phải là loại bộ chọn, nhưng có vẻ như vậy phải không? 🤖

Tài nguyên