Discover the View Transitions API for seamless element morphing across DOM updates, and Master CSS Container Queries (@container) to build highly adaptive components that scale according to parent dimensions instead of viewport width.

This lesson is currently only available in Vietnamese. Please switch the language toggle in the menu to Vietnamese to read the full guide and take the interactive quiz.

Lâu nay, tư duy thiết kế giao diện thích ứng (Responsive Design) luôn gắn liền với khái niệm Viewport và Media Queries (@media). Chúng ta thay đổi bố cục dựa trên kích thước của toàn bộ cửa sổ trình duyệt.

Tuy nhiên, trong kiến trúc component hiện đại, một thành phần có thể được tái sử dụng ở nhiều vị trí khác nhau (ví dụ: thẻ sản phẩm nằm trong cột sidebar hẹp hoặc nằm trong vùng nội dung chính rộng). Để giúp các thành phần này tự thích ứng thông minh dựa trên diện tích vùng chứa chúng, CSS giới thiệu Container Queries. Đồng thời, để nâng tầm trải nghiệm tương tác mượt mà, View Transitions API xuất hiện như một công cụ tối tân hỗ trợ chuyển đổi trạng thái phần tử (morphing) vô cùng tự nhiên.

1. Container Queries — Khi Component tự thích ứng

Container Queries cho phép lập trình viên kiểm tra kích thước của thẻ bọc ngoài gần nhất (parent container) để gán style cho con, thay vì truy vấn kích thước toàn bộ màn hình.

Quy trình triển khai Container Queries gồm 2 bước:

Bước 1: Thiết lập không gian chứa (Containment Context)

Gán thuộc tính container-type lên thẻ cha để biến nó thành một vùng chứa được truy vấn:

parent.css
.parent-wrapper {
  /* Định nghĩa vùng chứa truy vấn theo chiều ngang (inline-size) */
  container-type: inline-size;
  container-name: product-grid;
}

Bước 2: Viết truy vấn con với @container

Sử dụng cú pháp @container để thay đổi giao diện thẻ con tùy thuộc độ rộng vùng chứa:

card.css
.product-card {
  display: flex;
  flex-direction: column; /* Mặc định xếp dọc */
}

/* Khi container bọc ngoài rộng từ 500px trở lên */
@container product-grid (min-width: 500px) {
  .product-card {
    flex-direction: row; /* Chuyển sang xếp ngang */
  }
}

2. Đơn vị độ dài Container mới

Container Queries mang tới một hệ thống đơn vị đo lường tương đối mới dựa trên kích thước vùng chứa:

  • cqw: 1% chiều rộng vùng chứa (Container Width).
  • cqh: 1% chiều cao vùng chứa (Container Height).
  • cqi: 1% kích thước inline (chiều ngang trong ngôn ngữ Latinh) của vùng chứa.
  • cqb: 1% kích thước block (chiều dọc) của vùng chứa.

3. View Transitions API — Chuyển cảnh Morphing mượt mà

Khi thay đổi DOM (ví dụ: chuyển từ chế độ danh sách sang xem chi tiết), trải nghiệm người dùng thường bị đột ngột. document.startViewTransition() giúp trình duyệt tự động chụp hai ảnh trạng thái trước/sau của DOM và tạo hoạt ảnh chuyển tiếp phối hợp tự động.

Cách áp dụng trong JavaScript:

transition.js
function updateDOMToDetailState() {
  // Thay đổi nội dung thẻ trong DOM
  document.getElementById('content').innerHTML = `<div class="detail">...</div>`;
}

// Bắt đầu quá trình morphing tự nhiên của trình duyệt
document.startViewTransition(() => {
  updateDOMToDetailState();
});

Để liên kết một phần tử cụ thể (như bức ảnh thu nhỏ mở rộng thành ảnh lớn), ta định nghĩa thuộc tính view-transition-name trên cả hai trạng thái cũ và mới trong CSS:

morph.css
.thumbnail-image {
  view-transition-name: active-card-image;
}
.detail-large-image {
  view-transition-name: active-card-image;
}

Trình duyệt sẽ tự động nội suy kích thước, tỷ lệ và tọa độ từ ảnh nhỏ sang ảnh lớn mà không cần bất kỳ dòng mã JavaScript tính toán tọa độ phức tạp nào.

Sân chơi tương tác: Morphing & Adaptive Lab

Sân chơi dưới đây tích hợp cả 2 kỹ thuật. Bạn có thể chọn tab chức năng điều khiển để kiểm tra cách Container Query tự định hình lại layout theo thanh trượt kéo độ rộng, hoặc nhấn vào thẻ để kích hoạt View Transitions Morphing:

🎨 Sân chơi tương tác: Morphing & Adaptive Lab

Cấu hình Thành phần

PRODUCT IMAGE

Tên sản phẩm thông minh

Thành phần này tự động thay đổi layout từ dạng cột sang dạng hàng ngang khi chiều rộng bọc ngoài lớn hơn 500px.

adaptive.html
<!-- 1. Cấu trúc Container Queries -->
<div class="resizable-container">
  <div class="product-card">
    <div class="image"></div>
    <div class="info"></div>
  </div>
</div>

<!-- 2. Cấu trúc View Transitions -->
<div class="card" onclick="openDetail()">
  <div class="thumb"></div>
</div>
adaptive.css

Trắc nghiệm ôn tập

Câu 1: Lớp giả lập phần tử nào được sử dụng để định nghĩa hình ảnh chụp của trạng thái CŨ trong luồng View Transitions API?

Trắc nghiệm ôn tập

Câu 2: Đơn vị độ dài 'cqi' trong CSS Container Queries đại diện cho đại lượng nào?

📖 Tài liệu tham khảo / References

Related Articles

Bài viết liên quan trong series

Lesson 9: CSS Rendering Performance & Accessibility (A11y) Bài 9: Hiệu Năng Render CSS & Khả Năng Truy Cập (Accessibility) Lesson 7: Scroll-Driven Animations — Timeline Control based on Scroll Position Bài 7: Scroll-Driven Animation — Hoạt Ảnh Theo Trục Cuộn Trang Back to CSS Course Overview Quay lại Lộ trình Series CSS