Tiếng Việt

Khám phá sức mạnh của CSS Container Queries để tạo ra các bố cục đáp ứng và linh hoạt, phản ứng theo kích thước của vùng chứa, cách mạng hóa thiết kế web.

Bố cục CSS Hiện đại: Tìm hiểu Sâu về Container Queries

Trong nhiều năm, media queries đã là nền tảng của thiết kế web đáp ứng. Chúng cho phép chúng ta điều chỉnh bố cục dựa trên kích thước của viewport. Tuy nhiên, media queries hoạt động trên kích thước của cửa sổ trình duyệt, điều này đôi khi có thể dẫn đến những tình huống khó xử, đặc biệt là khi làm việc với các thành phần có thể tái sử dụng. Và đây là lúc Container Queries xuất hiện – một tính năng CSS mang tính đột phá cho phép các thành phần tự điều chỉnh dựa trên kích thước của phần tử chứa nó, chứ không phải toàn bộ viewport.

Container Queries là gì?

Container Queries, được hầu hết các trình duyệt hiện đại hỗ trợ chính thức, cung cấp một cách tiếp cận chi tiết và tập trung vào thành phần hơn cho thiết kế đáp ứng. Chúng cho phép các thành phần riêng lẻ tự điều chỉnh giao diện và hành vi của mình dựa trên kích thước của vùng chứa cha, độc lập với kích thước của viewport. Điều này mang lại sự linh hoạt và khả năng tái sử dụng cao hơn, đặc biệt khi làm việc với các bố cục phức tạp và hệ thống thiết kế.

Hãy tưởng tượng một thành phần thẻ (card component) cần hiển thị khác nhau tùy thuộc vào việc nó được đặt trong một thanh bên hẹp hay một khu vực nội dung chính rộng. Với media queries, bạn sẽ phải dựa vào kích thước viewport và có khả năng phải sao chép các quy tắc CSS. Với container queries, thành phần thẻ có thể tự điều chỉnh một cách thông minh dựa trên không gian có sẵn trong vùng chứa của nó.

Tại sao nên sử dụng Container Queries?

Dưới đây là phân tích các ưu điểm chính của việc sử dụng Container Queries:

Bắt đầu với Container Queries

Sử dụng Container Queries bao gồm một vài bước chính:

  1. Định nghĩa Vùng chứa (Container): Chỉ định một phần tử làm vùng chứa bằng thuộc tính `container-type`. Điều này thiết lập các ranh giới mà trong đó query sẽ hoạt động.
  2. Định nghĩa Truy vấn (Query): Định nghĩa các điều kiện truy vấn bằng quy tắc `@container`. Điều này tương tự như `@media`, nhưng thay vì các thuộc tính viewport, bạn sẽ truy vấn các thuộc tính của vùng chứa.
  3. Áp dụng Style: Áp dụng các style sẽ được áp dụng khi các điều kiện truy vấn được đáp ứng. Các style này sẽ chỉ ảnh hưởng đến các phần tử bên trong vùng chứa.

1. Thiết lập Vùng chứa

Bước đầu tiên là xác định phần tử nào sẽ đóng vai trò là vùng chứa. Bạn có thể sử dụng thuộc tính `container-type` cho việc này. Có một số giá trị khả dụng:

Đây là một ví dụ:


.card-container {
  container-type: inline-size;
}

Trong ví dụ này, phần tử `.card-container` được chỉ định là một vùng chứa theo dõi kích thước inline của nó (chiều rộng).

2. Định nghĩa Truy vấn Vùng chứa

Tiếp theo, bạn sẽ định nghĩa chính query bằng cách sử dụng quy tắc `@container`. Đây là nơi bạn chỉ định các điều kiện phải được đáp ứng để các style bên trong query được áp dụng.

Dưới đây là một ví dụ đơn giản kiểm tra xem vùng chứa có chiều rộng ít nhất là 500 pixel hay không:


@container (min-width: 500px) {
  .card {
    flex-direction: row; /* Thay đổi bố cục thẻ */
  }
}

Trong ví dụ này, nếu phần tử `.card-container` rộng ít nhất 500 pixel, `flex-direction` của phần tử `.card` sẽ được đặt thành `row`.

Bạn cũng có thể sử dụng `max-width`, `min-height`, `max-height`, và thậm chí kết hợp nhiều điều kiện bằng các toán tử logic như `and` và `or`.


@container (min-width: 300px) and (max-width: 700px) {
  .card-title {
    font-size: 1.2em;
  }
}

Ví dụ này chỉ áp dụng các style khi chiều rộng của vùng chứa nằm trong khoảng từ 300px đến 700px.

3. Áp dụng Style

Bên trong quy tắc `@container`, bạn có thể áp dụng bất kỳ style CSS nào bạn muốn cho các phần tử bên trong vùng chứa. Các style này sẽ chỉ được áp dụng khi các điều kiện query được đáp ứng.

Dưới đây là một ví dụ hoàn chỉnh kết hợp tất cả các bước:


<div class="card-container">
  <div class="card">
    <h2 class="card-title">Product Title</h2>
    <p class="card-description">A brief description of the product.</p>
    <a href="#" class="card-button">Learn More</a>
  </div>
</div>

.card-container {
  container-type: inline-size;
  border: 1px solid #ccc;
  padding: 1em;
}

.card {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.card-title {
  font-size: 1.5em;
  margin-bottom: 0.5em;
}

.card-button {
  background-color: #007bff;
  color: white;
  padding: 0.5em 1em;
  text-decoration: none;
  border-radius: 5px;
}

@container (min-width: 500px) {
  .card {
    flex-direction: row;
    align-items: flex-start;
  }

  .card-title {
    font-size: 1.8em;
  }
}

Trong ví dụ này, khi `.card-container` rộng ít nhất 500 pixel, phần tử `.card` sẽ chuyển sang bố cục ngang và `.card-title` sẽ tăng kích thước.

Tên Vùng chứa

Bạn có thể đặt tên cho vùng chứa bằng `container-name: my-card;`. Điều này cho phép bạn cụ thể hơn trong các truy vấn của mình, đặc biệt nếu bạn có các vùng chứa lồng nhau.

.card-container {
  container-type: inline-size;
  container-name: my-card;
}

@container my-card (min-width: 500px) {
  /* Các style được áp dụng khi vùng chứa có tên "my-card" rộng ít nhất 500px */
}

Điều này đặc biệt hữu ích khi bạn có nhiều vùng chứa trên một trang và bạn muốn nhắm mục tiêu một vùng chứa cụ thể bằng các truy vấn của mình.

Các đơn vị của Container Query

Giống như media queries, container queries có các đơn vị riêng của chúng, tương đối so với vùng chứa. Chúng bao gồm:

Các đơn vị này hữu ích để xác định kích thước và khoảng cách tương đối so với vùng chứa, giúp tăng cường sự linh hoạt của bố cục của bạn.


.element {
  width: 50cqw;
  font-size: 2cqmin;
}

Ví dụ thực tế và các trường hợp sử dụng

Dưới đây là một số ví dụ thực tế về cách bạn có thể sử dụng Container Queries để tạo ra các thành phần có khả năng thích ứng và tái sử dụng tốt hơn:

1. Menu điều hướng đáp ứng

Một menu điều hướng có thể điều chỉnh bố cục của nó dựa trên không gian có sẵn trong vùng chứa của nó. Trong một vùng chứa hẹp, nó có thể thu gọn thành một menu hamburger, trong khi ở một vùng chứa rộng hơn, nó có thể hiển thị tất cả các mục menu theo chiều ngang.

2. Danh sách sản phẩm thích ứng

Một danh sách sản phẩm thương mại điện tử có thể điều chỉnh số lượng sản phẩm được hiển thị trên mỗi hàng dựa trên chiều rộng của vùng chứa của nó. Trong một vùng chứa rộng hơn, nó có thể hiển thị nhiều sản phẩm hơn trên mỗi hàng, trong khi ở một vùng chứa hẹp hơn, nó có thể hiển thị ít sản phẩm hơn để tránh quá đông đúc.

3. Thẻ bài viết linh hoạt

Một thẻ bài viết có thể thay đổi bố cục của nó dựa trên không gian có sẵn. Trong một thanh bên, nó có thể hiển thị một hình ảnh thu nhỏ và một mô tả ngắn, trong khi ở khu vực nội dung chính, nó có thể hiển thị một hình ảnh lớn hơn và một bản tóm tắt chi tiết hơn.

4. Các yếu tố biểu mẫu động

Các yếu tố biểu mẫu có thể điều chỉnh kích thước và bố cục của chúng dựa trên vùng chứa. Ví dụ, một thanh tìm kiếm có thể rộng hơn ở phần đầu trang của một trang web và hẹp hơn ở một thanh bên.

5. Widget trên bảng điều khiển

Các widget trên bảng điều khiển có thể điều chỉnh nội dung và cách trình bày của chúng dựa trên kích thước của vùng chứa. Một widget biểu đồ có thể hiển thị nhiều điểm dữ liệu hơn trong một vùng chứa lớn hơn và ít điểm dữ liệu hơn trong một vùng chứa nhỏ hơn.

Các lưu ý toàn cục

Khi sử dụng Container Queries, điều quan trọng là phải xem xét các tác động toàn cục của các lựa chọn thiết kế của bạn.

Hỗ trợ trình duyệt và Polyfill

Container Queries được hỗ trợ tốt trên các trình duyệt hiện đại, bao gồm Chrome, Firefox, Safari và Edge. Tuy nhiên, nếu bạn cần hỗ trợ các trình duyệt cũ hơn, bạn có thể sử dụng một polyfill như @container-style/container-query. Polyfill này bổ sung hỗ trợ cho container queries vào các trình duyệt không hỗ trợ chúng một cách tự nhiên.

Trước khi sử dụng Container Queries trong môi trường sản xuất, luôn là một ý tưởng tốt để kiểm tra hỗ trợ trình duyệt hiện tại và xem xét việc sử dụng một polyfill nếu cần thiết.

Các thực hành tốt nhất

Dưới đây là một số thực hành tốt nhất cần ghi nhớ khi làm việc với Container Queries:

So sánh Container Queries và Media Queries

Mặc dù cả Container Queries và Media Queries đều được sử dụng cho thiết kế đáp ứng, chúng hoạt động dựa trên các nguyên tắc khác nhau và phù hợp nhất cho các kịch bản khác nhau.

Tính năng Container Queries Media Queries
Mục tiêu Kích thước vùng chứa Kích thước viewport
Phạm vi Cấp độ thành phần Toàn cục
Khả năng tái sử dụng Cao Thấp hơn
Độ ưu tiên Cụ thể hơn Ít cụ thể hơn
Trường hợp sử dụng Điều chỉnh các thành phần riêng lẻ theo ngữ cảnh của chúng Điều chỉnh bố cục tổng thể theo các kích thước màn hình khác nhau

Nói chung, Container Queries phù hợp hơn để điều chỉnh các thành phần riêng lẻ theo ngữ cảnh của chúng, trong khi Media Queries phù hợp hơn để điều chỉnh bố cục tổng thể theo các kích thước màn hình khác nhau. Bạn thậm chí có thể kết hợp cả hai để có các bố cục phức tạp hơn.

Tương lai của Bố cục CSS

Container Queries đại diện cho một bước tiến quan trọng trong sự phát triển của bố cục CSS. Bằng cách cho phép các thành phần tự điều chỉnh dựa trên vùng chứa của chúng, chúng cho phép mã linh hoạt hơn, có thể tái sử dụng và dễ bảo trì hơn. Khi hỗ trợ của trình duyệt tiếp tục được cải thiện, Container Queries sẵn sàng trở thành một công cụ thiết yếu cho các nhà phát triển front-end.

Kết luận

Container Queries là một sự bổ sung mạnh mẽ cho hệ sinh thái CSS, cung cấp một cách tiếp cận tập trung vào thành phần hơn cho thiết kế đáp ứng. Bằng cách hiểu cách chúng hoạt động và cách sử dụng chúng một cách hiệu quả, bạn có thể tạo ra các ứng dụng web có khả năng thích ứng, tái sử dụng và dễ bảo trì hơn. Hãy nắm bắt Container Queries và mở khóa một cấp độ linh hoạt mới trong các bố cục CSS của bạn!