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. Để 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 Vùng chứa 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ề 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 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 dựa trên thành phần thực sự bằng cách truy vấn kích thước của phần tử mẹ. Đây là thông tin chi tiết và hữu ích hơn nhiều so với những truy vấn phương tiện chỉ cung cấp thông tin kích thước về 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í chúng nằm trên 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 cách 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 để thiết lập các kiểu dựa trên mẫu 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 đó, viết lại mã trước đó như:

@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 hiển thị 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 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 (chẳng hạn như vh, vb, vwvi) có thể được 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ẽ làm cho kích thước phông chữ bằng 15% kích thước nội tuyến của vùng chứa, nghĩa là kích thước này sẽ lớn hơn khi kích thước nội tuyến (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() để 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 thích ứng 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 để giảm phạm vi kích thước, như hiển thị trong chế độ xem 2 cột.

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 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. Polyfill này 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 có kích thước dưới 9kb khi được nén và sử dụng ResizeObserver cùng 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 đ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 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ệ thống hỗ trợ việc lồng các quy tắc @container trong các 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.
  • Việc lọc chính xác các truy vấn dựa trên tính năng (ví dụ: việc truy vấn height trên container: inline-size không được cho phép một cách chính xác với chế độ viết theo chiều ngang).
  • Đột biến 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 đang sử dụng đoạn mã polyfill truy vấn vùng chứa, bạn cần chú ý một số tính năng sau:

  • DOM bóng 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 ả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.
  • Tính năng polyfill này chỉ hoạt động với CSS cùng dòng và cùng nguồn gốc. 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

  • Để ngăn ảnh hưởng đến FIDCLS, polyfill không đảm bảo về thời điểm bố cục đầu tiên sẽ diễn ra, ngay cả khi bố cục được tải đồng bộ, ngoại trừ việc bố cục 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 gốc 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
    • Cạnh 88
    • Samsung Internet 15
    • Firefox 78