Giới thiệu
Mixed Column Layout cho phép số cột thay đổi tại nhiều breakpoint: 4 cột desktop → 2 cột tablet → 1 cột mobile. Khác với auto-fit tự động, cách này kiểm soát chính xác breakpoint.
Ví dụ: Grid với 3 Breakpoints kiểm soát rõ ràng
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mixed Column Layout Grid</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; background: #f5f5f5; padding: 2rem; }
.colContainer {
max-width: 1200px; margin: 0 auto;
display: grid;
grid-template-columns: repeat(4, 1fr); /* Default: 4 cột */
gap: 20px;
}
.col {
background: white;
border-radius: 12px;
padding: 2rem;
text-align: center;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s;
}
.col:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0,0,0,0.12); }
.col h3 { color: #2c3e50; margin-bottom: 0.5rem; }
.col p { color: #666; font-size: 0.95rem; }
/* Màu gradient cho từng col */
.col:nth-child(1) { border-top: 4px solid #991dd0; }
.col:nth-child(2) { border-top: 4px solid #0c7e78; }
.col:nth-child(3) { border-top: 4px solid #cf295b; }
.col:nth-child(4) { border-top: 4px solid #cc5b27; }
/* Breakpoint 1: Tablet landscape / Small laptop ≤ 900px → 2 cột */
@media (max-width: 900px) {
.colContainer { grid-template-columns: repeat(2, 1fr); }
}
/* Breakpoint 2: Mobile ≤ 600px → 1 cột */
@media (max-width: 600px) {
.colContainer { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<h1 style="text-align:center; margin-bottom:0.5rem; color:#2c3e50;">Mixed Column Layout Grid</h1>
<p style="text-align:center; color:#666; margin-bottom:2rem;">Resize màn hình: 4 cột → 2 cột (≤900px) → 1 cột (≤600px)</p>
<div class="colContainer">
<div class="col"><h3>Cột 1</h3><p>Nội dung cột đầu tiên. Responsive grid layout.</p></div>
<div class="col"><h3>Cột 2</h3><p>Nội dung cột thứ hai. Tự động xếp lại khi resize.</p></div>
<div class="col"><h3>Cột 3</h3><p>Nội dung cột thứ ba. Grid template columns thay đổi.</p></div>
<div class="col"><h3>Cột 4</h3><p>Nội dung cột thứ tư. Không cần float/clearfix.</p></div>
</div>
</body>
</html>
So sánh 2 cách tiếp cận
Cách 1: Explicit Breakpoints (Ví dụ trên - Kiểm soát chính xác)
- Ưu: Kiểm soát chính xác lúc nào chuyển cột, phù hợp design system có breakpoint cố định.
- Nhược: Cần viết media query, ít linh hoạt với container width (chỉ dựa trên viewport).
Cách 2: Intrinsic Layout với auto-fit/minmax (Tự động - Xem bài 1003063625)
- Ưu: 0 media query, tự thích ứng với container width (hỗ trợ Container Queries tương lai).
- Nhược: Breakpoint phụ thuộc vào minmax value, khó khớp chính xác design spec.
Khi nào dùng cách nào?
- Explicit breakpoints: Design system chặt chẽ, designer yêu cầu breakpoint chính xác (VD: 4 cột ở 1200px, 2 cột ở 768px).
- Auto-fit/minmax: Component-based design, card grid, gallery, dashboard widget - nơi container width thay đổi không theo viewport.
Mở rộng: Asymmetric Grid (Cột không đều)
.asymmetricGrid {
display: grid;
grid-template-columns: 2fr 1fr 1fr; /* Cột 1 gấp 2 lần cột 2,3 */
gap: 20px;
}
@media (max-width: 900px) {
.asymmetricGrid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 600px) {
.asymmetricGrid { grid-template-columns: 1fr; }
}
Ứng dụng: Sidebar (2fr) + 2 widget nhỏ (1fr 1fr), hoặc Featured article lớn + 2 bài viết nhỏ.
Container Queries (Tương lai gần)
Thay vì @media (viewport), dùng @container (container width):
.colContainer { container-type: inline-size; }
@container (max-width: 600px) { .colContainer { grid-template-columns: 1fr; } }
@container (min-width: 601px) and (max-width: 900px) { .colContainer { grid-template-columns: repeat(2, 1fr); } }
@container (min-width: 901px) { .colContainer { grid-template-columns: repeat(4, 1fr); } }
Hỗ trợ: Chrome 105+, Firefox 110+, Safari 16+, Edge 105+. Đây là xu hướng cho Design System component-based.