- Demo trực quan: đổi đúng thứ tự, Flexbox tự nhiên dễ
- Điều khiển Flexbox
- Khối Flexbox mẫu
- 1. Vì sao nhiều người thấy Flexbox khó?
- 2. Bước 1: xác định trục chính bằng flex-direction
- 3. Bước 2: sắp xếp trên trục chính với justify-content
- 4. Bước 3: canh trên trục phụ với align-items
- 5. Bước 4: khoảng cách và sự linh hoạt (gap, flex-grow, flex-basis)
- 6. Một số pattern Flexbox thực tế thường dùng
- 6.1 Thanh điều hướng với logo trái, menu giữa, nút phải
- 6.2 Hàng card chia đều chiều ngang, xuống dòng đẹp ở màn nhỏ
- 6.3 Căn giữa tuyệt đối theo cả hai chiều
- 7. Mã nguồn rút gọn cho khối demo Flexbox
- 8. Kết luận
Demo trực quan: đổi đúng thứ tự, Flexbox tự nhiên dễ
Khối demo dưới đây cho phép bạn thay đổi flex-direction, justify-content, align-items và gap. Tất cả đều hiển thị ngay lập tức để bạn cảm nhận trực quan cách Flexbox sắp xếp phần tử.
Điều khiển Flexbox
Khối Flexbox mẫu
1. Vì sao nhiều người thấy Flexbox khó?
Flexbox bị gắn mác “khó” chủ yếu vì mọi người thường học sai thứ tự. Thay vì bắt đầu từ bức tranh tổng thể, nhiều người lao vào từng thuộc tính đơn lẻ, thử hết giá trị này tới giá trị khác để xem giao diện thay đổi ra sao. Cách học đó giống như cố gắng lái xe bằng cách bấm ngẫu nhiên các nút, thay vì hiểu vô lăng và chân ga trước.
Thứ tự hợp lý để tiếp cận Flexbox nên là:
- Hiểu khái niệm trục chính (main axis) và trục phụ (cross axis).
- Quyết định trục chính bằng
flex-direction. - Sắp xếp item trên trục chính bằng
justify-content. - Canh item trên trục phụ bằng
align-itemsvàalign-self. - Sau cùng mới tinh chỉnh bằng
gap,flex-grow,flex-basis,margin: auto…
Khi đi đúng thứ tự, bạn gần như không cần nhớ thuộc tính theo kiểu học vẹt. Bạn chỉ cần trả lời câu hỏi: “Mình đang muốn điều khiển theo trục nào?”.
2. Bước 1: xác định trục chính bằng flex-direction
Trục chính là ý tưởng quan trọng nhất trong Flexbox. Bằng flex-direction, bạn quyết định item sẽ xếp theo hàng hay xếp theo cột.
.container {
display: flex;
flex-direction: row; /* hoặc row-reverse, column, column-reverse */
}
row: trục chính là ngang, bắt đầu từ trái sang phải (mặc định trong giao diện tiếng Việt, tiếng Anh).row-reverse: trục chính vẫn ngang nhưng bắt đầu từ phải sang trái.column: trục chính là dọc, các item xếp từ trên xuống dưới.column-reverse: trục chính là dọc, các item xếp từ dưới lên trên.
Khi trục chính đổi, ý nghĩa của các thuộc tính liên quan cũng đổi theo. Vì vậy, luôn chọn trục trước rồi mới chỉnh cách canh, thay vì vừa chỉnh trục vừa chỉnh canh một cách ngẫu nhiên.
3. Bước 2: sắp xếp trên trục chính với justify-content
Sau khi đóng đinh được trục chính, justify-content quyết định các item nằm chỗ nào trên trục đó.
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
flex-start: dồn về đầu trục.center: gom vào giữa trục.flex-end: dồn về cuối trục.space-between: khoảng trống phân bổ giữa các item, hai đầu không có khoảng trống.space-around: mỗi item có khoảng trống hai bên, nhìn như được “bao quanh” bởi khoảng trống.space-evenly: mọi khoảng trống (giữa item và hai đầu) đều bằng nhau.
Nếu container là một hàng ngang, justify-content điều khiển theo chiều ngang. Nếu container là một cột dọc, nó điều khiển theo chiều dọc. Bạn có thể thử ngay trong demo: đổi flex-direction sang column rồi chỉnh justify-content để cảm nhận sự khác biệt.
4. Bước 3: canh trên trục phụ với align-items
Khi trục chính đã được quyết định, trục phụ luôn là trục còn lại. align-items giúp bạn điều khiển vị trí các item trên trục phụ.
.container {
display: flex;
flex-direction: row;
align-items: center;
}
stretch: item giãn ra để lấp đầy trục phụ (giá trị mặc định).flex-start: item bám vào đầu trục phụ.center: item canh giữa trục phụ.flex-end: item bám vào cuối trục phụ.baseline: canh theo đường baseline của text.
Trong các layout có chiều cao khác nhau giữa các item (ví dụ một card có hai dòng text, card còn lại có bốn dòng), align-items quyết định chúng được căn thẳng hàng theo mép nào. Đây là lý do nhiều layout “không thẳng hàng” dù nhìn qua tưởng như giống nhau.
5. Bước 4: khoảng cách và sự linh hoạt (gap, flex-grow, flex-basis)
Sau khi bạn đã kiểm soát được trục chính và trục phụ, bước tiếp theo là tinh chỉnh khoảng cách và độ rộng của từng item.
Cách đơn giản nhất để tạo khoảng cách giữa các item là dùng gap:
.container {
display: flex;
gap: 16px;
}
Trong demo đầu bài, thanh trượt gap chính là ví dụ trực tiếp. So với việc dùng margin từng item, gap rõ ràng, gọn và dễ đọc hơn rất nhiều.
Khi cần item co giãn để chiếm hết không gian, bạn dùng nhóm thuộc tính flex:
.item {
flex: 1 1 0; /* flex-grow flex-shrink flex-basis */
}
flex-grow: mức độ item được phép “nở” khi còn không gian.flex-shrink: mức độ item được phép “co” khi thiếu không gian.flex-basis: kích thước cơ bản trước khi grow/shrink.
Trong nhiều trường hợp, chỉ cần flex: 1 là đủ để các item chia đều không gian còn lại. Phần còn lại chủ yếu là tinh chỉnh.
6. Một số pattern Flexbox thực tế thường dùng
Dưới đây là vài mẫu bố cục hay gặp, đều có thể giải được gọn gàng với Flexbox theo đúng thứ tự đã nêu.
6.1 Thanh điều hướng với logo trái, menu giữa, nút phải
<div class="uk-flex nav-bar">
<div class="nav-logo">Logo</div>
<div class="nav-menu">Menu</div>
<div class="nav-actions">Đăng nhập</div>
</div>
.nav-bar {
display: flex;
align-items: center;
}
.nav-menu {
margin: 0 auto; /* đẩy menu ra giữa, hai bên là logo và actions */
}
Theo đúng trình tự: chọn trục (row), sau đó align-items để canh giữa theo chiều dọc, cuối cùng dùng margin auto để phân bố không gian trên trục chính.
6.2 Hàng card chia đều chiều ngang, xuống dòng đẹp ở màn nhỏ
<div class="uk-card uk-card-default uk-card-body cards-row">
<div class="card-item">Card 1</div>
<div class="card-item">Card 2</div>
<div class="card-item">Card 3</div>
</div>
.cards-row {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card-item {
flex: 1 1 200px; /* rộng tối thiểu 200px, sau đó co giãn */
}
Với cách này, Flexbox đảm nhiệm tốt phần chia hàng, trong khi bạn chỉ cần chỉnh flex-basis để quyết định điểm gãy xuống dòng.
6.3 Căn giữa tuyệt đối theo cả hai chiều
<div class="full-page">
<div class="box">Centered</div>
</div>
.full-page {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Nếu đã quen với trục chính và trục phụ, bạn sẽ thấy pattern này hoàn toàn hợp lý: trục chính canh giữa, trục phụ cũng canh giữa.
7. Mã nguồn rút gọn cho khối demo Flexbox
Nếu bạn muốn tái sử dụng demo trong một bài viết khác hoặc chỉnh sửa lại theo nhu cầu, dưới đây là phiên bản rút gọn nhất của HTML và CSS/JS cốt lõi.
<div class="flex-demo-container">
<div class="flex-demo-item">Item 1</div>
<div class="flex-demo-item">Item 2</div>
<div class="flex-demo-item">Item 3</div>
</div>
.flex-demo-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
gap: 8px;
}
Tất cả phần còn lại trong khối demo chỉ là lớp vỏ: UIkit để trình bày form, một ít JavaScript để gắn sự kiện và cập nhật style, cùng một đoạn mô tả hiện trạng dựa trên các giá trị bạn chọn.
8. Kết luận
Flexbox chỉ khó khi bạn tiếp cận theo kiểu thuộc tính rời rạc. Một khi đã nắm được thứ tự đúng gồm: chọn trục bằng flex-direction, điều khiển trục chính bằng justify-content, điều khiển trục phụ bằng align-items, rồi mới tinh chỉnh bằng gap và flex, mọi thứ sẽ trở nên rất thẳng hàng và dễ đoán. Hãy tận dụng các khối demo có thể tương tác để luyện cảm giác, sau một thời gian ngắn bạn sẽ không còn phải tra lại Flexbox mỗi khi cần xếp bố cục nữa.
Bình luận