@container và :has(): hai API thích ứng mới và mạnh mẽ xuất hiện trong Chromium 105

Truy vấn vùng chứa và :has() là một sự kết hợp hoàn hảo cho thiết kế thích ứng. Thật may là cả hai tính năng này đều đang hoạt động cùng nhau trong Chromium 105. Đây là một bản phát hành lớn với hai tính năng được yêu cầu nhiều cho giao diện thích ứng!

Truy vấn vùng chứa: thông tin tóm tắt nhanh

Truy vấn vùng chứa cho phép nhà phát triển truy vấn bộ chọn mẹ để biết kích thước và thông tin định kiểu, giúp phần tử con có thể sở hữu logic định kiểu thích ứng, bất kể phần tử đó nằm ở đâu trên trang web.

Thay vì dựa vào khung nhìn để nhập kiểu như không gian có sẵn, giờ đây, nhà phát triển cũng có thể truy vấn kích thước của các phần tử trong trang. Khả năng này có nghĩa là một thành phần sở hữu logic tạo kiểu thích ứng. Điều này giúp thành phần linh hoạt hơn nhiều, vì logic tạo kiểu được đính kèm với thành phần đó, bất kể thành phần đó xuất hiện ở đâu trên trang.

Sử dụng truy vấn vùng chứa

Để tạo bằng truy vấn vùng chứa, trước tiên, bạn phải thiết lập vùng chứa trên một phần tử mẹ. Thực hiện việc này bằng cách đặt container-type trên vùng chứa mẹ. Bạn có thể có một thẻ có hình ảnh và một số nội dung văn bản như sau:

Thẻ đơn có hai cột.

Để tạo truy vấn vùng chứa, hãy đặt container-type trên vùng chứa thẻ:

.card-container {
  container-type: inline-size;
}

Việc đặt container-type thành inline-size sẽ truy vấn kích thước hướng nội tuyến của thành phần mẹ. Trong các ngôn ngữ Latinh như tiếng Anh, đây sẽ là chiều rộng của thẻ vì văn bản chạy cùng dòng từ trái sang phải.

Bây giờ, chúng ta có thể sử dụng vùng chứa đó để áp dụng kiểu cho bất kỳ phần tử con nào bằng @container:

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}

Bộ chọn mẹ :has()

Lớp giả :has() CSS cho phép nhà phát triển kiểm tra xem phần tử mẹ có chứa phần tử con có các tham số cụ thể hay không.

Ví dụ: p:has(span) cho biết bộ chọn đoạn văn (p) có span bên trong. Bạn có thể sử dụng thuộc tính này để tạo kiểu cho chính đoạn văn bản mẹ, hoặc tạo kiểu cho bất kỳ nội dung nào trong đoạn văn bản mẹ. Một ví dụ hữu ích là figure:has(figcaption) để tạo kiểu cho phần tử figure chứa chú thích. Bạn có thể xem thêm nhiều thông tin về :has() trong bài viết này của Jhey Tompkins.

Truy vấn vùng chứa và :has()

Bạn có thể kết hợp sức mạnh lựa chọn mẹ của :has() với sức mạnh truy vấn mẹ của truy vấn vùng chứa để tạo một số kiểu nội tại thực sự linh hoạt.

Hãy mở rộng ví dụ đầu tiên bằng thẻ tên lửa. Nếu bạn có thẻ không có hình ảnh thì sao? Bạn có thể muốn tăng kích thước của tiêu đề và điều chỉnh bố cục lưới thành một cột để tiêu đề trông có chủ ý hơn khi không có hình ảnh.

Văn bản lớn hơn trên thẻ không có hình ảnh và văn bản này xuất hiện trong một cột.

Trong ví dụ này, thẻ có hình ảnh có mẫu lưới hai cột, trong khi thẻ không có hình ảnh có bố cục một cột. Ngoài ra, thẻ không có hình ảnh có tiêu đề lớn hơn. Để viết mã này bằng :has(), hãy sử dụng CSS sau.

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}

Bạn đang tìm một phần tử có lớp visual để áp dụng kiểu hai cột ở trên. Một hàm CSS gọn khác là :not(). Đây là một phần của cùng một thông số kỹ thuật như :has() nhưng đã xuất hiện lâu hơn nhiều và có khả năng hỗ trợ trình duyệt tốt hơn. Bạn thậm chí có thể kết hợp :has():not(), như sau:

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}

Trong mã trên, bạn đang viết một bộ chọn tạo kiểu cho h1 trong một thẻ không chứa lớp visual. Đây là cách bạn có thể điều chỉnh kích thước phông chữ một cách rõ ràng.

Kết hợp kiến thức đã học

Bản minh hoạ ở trên cho thấy sự kết hợp của :has(), :not()@container, nhưng truy vấn vùng chứa thực sự tỏa sáng khi bạn có thể thấy cùng một phần tử được sử dụng ở nhiều vị trí. Hãy thêm một chút kiểu dáng và hiển thị các thẻ này trong một lưới cạnh nhau.

Giờ đây, bạn có thể thực sự thấy được sức mạnh của CSS hiện đại. Chúng ta có thể viết các kiểu rõ ràng bằng cách sử dụng các kiểu được nhắm mục tiêu, xây dựng logic dựa trên logic và tạo ra các thành phần thực sự mạnh mẽ. Với hai tính năng mạnh mẽ này trong Chromium 105 và đang tăng tốc hỗ trợ trên nhiều trình duyệt, đây là thời điểm thú vị để trở thành nhà phát triển giao diện người dùng!