@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() hoàn toàn trùng khớp. 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 khổng lồ với hai tính năng được yêu cầu cao cho giao diện thích ứng!

Truy vấn vùng chứa: bản 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 thông tin về kích thước và kiểu, giúp phần tử con có thể sở hữu logic tạo 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, chẳng hạn như không gian có sẵn, nhà phát triển giờ đây 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 định kiểu thích ứng. Điều này giúp thành phần trở nên linh hoạt hơn nhiều, vì logic định 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

Để xây dựng bằng các truy vấn vùng chứa, trước tiên, bạn phải đặt 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ó thẻ có hình ảnh và một số nội dung văn bản như sau:

Thẻ hai cột duy nhấ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 theo hướng cùng dòng của thành phần mẹ. Trong 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 nội tuyến từ trái sang phải.

Giờ đây, chúng ta có thể dùng vùng chứa đó để áp dụng các kiểu cho bất kỳ phần tử con nào bằng cách sử dụ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 với các tham số cụ thể hay không.

Ví dụ: p:has(span) cho biết bộ chọn đoạ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 đoạn mẹ hoặc hoặc tạo kiểu cho nội dung bất kỳ trong đoạn đó. Một ví dụ hữu ích là figure:has(figcaption) để tạo kiểu cho một phần tử figure có chứa phụ đề. 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 các 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? Có thể bạn 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 để trang web có chủ đí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à hiển thị trong một cột.

Trong ví dụ này, thẻ chứa hình ảnh có mẫu lưới gồm 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 thông số kỹ thuật tương tự như :has() nhưng đã tồn tại lâu hơn nhiều và có 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 đoạn mã trên, bạn đang viết một bộ chọn có tác dụng 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 cỡ chữ rất 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 các truy vấn về vùng chứa thực sự nổi bật khi bạn có thể thấy cùng một phần tử được dùng ở nhiều nơi. Hãy thêm chút phong cách và giới thiệu những 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ẽ. Hai tính năng mạnh mẽ này đã có mặt trong Chromium 105 và ngày càng được hỗ trợ trên nhiều trình duyệt, đây là thời điểm thú vị để trở thành một nhà phát triển giao diện người dùng!