Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> CSS

Cách tạo Mixed Column Layout Grid (Lưới cột hỗn hợp) với CSS

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.