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ó cụm từ tìm kiếm về 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 bạn dễ dàng sử dụng các truy vấn vùng chứa dựa trên kích thước và đơn vị cq hơn nữa, nhóm Aurora tại Chrome đã nỗ lực cập nhật Trình bổ sung nhiều phương thức truy vấn vùng chứa để hỗ trợ nhiều trình duyệt và trường hợp sử dụng hơn. 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 đến các tính năng của phần tử mẹ để định 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 các thông tin như truy vấn nội dung nghe nhìn chỉ cung cấp thông tin về 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 có thể xuất hiện khác nhau dựa trên vị trí của các thành phần đó trong trang. Nhờ đó, các thẻ này trở nên 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 trên 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 ký hiệu viết tắt container để đặt loại vùng chứa và tên vùng chứa cùng một lúc.

.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 thành phần mẹ gần nhất. Đối với thiết kế như hình trên, trong đó thẻ có thể chuyển từ một cột thành hai cột, hãy viết nội dung như:

@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 đó, hãy 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ị này tương ứng với kích thước của vùng chứa:

đơn vịso với
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 nội tuyến 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ị nhỏ hơn của cqi hoặc cqb
cqmaxGiá trị cqi hoặc cqb lớn hơn

Một ví dụ về cách bạn sẽ sử dụng các đơn vị dựa trên vùng chứa là kiểu chữ thích ứng. Các đơn vị dựa trên khung nhìn (như vh, vb, vwvi) có thể dùng để đị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ẽ đặt cỡ chữ bằng 15% kích thước nội tuyến của vùng chứa, nghĩa là cỡ chữ sẽ lớn hơn khi kích thước nội tuyến (chiều rộng) tăng lên hoặc nhỏ hơn khi kích thước nội tuyến giảm xuống. Để thực hiện điều này hơn nữa, hãy sử dụng hàm clamp() để thiết lập 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 đặt kích thước cho kiểu chữ một cách linh hoạt dựa trên kích thước vùng chứa:

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

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

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

Truy vấn vùng chứa polyfill

Bởi vì truy vấn vùng chứa là một tính năng mạnh mẽ, 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à biết rằng hỗ trợ trình duyệt là một phần quan trọng trong việc đó. Do đó, chúng tôi đã nỗ lực cải thiện Vùng chứa truy vấn Polyfill. Trình bổ trợ 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 9kb khi được 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 phạm vi (200px < width < 400pxwidth < 400px).
  • Đơn vị độ dài tương đối của vùng chứa (cqw, cqh, cqi, cqb, cqmincqmax) trong các thuộc tính và khung hình chính.

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

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

<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 tệp polyfill theo điều kiện dựa trên User-Agent hoặc tự lưu trữ tệp đó trên nguồn gốc của riêng mình.

Để mang đến trải nghiệm tốt nhất cho người dùng, 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ế bằng 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ị 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 Polyfill

Polyfill đã 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ẽ chuyển sau khi polyfill tải.
  • Hỗ trợ đầy đủ 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ỳ nơi nào chúng 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 các điều kiện truy vấn, phần khai báo thuộc tính và khung hình chính của ả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 bằng nhau (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 chính xác các truy vấn dựa trên các tính năng (ví dụ: truy vấn height trên container: inline-size bị từ chối chính xác bằng chế độ ghi ngang).
  • Sự thay đổi DOM (ví dụ: các phần tử <style><link> 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, hãy lưu ý một số tính năng bị thiếu:

  • Shadow DOM 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: Không hỗ trợ Đơn vị tương đối của vùng chứa trong các khung hình chính của ảnh động trước phiên bản 15.4.
  • 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.
  • Trình bổ trợ này chỉ hoạt động với CSS cùng nguồn và nội tuyến. Không hỗ trợ biểu định kiểu trên nhiều nguồn gốc và biểu định kiểu trong iframe (trừ phi tệp polyfill được tải theo cách thủ công).
  • Vùng chứa layoutstyle yêu cầu hỗ trợ trình duyệt cơ bản:
    • Safari 15.4 trở lên
    • Firefox không hỗ trợ ngăn chứa kiểu tại thời điểm này, nhưng đang làm việc với tính năng này.

Cảnh báo

  • Để tránh ảnh hưởng đến FIDCLS, polyfill không đảm bảo thời điểm bố cục đầu tiên sẽ xuất hiện, ngay cả khi bố cục đó đượ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 màu đó để vẽ đầu tiên.
  • Tạo ResizeObserver Loop Errors. Polyfill ban đầu cũng thực hiện việc này, nhưng bạn cũng nên đưa ra chỉ số. Đ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á 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 việc thay đổi kích thước khối.
  • Đoạn polyfill này được thử nghiệm trong các Thử nghiệm nền tảng web và đạt 70% vượt qua vì một số tính năng nhất định như API JavaScript không được polyfill, và do đó tỷ lệ vượt qua được 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
    • Samsung Internet 15
    • Firefox 78