Learn CSS Flexible Box Layout (Flexbox) in-depth, including axes, space distribution math (grow, shrink, basis), and alignment properties.
This lesson is currently only available in Vietnamese. Please switch the language toggle in the menu to Vietnamese to read the full guide and take the interactive quiz.
Trước khi CSS Flexible Box Layout (Flexbox) ra đời, dàn trang một chiều dọc hoặc ngang trên web là một
cơn ác mộng của lập trình viên. Chúng ta phải lạm dụng float,
display: inline-block hoặc các bảng HTML Table để căn chỉnh phần tử.
Flexbox ra đời như một mô hình bố cục hiện đại giúp tự động điều chỉnh kích thước phần tử để lấp đầy không gian chứa trống một cách thông minh, bất kể kích thước màn hình hiển thị.
1. Trục chính (Main Axis) & Trục phụ (Cross Axis)
Điểm mấu chốt để hiểu Flexbox là hệ tọa độ hai trục vuông góc:
-
Main Axis (Trục chính): Trục dọc theo đó các phần tử con được sắp xếp. Hướng của
trục được xác định bởi thuộc tính
flex-direction:row(mặc định): Trục chính chạy nằm ngang từ trái sang phải.column: Trục chính chạy thẳng đứng từ trên xuống dưới.
- Cross Axis (Trục phụ): Trục vuông góc với trục chính. Hướng của trục phụ phụ thuộc hoàn toàn vào trục chính. Nếu trục chính là trục ngang, trục phụ sẽ là trục dọc và ngược lại.
direction (như RTL của tiếng Ả Rập) và writing-mode. Flexbox
hoạt động dựa trên các khái niệm trừu tượng: main-start, main-end,
cross-start, và cross-end.
2. Sức mạnh tự co giãn: flex-grow, flex-shrink và flex-basis
Đây là ba thuộc tính áp dụng cho phần tử con (Flex Items) quyết định thuật toán phân bổ không gian của trình duyệt.
2.1 flex-basis (Kích thước gốc)
Độ rộng ban đầu của phần tử trước khi trình duyệt thực hiện phân chia không gian thừa hoặc co cụm. Có
thể đặt theo pixel, phần trăm, hoặc dùng auto (mặc định - kích thước dựa theo nội dung
của phần tử).
2.2 flex-grow (Hệ số giãn)
Khi tổng kích thước flex-basis của các con nhỏ hơn kích thước của
container cha, chúng ta sẽ có không gian thừa (Remaining Space): $$\text{Remaining
Space} = \text{Container Width} - \sum_{i} \text{flex-basis}_i$$ Các phần tử con có hệ số
flex-grow > 0 sẽ chia nhau không gian thừa này theo tỷ lệ: $$\text{Allocated Space}_i
= \text{Remaining Space} \times \frac{\text{flex-grow}_i}{\sum \text{flex-grow}}$$
.container {
display: flex;
width: 600px;
}
.item-1 {
flex-basis: 100px;
flex-grow: 1; /* Sẽ nhận 1/3 không gian thừa */
}
.item-2 {
flex-basis: 200px;
flex-grow: 2; /* Sẽ nhận 2/3 không gian thừa */
}
/* Tổng flex-basis = 300px. Không gian thừa = 600 - 300 = 300px.
Item 1 nhận thêm: 300 * 1/3 = 100px -> Kích thước thực tế = 200px.
Item 2 nhận thêm: 300 * 2/3 = 200px -> Kích thước thực tế = 400px. */
2.3 flex-shrink (Hệ số co)
Khi tổng kích thước flex-basis vượt quá kích thước container cha, chúng
ta có không gian tràn (Overflow Space). Các con sẽ bị bóp nhỏ lại để vừa khít cha
theo hệ số flex-shrink.
Sân chơi tương tác: Flexbox Sandbox
Hãy trực tiếp điều chỉnh các thuộc tính của Flex Container và Flex Items bên dưới để xem trực quan thuật toán co giãn và căn lề hoạt động trong thời gian thực:
Container Controls
Item Configurator
<div class="container">
<div class="item item-1">Item 1</div>
<div class="item item-2">Item 2</div>
<div class="item item-3">Item 3</div>
</div>
3. Căn chỉnh và giãn cách: justify-content, align-items & gap
Một trong những ưu điểm lớn nhất của Flexbox là khả năng căn lề tự động mà không cần tính toán thủ công:
-
justify-content: Căn chỉnh các phần tử dọc theo
trục chính (Main Axis). Gồm các giá trị:
flex-start,flex-end,center,space-between(giãn cách đều, đẩy lề sát biên),space-around(khoảng cách biên bằng 1/2 khoảng cách giữa các phần tử), vàspace-evenly(mọi khoảng cách bằng nhau). -
align-items: Căn chỉnh các phần tử dọc theo
trục phụ (Cross Axis) cho toàn bộ container. Mặc định là
stretch(tự động co kéo dài toàn phần để lấp đầy chiều cao dòng chứa). -
align-self: Cho phép đè lên thuộc tính
align-itemschung tại riêng một phần tử con đặc thù. - gap: Thuộc tính cực kỳ hữu dụng để gán khoảng cách trống chính xác giữa các phần tử con mà không làm hỏng viền lề ngoài như khi sử dụng margin.
justify-self không tồn tại và không có hiệu
lực. Bạn chỉ có thể dùng align-self ở trục phụ. Ở trục chính, nếu muốn đẩy riêng một
phần tử về một phía, hãy dùng kỹ thuật margin-left: auto hoặc
margin-right: auto.
Trắc nghiệm ôn tập
Câu 1: Thuộc tính "justify-content" dùng để căn chỉnh các phần tử con dọc theo trục nào?
Trắc nghiệm ôn tập
Câu 2: Nếu có 3 phần tử con có flex-grow lần lượt là 0, 1, và 2. Trình duyệt chia không gian thừa như thế nào?