CSS anh chị em của cha mẹ

Chúng tôi sử dụng bộ chọn anh chị em liền kề (+), nếu chúng tôi muốn khớp phần tử xuất hiện ngay sau bộ chọn đầu tiên. Ở đây, cả hai bộ chọn đều là con của cùng một phần tử cha

Cú pháp của bộ kết hợp anh chị em liền kề CSS như sau -

Selector + Selector{
   attribute: /*value*/
}

Nếu chúng tôi muốn chọn anh chị em của cùng một cha mẹ bất kể vị trí của phần tử được chọn thứ hai, chúng tôi sử dụng bộ kết hợp anh chị em chung CSS

Adrian Bece là nhà phát triển web toàn diện với kinh nghiệm sâu rộng về Thương mại điện tử. Anh ấy thích viết và nói về những công nghệ mới nhất và tốt nhất trên web … Thông tin thêm về Adrian ↬

Bản tin email

Email (đập vỡ) của bạn

Mẹo hàng tuần về giao diện người dùng & UX.
Được hơn 200.000 người tin cậy.

  • CSS anh chị em của cha mẹ
    Các mẫu thiết kế giao diện thông minh, khóa học 8h-video

  • CSS anh chị em của cha mẹ
    Hệ thống thiết kế thành công

  • CSS anh chị em của cha mẹ
    Danh sách kiểm tra thiết kế giao diện thông minh

  • CSS anh chị em của cha mẹ
    Giao diện người dùng SmashingConf 2023

  • CSS anh chị em của cha mẹ
    Bắt đầu miễn phí

Điều gì làm cho bộ chọn quan hệ trở thành một trong những tính năng được yêu cầu nhiều nhất và làm cách nào chúng tôi, với tư cách là nhà phát triển, giải quyết việc không có nó?

Bộ chọn gốc đã nằm trong danh sách mong muốn của các nhà phát triển trong hơn 10 năm và nó đã trở thành một trong những tính năng CSS được yêu cầu nhiều nhất bên cạnh các truy vấn vùng chứa kể từ đó. Lý do chính khiến tính năng này không được triển khai trong thời gian này dường như là do những lo ngại về hiệu suất. Điều tương tự cũng được nói về các truy vấn bộ chứa và những truy vấn này hiện đang được thêm vào các phiên bản beta của trình duyệt, vì vậy những hiệu suất đó dường như không còn là vấn đề nữa

Công cụ kết xuất trình duyệt đã được cải thiện khá nhiều kể từ đó. Quá trình kết xuất đã được tối ưu hóa đến mức các trình duyệt có thể xác định một cách hiệu quả những gì cần được kết xuất hoặc cập nhật và những gì không, mở đường cho một bộ tính năng mới và thú vị

Brian Kardell gần đây đã thông báo rằng nhóm của anh ấy tại Igalia hiện đang tạo mẫu một bộ chọn

:has() { /* .. */ }
9 sẽ đóng vai trò là bộ chọn chính, nhưng nó có thể có phạm vi sử dụng rộng hơn nhiều ngoài nó. Cộng đồng nhà phát triển gọi nó là "bộ chọn gốc" và một số nhà phát triển đã chỉ ra rằng cái tên này không chính xác lắm. Một tên phù hợp hơn sẽ là bộ chọn quan hệ hoặc lớp giả quan hệ theo thông số kỹ thuật, vì vậy tôi sẽ đề cập đến
:has() { /* .. */ }
9 như vậy kể từ bây giờ trong bài viết

Nhóm tại Igalia đã làm việc trên một số tính năng công cụ web đáng chú ý như truy vấn vùng chứa và lưới CSS, do đó, bộ chọn

:has() { /* .. */ }
9 có cơ hội nhìn thấy ánh sáng ban ngày, nhưng vẫn còn một chặng đường dài phía trước

Điều gì làm cho bộ chọn quan hệ trở thành một trong những tính năng được yêu cầu nhiều nhất trong vài năm qua và các nhà phát triển đang khắc phục bộ chọn bị thiếu như thế nào?

Các trường hợp sử dụng tiềm năng

Bộ chọn quan hệ sẽ hữu ích cho việc áp dụng kiểu có điều kiện cho các thành phần giao diện người dùng dựa trên nội dung hoặc trạng thái của phần tử con hoặc phần tử kế tiếp của nó trong cây DOM. Nguyên mẫu bộ chọn quan hệ sắp tới có thể mở rộng phạm vi và các trường hợp sử dụng cho các bộ chọn hiện có, cải thiện chất lượng và độ mạnh của CSS, đồng thời giảm nhu cầu sử dụng JavaScript để áp dụng các kiểu và lớp CSS cho các trường hợp sử dụng đó

Hãy xem một vài ví dụ cụ thể để giúp chúng tôi minh họa nhiều trường hợp sử dụng tiềm năng

Biến thể dựa trên nội dung

Một số thành phần giao diện người dùng có thể có nhiều biến thể dựa trên các khía cạnh khác nhau — nội dung, vị trí trên trang, trạng thái con, v.v. Trong những trường hợp đó, chúng tôi thường tạo nhiều lớp CSS để bao gồm tất cả các biến thể có thể có và áp dụng chúng theo cách thủ công hoặc bằng JavaScript, tùy thuộc vào cách tiếp cận và ngăn xếp công nghệ

CSS anh chị em của cha mẹ
Bốn biến thể thẻ tùy thuộc vào nội dung. Bố cục vùng chứa thẻ gốc phụ thuộc vào nội dung và vùng chứa hình ảnh thẻ được tạo kiểu khác nhau tùy thuộc vào việc vùng chứa hình ảnh có chú thích hình ảnh hay không. (Xem trước lớn)

Ngay cả khi sử dụng phương pháp đặt tên CSS như BEM, các nhà phát triển cần theo dõi các lớp CSS khác nhau và đảm bảo áp dụng chúng một cách chính xác cho phần tử cha và, tùy chọn, cho các phần tử con bị ảnh hưởng. Tùy thuộc vào số lượng các biến thể, các kiểu thành phần có thể nhanh chóng vượt khỏi tầm kiểm soát và trở nên khó quản lý cũng như duy trì dẫn đến lỗi, vì vậy các nhà phát triển sẽ cần ghi lại tất cả các biến thể và trường hợp sử dụng bằng cách sử dụng các công cụ như Storybook

Với bộ chọn CSS quan hệ, các nhà phát triển có thể viết kiểm tra nội dung trực tiếp bằng CSS và các kiểu sẽ được áp dụng tự động. Điều này sẽ làm giảm số lượng các lớp CSS biến thể, giảm khả năng xảy ra lỗi do lỗi của con người và các bộ chọn sẽ tự ghi lại bằng các kiểm tra điều kiện

Kiểu dựa trên xác thực

CSS hỗ trợ các lớp giả đầu vào như

:has() { /* .. */ }
4 và
:has() { /* .. */ }
5 để nhắm mục tiêu các phần tử xác thực thành công và các phần tử xác thực không thành công, xin trân trọng. Được kết hợp với các thuộc tính đầu vào HTML như
:has() { /* .. */ }
6 và
:has() { /* .. */ }
7, nó cho phép xác thực biểu mẫu gốc mà không cần dựa vào JavaScript

Tuy nhiên, việc nhắm mục tiêu các phần tử có

:has() { /* .. */ }
4 và
:has() { /* .. */ }
5 bị giới hạn trong việc nhắm mục tiêu chính phần tử đó hoặc phần tử liền kề của nó. Tùy thuộc vào thiết kế và cấu trúc HTML, các phần tử vùng chứa đầu vào hoặc các phần tử trước như phần tử
/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
0 cũng cần áp dụng một số kiểu

CSS anh chị em của cha mẹ
Các vùng chứa đầu vào email riêng lẻ thay đổi kiểu dựa trên tính hợp lệ của trạng thái đầu vào email. Khi tất cả các đầu vào được xác thực thành công, nút gửi (nằm ngay sau vùng chứa đầu vào cuối cùng trong DOM) sẽ được bật. (Xem trước lớn)

Bộ chọn quan hệ sẽ mở rộng trường hợp sử dụng cho các lớp giả trạng thái đầu vào như

:has() { /* .. */ }
4 và
:has() { /* .. */ }
5 bằng cách cho phép phần tử cha hoặc các phần tử trước đó được tạo kiểu dựa trên giá trị đầu vào

Điều này không chỉ áp dụng cho các lớp giả đó. Khi làm việc với API bên ngoài trả về các thông báo lỗi được thêm vào vùng chứa đầu vào, sẽ không cần phải áp dụng lớp CSS thích hợp cho vùng chứa. Bằng cách viết một bộ chọn quan hệ với điều kiện kiểm tra xem bộ chứa thông báo con có trống không, các kiểu thích hợp có thể được áp dụng cho bộ chứa

Thêm sau khi nhảy. Tiếp tục đọc bên dưới ↓

Gặp gỡ Hội thảo trực tuyến Smashing về giao diện người dùng & giao diện người dùng, với các bài học thực tế, phiên trực tiếp, bản ghi video và phần Hỏi & Đáp thân thiện. Trên các hệ thống thiết kế, UX, hiệu suất web và CSS/JS. Với Brad Frost, Stephanie Troeth và rất nhiều người khác

Chuyển đến hội thảo ↬

CSS anh chị em của cha mẹ

Phần tử con

Đôi khi một phần tử cha hoặc các kiểu phần tử trước đó phụ thuộc vào trạng thái của phần tử đích. Trường hợp này khác với trạng thái xác thực vì trạng thái không liên quan chặt chẽ đến tính hợp lệ của đầu vào

Giống như trong ví dụ trước, lớp giả

/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
3 cho các phần tử đầu vào hộp kiểm và radio được giới hạn để nhắm mục tiêu vào chính phần tử đó hoặc phần tử liền kề của nó. Điều này không giới hạn ở các lớp giả như
/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
3,
/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
5,
/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
6,
/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
7, v.v. nhưng với bất kỳ thứ gì khác mà bộ chọn CSS có thể nhắm mục tiêu như tính khả dụng của phần tử cụ thể, thuộc tính, lớp CSS, id, v.v.

Bộ chọn quan hệ sẽ mở rộng phạm vi và trường hợp sử dụng của bộ chọn CSS ngoài phần tử bị ảnh hưởng hoặc phần tử liền kề của nó

CSS anh chị em của cha mẹ
Khi một hoặc nhiều hộp kiểm trong trình đơn thả xuống bộ lọc được chọn, nút này sẽ thay đổi biểu tượng để biểu thị trạng thái bộ lọc đang hoạt động trong nhóm. (Xem trước lớn)

Chọn anh chị em trước đây

Bộ chọn CSS bị giới hạn bởi hướng lựa chọn — có thể chọn phần tử con hoặc phần tử theo sau, nhưng không thể chọn phần tử cha hoặc phần tử trước đó

Bộ chọn quan hệ cũng có thể được sử dụng làm bộ chọn anh chị em trước đó

CSS anh chị em của cha mẹ
Ví dụ nhập nhãn nổi từ Google Material UI. Nhãn (anh chị em trước đó) được tạo kiểu dựa trên trạng thái giá trị và tiêu điểm của đầu vào. (Xem trước lớn)

Bộ chọn /* Select image element that is a child of a figure element if figure element has a figcaption as a child */ figure:has(figcaption) img { /* .. */ } /* Select a button element that is a child of a form element if a child checkbox input element is checked */ form:has(input[type="checkbox"]:checked) button { /* .. */ } 8 nâng cao

Khi làm việc với các phần tử được tải động và sử dụng bộ tải khung, thông thường sẽ chuyển đổi một lớp CSS đang tải trên phần tử gốc bằng JavaScript sau khi dữ liệu được tìm nạp và các thành phần được điền dữ liệu

Bộ chọn quan hệ có thể loại bỏ nhu cầu về chức năng chuyển đổi lớp JavaScript CSS bằng cách mở rộng phạm vi và chức năng của lớp giả

/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }
8. Với bộ chọn quan hệ, các điều kiện cần thiết để hiển thị một phần tử có thể được xác định trong CSS bằng cách nhắm mục tiêu các phần tử HTML dữ liệu bắt buộc và kiểm tra xem phần tử đó có được điền dữ liệu hay không. Cách tiếp cận này sẽ hoạt động với các phần tử phức tạp và được lồng sâu

CSS anh chị em của cha mẹ
Trình giữ chỗ Skeleton được hiển thị trên trang gốc cho đến khi tất cả các vùng chứa dữ liệu (các phần tử đoạn được lồng sâu) được điền dữ liệu. (Xem trước lớn)

Đặc tả lớp giả CSS :has() { /* .. */ } 9

Hãy nhớ rằng

:has() { /* .. */ }
9 không được hỗ trợ trong bất kỳ trình duyệt nào nên các đoạn mã liên quan đến pseudo-class sắp tới sẽ không hoạt động. Lớp giả quan hệ được xác định trong đặc tả cấp 4 của bộ chọn đã được cập nhật kể từ lần phát hành đầu tiên vào năm 2011, vì vậy đặc tả đã được xác định rõ và sẵn sàng để tạo mẫu và phát triển

Như đã nói, chúng ta hãy đi sâu vào đặc tả lớp giả của

:has() { /* .. */ }
9. Ý tưởng đằng sau lớp giả là áp dụng các kiểu cho bộ chọn nếu điều kiện (được định nghĩa là bộ chọn CSS thông thường) đã được đáp ứng

:has() { /* .. */ }
7

Tương tự như các lớp giả khác như

:has() { /* .. */ }
83, bộ chọn giả quan hệ bao gồm các phần sau

:has() { /* .. */ }
  • :has() { /* .. */ }
    
    84
    Bộ chọn cho một phần tử sẽ được nhắm mục tiêu nếu điều kiện được chuyển dưới dạng đối số cho lớp giả
    :has() { /* .. */ }
    
    9 đã được đáp ứng. Bộ chọn điều kiện nằm trong phạm vi phần tử này.
  • :has() { /* .. */ }
    
    86
    Một điều kiện được xác định bằng bộ chọn CSS cần được đáp ứng để các kiểu được áp dụng cho bộ chọn.

Giống như hầu hết các lớp giả, bộ chọn có thể được xâu chuỗi để nhắm mục tiêu các phần tử con của phần tử đích hoặc phần tử liền kề

/* Select image element that is a child of a figure element if figure element has a figcaption as a child */
figure:has(figcaption) img { /* .. */ }

/* Select a button element that is a child of a form element if a child checkbox input element is checked */
form:has(input[type="checkbox"]:checked) button { /* .. */ }

Từ một vài ví dụ này, rõ ràng lớp giả

:has() { /* .. */ }
9 linh hoạt, mạnh mẽ và hữu ích như thế nào. Nó thậm chí có thể được kết hợp với các lớp giả khác như
:has() { /* .. */ }
83 để tạo các bộ chọn quan hệ phức tạp

:has() { /* .. */ }
8

Bộ chọn quan hệ không giới hạn ở nội dung và trạng thái con của phần tử đích, mà còn có thể nhắm mục tiêu các phần tử liền kề trong cây DOM, làm cho nó trở thành "bộ chọn anh chị em trước đó" một cách hiệu quả

:has() { /* .. */ }
5

Tóm lại, bộ chọn quan hệ neo lựa chọn CSS vào một phần tử có lớp giả

:has() { /* .. */ }
9 và ngăn lựa chọn di chuyển đến các phần tử được truyền dưới dạng đối số cho lớp giả

:has() { /* .. */ }
6

Cách tiếp cận và giải pháp hiện tại

Các nhà phát triển hiện phải sử dụng nhiều cách giải quyết khác nhau để bù cho bộ chọn quan hệ bị thiếu. Bất kể các giải pháp thay thế và như đã thảo luận trong bài viết này, rõ ràng bộ chọn quan hệ sẽ có tác động và thay đổi trò chơi như thế nào sau khi được phát hành

Trong bài viết này, chúng tôi sẽ đề cập đến hai cách tiếp cận được sử dụng nhiều nhất khi xử lý các trường hợp sử dụng mà bộ chọn quan hệ sẽ là lý tưởng

  • các lớp biến thể CSS
  • Giải pháp JavaScript và triển khai jQuery của lớp giả
    :has() { /* .. */ }
    
    9

Các lớp biến thể CSS cho các phần tử tĩnh

Với các lớp biến thể CSS (các lớp sửa đổi trong BEM), các nhà phát triển có thể gán thủ công một lớp CSS thích hợp cho các thành phần dựa trên nội dung của thành phần đó. Cách tiếp cận này phù hợp với các phần tử tĩnh có nội dung hoặc trạng thái không thay đổi sau lần kết xuất ban đầu

Hãy xem ví dụ về thành phần thẻ sau đây có một số biến thể tùy thuộc vào nội dung. Một số thẻ không có hình ảnh, một số khác không có mô tả và một thẻ có chú thích trên hình ảnh

Xem Bút [Các biến thể của thẻ](https. // codepen. io/smashingmag/pen/jOBpeQo) của Adrian Bece

Xem các biến thể Thẻ bút của Adrian Bece

Để các thẻ này có bố cục chính xác, nhà phát triển cần áp dụng các lớp CSS sửa đổi chính xác theo cách thủ công. Dựa trên thiết kế, các phần tử có thể có nhiều biến thể dẫn đến một số lượng lớn các lớp bổ trợ, đôi khi dẫn đến các giải pháp thay thế HTML sáng tạo để nhóm tất cả các lớp đó trong phần đánh dấu. Các nhà phát triển cần theo dõi các lớp CSS, duy trì tài liệu và đảm bảo áp dụng các lớp phù hợp

:has() { /* .. */ }
7

Giải pháp thay thế JavaScript

Đối với các trường hợp phức tạp hơn, khi kiểu phần tử gốc được áp dụng phụ thuộc vào trạng thái con hoặc nội dung phần tử thay đổi linh hoạt, nhà phát triển sử dụng JavaScript để áp dụng các kiểu cần thiết cho phần tử gốc tùy thuộc vào những thay đổi về nội dung hoặc trạng thái. Điều này thường được xử lý bằng cách viết một giải pháp tùy chỉnh theo từng trường hợp cụ thể

Xem Bút [Trạng thái nút lọc](https. // codepen. io/smashingmag/pen/LYWBgXy) của Adrian Bece

Xem trạng thái nút Bộ lọc bút của Adrian Bece

Bộ chọn quan hệ trong jQuery

Việc triển khai bộ chọn

:has() { /* .. */ }
9 quan hệ đã tồn tại trong thư viện JavaScript phổ biến jQuery từ năm 2007 và nó tuân theo đặc tả CSS. Tất nhiên, hạn chế chính của việc triển khai này là dòng jQuery cần được đính kèm theo cách thủ công được gọi bên trong trình xử lý sự kiện, trong khi việc triển khai CSS gốc sẽ là một phần của quy trình kết xuất trình duyệt và tự động phản hồi trạng thái trang và nội dung thay đổi

Tất nhiên, nhược điểm của phương pháp JavaScript và jQuery là phụ thuộc vào sự phụ thuộc vào thư viện JavaScript và jQuery, điều này có thể làm tăng kích thước tổng thể của trang và thời gian phân tích cú pháp JavaScript. Ngoài ra, người dùng đang duyệt Web khi tắt JavaScript sẽ gặp lỗi hình ảnh nếu dự phòng không được triển khai

:has() { /* .. */ }
8

Xem Bút [Đầu vào email — hợp lệ / không hợp lệ](https. // codepen. io/smashingmag/pen/BaWPqqO) của Adrian Bece

Xem đầu vào Pen Email — hợp lệ / không hợp lệ của Adrian Bece

Phần kết luận

Tương tự như các truy vấn bộ chứa, lớp giả

:has() { /* .. */ }
9 sẽ là yếu tố thay đổi cuộc chơi chính khi được triển khai trong trình duyệt. Bộ chọn quan hệ sẽ cho phép các nhà phát triển viết các bộ chọn mạnh mẽ và linh hoạt mà CSS hiện không thể thực hiện được

Ngày nay, các nhà phát triển đang xử lý chức năng bộ chọn gốc bị thiếu bằng cách viết nhiều lớp CSS bổ trợ cần được áp dụng thủ công hoặc bằng JavaScript, nếu bộ chọn phụ thuộc vào trạng thái phần tử con. Bộ chọn quan hệ sẽ giảm số lượng các lớp CSS sửa đổi bằng cách cho phép các nhà phát triển viết các bộ chọn mạnh mẽ tự ghi lại và sẽ giảm nhu cầu JavaScript để áp dụng các kiểu động

Bạn có thể nghĩ ra nhiều ví dụ hơn trong đó bộ chọn cha mẹ hoặc bộ chọn anh chị em trước đó sẽ hữu ích không?

CSS anh chị em là gì?

Bộ kết hợp anh chị em chung ( ~ ) tách hai bộ chọn và khớp với tất cả các lần lặp lại của phần tử thứ hai, theo sau phần tử đầu tiên (mặc dù không nhất thiết phải ngay lập tức) và là con của cùng một phần tử cha. /* Các đoạn là anh em của và sau bất kỳ hình ảnh nào */ img ~ p { color. màu đỏ;

Có bộ chọn gốc CSS không?

"Bộ chọn gốc", tính năng CSS được chờ đợi nhiều thứ hai theo Khảo sát trạng thái của CSS năm 2021, còn được gọi là bộ chọn có , đã được hỗ trợ trình duyệt. Đừng nói Safari luôn là cuối cùng. Đôi khi chúng ta là người đầu tiên.

Tôi có thể chọn một CSS anh em trước đó không?

Không, không có bộ chọn "anh chị em trước" . Trên một ghi chú liên quan, ~ dành cho anh chị em kế thừa chung (có nghĩa là phần tử xuất hiện sau phần tử này, nhưng không nhất thiết phải ngay sau) và là bộ chọn CSS3. + dành cho anh chị em tiếp theo và là CSS2. 1.

Tổ hợp anh chị em liền kề là gì?

Bộ kết hợp anh chị em liền kề ( + ) tách hai bộ chọn và chỉ khớp với phần tử thứ hai nếu nó ngay sau phần tử đầu tiên và cả hai đều là phần tử con của cùng một phần tử cha .