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

Cách tạo Zig Zag Layout (Bố cục xen kẽ) Responsive với CSS

Giới thiệu

Zig Zag Layout (Alternating Layout) là mẫu thiết kế phổ biến cho trang "Features", "About", "Services": hình ảnh bên trái - nội dung bên phải, rồi lần sau ngược lại. Tạo nhịp điệu thị giác, tránh đơn điệu.

Ví dụ hiện đại: CSS Grid + Flexbox (Khuyến nghị)

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Responsive Zig Zag Layout</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.7; background: #fafafa; }
        
        .zigzagSection { padding: 4rem 2rem; }
        .container { max-width: 1100px; margin: 0 auto; }
        .sectionTitle { text-align: center; font-size: 2.5rem; color: #6a1b9a; margin-bottom: 3rem; }
        
        /* ZigZag Item - Grid Layout */
        .zigzagItem {
            display: grid;
            grid-template-columns: 1fr;
            gap: 2rem;
            align-items: center;
            margin-bottom: 4rem;
        }
        .zigzagItem:last-child { margin-bottom: 0; }
        
        /* Reverse order cho item chẵn (2, 4, 6...) trên desktop */
        @media (min-width: 768px) {
            .zigzagItem {
                grid-template-columns: 1fr 1fr;
            }
            .zigzagItem:nth-child(even) .zigzagContent {
                order: 1;  /* Nội dung sang trái */
            }
            .zigzagItem:nth-child(even) .zigzagImage {
                order: 2;  /* Hình sang phải */
            }
        }
        
        .zigzagContent { padding: 1rem; }
        .zigzagContent h2 { font-size: 2rem; color: #2c3e50; margin-bottom: 1rem; line-height: 1.3; }
        .zigzagContent p { font-size: 1.1rem; color: #555; margin-bottom: 1.5rem; }
        .btn {
            display: inline-block; padding: 0.8rem 2rem;
            background: linear-gradient(135deg, #6a1b9a, #8e24aa);
            color: white; text-decoration: none; border-radius: 50px;
            font-weight: 600; transition: transform 0.2s, box-shadow 0.2s;
        }
        .btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(106, 27, 154, 0.4); }
        
        .zigzagImage img {
            width: 100%; height: auto; border-radius: 12px;
            box-shadow: 0 12px 32px rgba(0,0,0,0.15);
            object-fit: cover; aspect-ratio: 4/3;
        }
    </style>
</head>
<body>
    <section class="zigzagSection">
        <div class="container">
            <h1 class="sectionTitle">Responsive Zig Zag Layout</h1>
            
            <!-- Item 1: Image Left, Content Right -->
            <div class="zigzagItem">
                <div class="zigzagImage">
                    <img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&h=450&fit=crop" alt="A Gypsy">
                </div>
                <div class="zigzagContent">
                    <h2>Một người Du mục</h2>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia tempore expedita sequi consequuntur rerum quasi voluptate deleniti iure quae magni qui, laudantium illo dolorum temporibus, dolor labore, quos eos. Dolores?</p>
                    <a href="#" class="btn">Tìm hiểu thêm</a>
                </div>
            </div>
            
            <!-- Item 2: Content Left, Image Right (Reversed) -->
            <div class="zigzagItem">
                <div class="zigzagImage">
                    <img src="https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=600&h=450&fit=crop" alt="A cruise ship">
                </div>
                <div class="zigzagContent">
                    <h2>Du thuyền sang trọng</h2>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia tempore expedita sequi consequuntur rerum quasi voluptate deleniti iure quae magni qui, laudantium illo dolorum temporibus, dolor labore, quos eos. Dolores?</p>
                    <a href="#" class="btn">Khám phá</a>
                </div>
            </div>
            
            <!-- Item 3: Image Left, Content Right -->
            <div class="zigzagItem">
                <div class="zigzagImage">
                    <img src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=600&h=450&fit=crop" alt="Nature view">
                </div>
                <div class="zigzagContent">
                    <h2>Cảm nhận Thiên nhiên</h2>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia tempore expedita sequi consequuntur rerum quasi voluptate deleniti iure quae magni qui, laudantium illo dolorum temporibus, dolor labore, quos eos. Dolores?</p>
                    <a href="#" class="btn">Xem thêm</a>
                </div>
            </div>
        </div>
    </section>
</body>
</html>

Giải thích kỹ thuật cốt lõi

  1. Mobile First: Mặc định 1 cột (grid-template-columns: 1fr), hình ảnh trên, nội dung dưới.
  2. Desktop (≥768px): 2 cột bằng nhau (1fr 1fr).
  3. Xen kẽ thứ tự: nth-child(even) + order property đảo vị trí cột cho item chẵn.
  4. align-items: center: Căn giữa dọc nội dung so với hình ảnh.
  5. Gap: Khoảng cách giữa 2 cột tự động responsive.

So sánh với cách cũ (Float)

Code gốc dùng float: left, width: 66.66%/33.33%, clearfix hack. Cách Grid:

  • Code ngắn gọn 60%.
  • Không cần clearfix, không lo collapsing parent.
  • Dễ dàng đảo thứ tự cột bằng order thay vì viết HTML trùng lặp.
  • Căn giữa dọc tự động với align-items.

Biến thể: Zig Zag với hình ảnh full chiều rộng (Background Image)

.zigzagItem {
    display: grid;
    grid-template-columns: 1fr;
}
@media (min-width: 768px) {
    .zigzagItem { grid-template-columns: 1fr 1fr; }
    .zigzagItem:nth-child(even) { direction: rtl; } /* Đảo toàn bộ row */
    .zigzagItem > * { direction: ltr; } /* Reset direction cho content */
}
.zigzagImage {
    background-size: cover; background-position: center;
    min-height: 400px; border-radius: 12px;
}

Cách này dùng direction: rtl trên parent để đảo toàn bộ row - rất "hack" nhưng hiệu quả cho layout phức tạp.

Accessibility & SEO

  • Luôn có alt mô tả cho hình ảnh.
  • Thứ tự DOM: Hình ảnh trước, nội dung sau (mobile) - screen reader đọc hợp lý.
  • Dùng <section>, <article>, heading hierarchy đúng (h1 → h2).