Flexbox là công cụ bố cục một chiều (hàng hoặc cột) mạnh và linh hoạt: thanh menu, hàng thẻ, căn chỉnh nút, chia cột co giãn. Bài này giải thích toàn bộ thuộc tính của container và item kèm ví dụ trực quan.
- Hiểu trục chính, trục phụ và hướng
- Dùng justify-content, align-items, gap, flex-wrap
- Điều khiển co giãn bằng flex-grow, flex-shrink, flex-basis
- Dùng order, align-self và các mẫu bố cục thường gặp
- Flex container
- Phần tử có display: flex.
- Flex item
- Con trực tiếp của container.
- Main axis
- Trục chính theo flex-direction (mặc định ngang).
- Cross axis
- Trục vuông góc với trục chính.
Một số khái niệm
| Thuộc tính container | Giá trị | Tác dụng |
|---|---|---|
| flex-direction | row | column | row-reverse | Hướng trục chính |
| flex-wrap | nowrap | wrap | Cho xuống dòng |
| justify-content | flex-start | center | space-between | space-around | space-evenly | Phân bố theo trục chính |
| align-items | stretch | center | flex-start | flex-end | baseline | Căn theo trục phụ |
| align-content | như justify-content | Căn các dòng khi wrap |
| gap | 16px | 10px 20px | Khoảng cách giữa item |
| Thuộc tính item | Ví dụ | Tác dụng |
|---|---|---|
| flex-grow | 1 | Tỉ lệ chiếm phần dư |
| flex-shrink | 0 | Không cho co lại |
| flex-basis | 200px | Kích thước ban đầu |
| flex (viết tắt) | 1 1 200px | 1 | none | grow shrink basis |
| align-self | center | Căn riêng item |
| order | -1 | Đổi thứ tự hiển thị |
justify-content và align-items
<style>
.r { display: flex; gap: 6px; background: #eceff1; padding: 6px; margin-bottom: 6px; height: 54px; border-radius: 6px; }
.r span { background: #2e7d32; color: #fff; padding: 4px 10px; border-radius: 4px; font-size: 12px; }
.r b { font-size: 11px; color: #546e7a; margin-right: auto; align-self: center; }
</style>
<div class="r" style="justify-content:flex-start"><span>1</span><span>2</span><span>3</span></div>
<div class="r" style="justify-content:center;align-items:center"><span>center</span><span>2</span><span>3</span></div>
<div class="r" style="justify-content:space-between;align-items:flex-end"><span>space-between</span><span>2</span><span>3</span></div>
<div class="r" style="justify-content:space-evenly;align-items:stretch"><span>space-evenly</span><span>stretch</span><span>3</span></div>Co giãn: flex-grow, shrink, basis
<style>
.r { display: flex; gap: 6px; margin-bottom: 8px; }
.r div { background: #1565c0; color: #fff; padding: 8px; border-radius: 6px; font-size: 13px; }
.g1 { flex: 1; } .g2 { flex: 2; } .co-dinh { flex: 0 0 120px; background: #e65100 !important; }
</style>
<div class="r"><div class="g1">flex: 1</div><div class="g2">flex: 2 (gấp đôi)</div><div class="g1">flex: 1</div></div>
<div class="r"><div class="co-dinh">0 0 120px</div><div class="g1">flex: 1 lấp phần còn lại</div></div>flex: 1 = 1 1 0%: mọi item chia đều không gian. flex: 0 0 120px: cố định 120px, không co không giãn, rất hợp cho cột sidebar.
Các mẫu bố cục thường gặp
<style>
.nav { display: flex; align-items: center; gap: 16px; padding: 10px 14px; background: #263238; color: #fff; border-radius: 8px; }
.nav .logo { font-weight: 800; } .nav .day { margin-left: auto; } /* đẩy phần còn lại sang phải */
.the-wrap { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.the { flex: 1 1 150px; background: #e8f5e9; border-radius: 8px; padding: 10px; display: flex; flex-direction: column; }
.the .nut { margin-top: auto; align-self: flex-start; background: #2e7d32; color: #fff; padding: 4px 10px; border-radius: 6px; font-size: 12px; }
</style>
<div class="nav"><span class="logo">TỰ HỌC TIN</span><span>Khóa học</span><span>Blog</span><span class="day">Đăng nhập</span></div>
<div class="the-wrap">
<div class="the"><b>HTML</b><p>Ngắn</p><span class="nut">Học</span></div>
<div class="the"><b>CSS</b><p>Mô tả dài hơn một chút để thấy nút vẫn nằm đáy thẻ</p><span class="nut">Học</span></div>
<div class="the"><b>JS</b><p>Ngắn</p><span class="nut">Học</span></div>
</div>margin-left: auto trong flex đẩy phần tử sang hết bên phải; margin-top: auto trong cột đẩy nút xuống đáy thẻ để các thẻ đều nhau. Thu nhỏ khung để thấy flex-wrap tự xuống dòng.
Trò chơi Flexbox Froggy (flexboxfroggy.com) giúp thuộc các thuộc tính chỉ trong 30 phút; Firefox DevTools có công cụ trực quan cho Flexbox rất tốt.
Item flex mặc định min-width: auto nên không co nhỏ hơn nội dung (chuỗi dài, ảnh lớn) gây tràn; thêm min-width: 0 cho item khi cần cắt chữ.
- Dựng thanh menu: logo trái, các mục giữa, nút đăng nhập phải.
- Dựng hàng thẻ khóa học tự xuống dòng, nút luôn ở đáy.
- Bố cục 2 cột: sidebar 260px cố định, nội dung co giãn.
- Làm footer 3 cột trên máy tính, xếp dọc trên điện thoại (flex-direction: column).
- display: flex trên cha; trục chính theo flex-direction.
- justify-content trục chính, align-items trục phụ, gap khoảng cách.
- flex: grow shrink basis điều khiển co giãn.
- margin auto, align-self, order cho căn chỉnh từng item.