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 truy vấn vùng chứa đã có tại đây!

Tin vui dành cho bạn! Một trong những tính năng được nhà phát triển yêu cầu nhiều nhất đã bắt đầu ra mắt trong 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 container Query Polyfill để 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. Điều này giúp các thành phần này linh hoạt và thích ứng 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;
  }
}

Để rõ ràng và gọn gà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

Để truy vấn vùng chứa trở nên 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ịtương ứng 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ị lớn hơn của cqi hoặc cqb

Một ví dụ về cách bạn sử dụng các đơn vị dựa trên vùng chứa là kiểu chữ thích ứng. Bạn có thể sử dụng các đơn vị dựa trên khung nhìn (chẳng hạn như vh, vb, vwvi) để định 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. Để làm được điều này, 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ữ, đồng thời điều chỉnh kích thước kiểu chữ theo 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 nội tuyến của vùng chứa ở bất kỳ vị trí 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.

Polyfill truy vấn vùng chứa

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ể thoải mái kết hợp tính năng này vào dự án của mình và biết rằng tính năng hỗ trợ trình duyệt đóng vai trò quan trọng trong đó. Do đó, chúng tôi đã nỗ lực cải thiện Tìm kiếm vùng chứa 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ị chiều 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 có thể sử dụng một dịch vụ để phân phối có điều kiện polyfill dựa trên User-Agent hoặc tự lưu trữ polyfill trên nguồn gốc của riêng bạn.

Để 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 cá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ờ xuất hiện.

Các tính năng mới của Polyfill

Trình bổ trợ đã cập nhật hỗ trợ:

  • 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ẽ được truyền sau khi polyfill tải.
  • Hỗ trợ đầy đủ cú pháp CSS (không còn vấn đề nào khi đặt nhận xét ở bất kỳ vị trí nào hợp lệ về cú pháp).
  • Chế độ viết dọc (thông qua writing-mode).
  • Các đơ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, nội dung 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.
  • Các 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).

Các giới hạn và cảnh báo về tính năng nội dung bổ sung

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:

  • 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ợ các biểu định kiểu trên nhiều nguồn gốc và biểu định kiểu trong iframe (trừ phi polyfill được tải theo cách thủ công).
  • Tính năng chứa layoutstyle yêu cầu trình duyệt cơ bản hỗ trợ:
    • Safari 15.4 trở lên
    • Firefox hiện không hỗ trợ tính năng chứa kiểu, nhưng đang tiến hành tính năng này.

Cảnh báo

  • Để tránh ả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 sẽ cố gắng tránh việc 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 lớp này cho lần vẽ đầu tiên.
  • Tạo ResizeObserver Loop Errors. Trình bổ trợ gốc cũng thực hiện việc này, nhưng bạn nên gọi ra. Đ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.
  • Trình bổ trợ này được kiểm thử theo Kiểm thử nền tảng web và đạt tỷ lệ đạt 70% vì một số tính năng như API JavaScript không được bổ trợ, do đó, tỷ lệ đạt được cố ý gần 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ó các phiên bản trước:
    • Safari 14
    • Chromium 88
    • Edge 88
    • Samsung Internet 15
    • Firefox 78