Truy vấn vùng chứa bắt đầu xuất hiện trong các trình duyệt ổn định trong khi polyfill có bản cập nhật lớn

Đã có truy vấn vùng chứa!

Tin vui—một trong những tính năng được yêu cầu nhiều nhất dành cho nhà phát triển đã bắt đầu có mặt trên các trình duyệt web! Kể từ Chromium 105Safari 16, bạn hiện có thể tạo truy vấn vùng chứa dựa trên kích thước và sử dụng giá trị đơn vị truy vấn vùng chứa trong các trình duyệt này. Để giúp việc sử dụng các truy vấn vùng chứa dựa trên kích thước và đơn vị cq trở nên dễ dàng hơn nữa, nhóm Aurora tại Chrome đã nỗ lực cập nhật Polyfill truy vấn vùng chứa để hỗ trợ thêm nhiều trình duyệt và trường hợp sử dụng khác, nhờ đó, bạn có thể tự tin sử dụng tính năng mạnh mẽ này ngay hôm nay.

Truy vấn vùng chứa là gì?

Truy vấn vùng chứa là một tính năng CSS cho phép bạn viết logic định kiểu nhắm mục tiêu đến các tính năng của phần tử mẹ để tạo kiểu cho phần tử con. Bạn có thể tạo thiết kế thích ứng thực sự dựa trên thành phần bằng cách truy vấn kích thước của thành phần mẹ. Đây là thông tin chi tiết và hữu ích hơn nhiều so với những thông tin như truy vấn nội dung nghe nhìn chỉ cung cấp thông tin kích thước của khung nhìn.

ALT_TEXT_HERE

Với truy vấn vùng chứa, bạn có thể viết các thành phần có thể sử dụng lại và có thể xuất hiện theo cách khác nhau dựa trên vị trí của các thành phần đó trên trang. Điều này giúp họ linh hoạt và phản hồi nhanh hơn nhiều trên các trang và mẫu.

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

Giả sử bạn có một số HTML:

<!-- card parent -->
<div class=”card-parent”>
  <div class=”card>
     <!-- card contents -->
      …
  </div>
</div>

Để sử dụng truy vấn vùng chứa, trước tiên bạn cần đặt vùng chứa cho phần tử mẹ mà bạn muốn theo dõi. Bạn có thể thực hiện việc này bằng cách đặt thuộc tính container-type hoặc sử dụng cú pháp viết tắt container để đặt đồng thời loại vùng chứa và tên vùng chứa.

.card-parent {
  /* query the inline-direction size of this parent */
  container-type: inline-size;
}

Giờ đây, bạn có thể sử dụng quy tắc @container để đặt kiểu dựa trên kiểu mẹ gần nhất. Đối với thiết kế như hình ảnh ở trên, trong đó thẻ có thể đi từ một cột đến hai cột, hãy viết nội dung như sau:

@container (min-width: 300px) {
  .card {
    /* styles to apply when the card container (.card-parent in this case) is >= 300px */
    /* I.e. shift from 1-column to 2-column layout: */
    grid-template-columns: 1fr 1fr;
  }
}

Để gọn gàng và rõ ràng hơn, hãy đặt tên cho vùng chứa phần tử mẹ:

.card-parent {
  container-type: inline-size;
  /* set name here, or write this in one line using the container shorthand */
  container-name: card-container;
}

Sau đó, viết lại mã trước đó như sau:

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

Đơn vị truy vấn vùng chứa

Để làm cho các truy vấn vùng chứa hữu ích hơn nữa, bạn cũng có thể sử dụng các giá trị đơn vị dựa trên vùng chứa. Bảng sau đây cho thấy các giá trị đơn vị vùng chứa có thể có và cách các giá trị đó tương ứng với kích thước của một vùng chứa:

đơn vịcó liên quan đến
cqw1% chiều rộng của vùng chứa truy vấn
cqh1% chiều cao của vùng chứa truy vấn
cqi1% kích thước cùng dòng của vùng chứa truy vấn
cqb1% kích thước khối của vùng chứa truy vấn
cqminGiá trị cqua hoặc cquab nhỏ hơn
cqmaxGiá trị lớn hơn của cqua hoặc cquab

Một ví dụ về cách bạn sử dụng đơn vị dựa trên vùng chứa là kiểu chữ thích ứng. Bạn có thể dùng các đơn vị dựa trên khung nhìn (chẳng hạn như vh, vb, vwvi) để xác định kích thước bất kỳ phần tử nào trên màn hình.

.card h2 {
  font-size: 15cqi;
}

Mã này sẽ làm cho kích thước phông chữ bằng 15% kích thước cùng dòng của vùng chứa, có nghĩa là kích thước sẽ lớn hơn khi kích thước cùng dòng (chiều rộng) tăng hoặc nhỏ hơn khi giảm. Để thực hiện điều này hơn nữa, hãy sử dụng hàm clamp() để đặt giới hạn kích thước tối thiểu và tối đa cho kiểu chữ của bạn, đồng thời định kích thước kiểu chữ một cách thích ứng dựa trên kích thước vùng chứa:

.card h2 {
  font-size: clamp(1.5rem, 15cqi, 3rem);
}

Giờ đây, tiêu đề sẽ không bao giờ lớn hơn 3rem hoặc nhỏ hơn .5rem, nhưng sẽ chiếm 15% kích thước cùng dòng của vùng chứa ở bất kỳ đâu trong khoảng đó.

Bản minh hoạ này thực hiện thêm một bước nữa và cập nhật thẻ rộng hơn để có phạm vi kích thước nhỏ hơn, vì thẻ hiển thị trong chế độ xem 2 cột.

Thẻ polyfill truy vấn vùng chứa

Bởi vì truy vấn vùng chứa là một tính năng rất hiệu quả, nên chúng tôi muốn bạn có thể cảm thấy thoải mái khi kết hợp tính năng này vào dự án của mình, và hiểu rằng hỗ trợ trình duyệt là một phần quan trọng trong quá trình đó. Do đó, chúng tôi đang nỗ lực cải tiến polyfill Truy vấn vùng chứa. Tính năng polyfill này được hỗ trợ chung trong:

  • Firefox 69 trở lên
  • Chrome 79 trở lên
  • Edge 79 trở lên
  • Safari 13.4 trở lên

Tệp này có kích thước dưới 9 kb khi nén và sử dụng ResizeObserver với MutationObserver để hỗ trợ cú pháp truy vấn @container đầy đủ hiện có trong các trình duyệt ổn định:

  • Truy vấn rời rạc (width: 300pxmin-width: 300px).
  • Truy vấn dải ô (200px < width < 400pxwidth < 400px).
  • Đơn vị độ dài tương đối của vùng chứa (cqw, cqh, cqi, cqb, cqmincqmax) trong thuộc tính và khung hình chính.

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

Để sử dụng đoạn mã polyfill, hãy thêm thẻ tập lệnh này vào phần đầu tài liệu của bạn: :

<script type="module">
  if (!("container" in document.documentElement.style)) {
    import("https://unpkg.com/container-query-polyfill@^0.2.0");
  }
</script>

Bạn cũng nên sử dụng một dịch vụ để phân phối polyfill có điều kiện dựa trên User-Agent hoặc tự lưu trữ polyfill tại nguồn của riêng bạn.

Để có trải nghiệm người dùng tốt nhất, ban đầu, bạn chỉ nên sử dụng polyfill cho nội dung dưới màn hình đầu tiên và sử dụng các truy vấn @supports để tạm thời thay thế polyfill đó bằng một chỉ báo tải cho đến khi polyfill đã sẵn sàng hiển thị:

@supports not (container-type: inline-size) {
  .container,
  footer {
    display: none;
  }

  .loader {
    display: flex;
  }
}

Trên các mạng và thiết bị đủ nhanh hoặc thiết bị có hỗ trợ sẵn các truy vấn vùng chứa, chỉ báo tải này sẽ không bao giờ hiển thị.

Các tính năng mới của thẻ polyfill

Tính năng polyfill mới cập nhật hỗ trợ:

  • Các quy tắc @container lồng nhau.
  • Hỗ trợ lồng các quy tắc @container trong truy vấn @supports@media và ngược lại.
  • CSS có điều kiện như @supports (container-type: inline-size) sẽ truyền sau khi polyfill được tải.
  • Hỗ trợ đầy đủ về cú pháp CSS (không còn bất kỳ vấn đề nào với việc đặt nhận xét ở bất kỳ vị trí nào có cú pháp hợp lệ).
  • Chế độ viết dọc (thông qua chế độ viết).
  • Đơn vị tương đối của vùng chứa (cqw, cqh, v.v.) được hỗ trợ trong điều kiện truy vấn, phần khai báo thuộc tính và khung hình động. remem được hỗ trợ trong các điều kiện truy vấn.
  • Cú pháp truy vấn vùng chứa mở rộng:
    • Cú pháp dải ô (ví dụ: (200px < width < 400px)).
    • Truy vấn đẳng thức (ví dụ: (width = 200px)).
  • Các phần tử giả như ::before::after.
  • Những trình duyệt không có :is(...)/:where(...) được hỗ trợ thông qua một giải pháp không bắt buộc
  • Các truy vấn tính năng orientationaspect-ratio.
  • Lọc đúng truy vấn dựa trên các tính năng (ví dụ: không được phép truy vấn height trên container: inline-size với chế độ ghi theo chiều ngang).
  • Sự đột biến của DOM (ví dụ: các phần tử <style><link> sẽ bị xoá trong thời gian chạy).

Giới hạn và cảnh báo của polyfill

Nếu bạn đang sử dụng polyfill truy vấn vùng chứa, có một số tính năng bị thiếu cần chú ý:

  • DOM tối chưa được hỗ trợ.
  • Đơn vị tương đối của vùng chứa (ví dụ: cqwcqh) không được hỗ trợ trong điều kiện truy vấn @media.
    • Safari: Đơn vị tương đối của vùng chứa không được hỗ trợ trong khung hình chính hoạt ảnh trước 15.4.
  • Hàm calc(), min(), max() hoặc các hàm toán học khác chưa được hỗ trợ trong điều kiện truy vấn.
  • Thẻ polyfill này chỉ hoạt động với CSS cùng dòng và có cùng nguồn gốc. Không hỗ trợ biểu định kiểu chéo nguồn gốc và biểu định kiểu trong iframe (trừ phi polyfill được tải theo cách thủ công)
  • Vùng chứa layoutstyle yêu cầu hỗ trợ cơ bản cho trình duyệt:
    • Safari 15.4 trở lên
    • Firefox không hỗ trợ tính năng chặn kiểu tại thời điểm này, nhưng đang hoạt động với tính năng này.

Cảnh báo

  • Để tránh ảnh hưởng đến FIDCLS, thẻ polyfill không đảm bảo về thời điểm bố cục đầu tiên sẽ xuất hiện, ngay cả khi được tải đồng bộ, ngoại trừ việc polyfill sẽ cố gắng tránh trì hoãn LCP một cách không hợp lý. Nói cách khác, bạn không bao giờ nên dựa vào giao diện này trong lần hiển thị đầu tiên.
  • Tạo ResizeObserver Loop Errors. Quảng cáo polyfill ban đầu cũng vậy, nhưng bạn cũng nên lưu ý. Điều này xảy ra vì kích thước khối của container-type: inline-size có thể sẽ thay đổi sau khi đánh giá một truy vấn, nhưng ResizeObserver không có cách nào để cho biết rằng chúng ta không quan tâm đến các thay đổi về kích thước khối.
  • Đoạn polyfill này được thử nghiệm dựa trên các Bài kiểm tra nền tảng web và đạt 70% đạt vì một số tính năng nhất định như API JavaScript không được điền poly, do đó, tỷ lệ vượt qua có chủ đích gần với 70%.
  • Giải pháp :where() là bắt buộc đối với 2,23% người dùng trình duyệt cũ hơn:
    • Safari 14
    • Chromium 88
    • Edge 88
    • Internet Samsung 15
    • Firefox 78