Flexbox không khó, khó là do bạn học sai thứ tự

Flexbox sinh ra để đơn giản hóa việc xếp bố cục một chiều (theo hàng hoặc cột). Vấn đề không phải ở Flexbox khó, mà là nhiều người học sai thứ tự: nhảy ngay vào thuộc tính lẻ tẻ như justify-content, align-items mà chưa hiểu trục chính, trục phụ, chưa hình dung container và item đang “ngồi” ở đâu. Bài này sẽ dẫn bạn đi lại Flexbox theo đúng thứ tự, kèm một khối demo tương tác để bạn xoay, kéo, chỉnh là hiểu ngay.

Flexbox không khó, khó là do bạn học sai thứ tự

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-itemsgap. 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

Bắt đầu từ trục chính, sau đó mới tới cách sắp xếp trên trục và trục phụ.

Hiện tại:8px

Gợi ý: hãy đổiflex-directiontrước, sau đó mới chơi vớijustify-contentalign-items. Đó cũng chính là thứ tự nên học khi bắt đầu với Flexbox.

Khối Flexbox mẫu

Đây là một container Flexbox với ba item. Tất cả thay đổi bạn chọn ở phần điều khiển sẽ áp dụng trực tiếp lên khối này.

Item 1
Item 2
Item 3
Trục chính đang là ngang (row), các item bắt đầu từ bên trái, trục phụ là dọc nênalign-itemsđiều khiển theo chiều cao.

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)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-itemsalign-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 gapflex, 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


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...