Flexbox là gì?
Flexbox (Flexible Box Layout) là mô hình layout 1 chiều cho phép căn chỉnh, phân phối không gian và sắp xếp các phần tử con dọc theo một trục chính.
.container { display: flex; }
Khi container là flex, các phần tử con trực tiếp trở thành flex items.
Thuộc tính của container (parent)
Hướng và xuống dòng
flex-direction: row | row-reverse | column | column-reverse;
flex-wrap: nowrap | wrap | wrap-reverse;
/* Kết hợp */
flex-flow: row wrap;
Căn chỉnh trên trục chính (justify-content)
Phân phối items theo trục chính (ngang khi flex-direction: row).
| Giá trị | Hành vi |
|---|---|
flex-start |
Căn về đầu (mặc định) |
flex-end |
Căn về cuối |
center |
Căn giữa |
space-between |
Khoảng cách đều giữa items |
space-around |
Khoảng cách đều cả 2 bên |
space-evenly |
Khoảng cách hoàn toàn đều |
Căn chỉnh trên trục phụ (align-items)
Căn chỉnh items theo trục vuông góc với trục chính.
| Giá trị | Hành vi |
|---|---|
stretch |
Kéo giãn lấp đầy (mặc định) |
flex-start |
Căn về đầu trục phụ |
flex-end |
Căn về cuối trục phụ |
center |
Căn giữa trục phụ |
baseline |
Căn theo đường baseline của text |
gap
.container { gap: 16px; } /* row-gap và column-gap */
.container { gap: 10px 20px; } /* row-gap column-gap */
Thuộc tính của item (child)
.item {
flex-grow: 1; /* Hệ số tăng trưởng — chiếm phần không gian dư */
flex-shrink: 1; /* Hệ số thu nhỏ khi thiếu không gian (mặc định 1) */
flex-basis: auto; /* Kích thước ban đầu trước khi grow/shrink */
/* Shorthand: grow shrink basis */
flex: 1 1 auto;
flex: 1; /* 1 1 0 — phổ biến nhất */
flex: none; /* 0 0 auto — không co giãn */
align-self: auto | flex-start | flex-end | center | baseline | stretch;
order: 0; /* Số nhỏ hơn xuất hiện trước (mặc định 0) */
}
Demo: justify-content
<div class="demo-wrap">
<div class="jc-row" id="jc-flex-start">
<span>flex-start</span>
<div class="jc-container jc-flex-start">
<div class="b">A</div><div class="b">B</div><div class="b">C</div>
</div>
</div>
<div class="jc-row">
<span>center</span>
<div class="jc-container jc-center">
<div class="b">A</div><div class="b">B</div><div class="b">C</div>
</div>
</div>
<div class="jc-row">
<span>flex-end</span>
<div class="jc-container jc-flex-end">
<div class="b">A</div><div class="b">B</div><div class="b">C</div>
</div>
</div>
<div class="jc-row">
<span>space-between</span>
<div class="jc-container jc-space-between">
<div class="b">A</div><div class="b">B</div><div class="b">C</div>
</div>
</div>
<div class="jc-row">
<span>space-around</span>
<div class="jc-container jc-space-around">
<div class="b">A</div><div class="b">B</div><div class="b">C</div>
</div>
</div>
<div class="jc-row">
<span>space-evenly</span>
<div class="jc-container jc-space-evenly">
<div class="b">A</div><div class="b">B</div><div class="b">C</div>
</div>
</div>
</div>
body { font-family: sans-serif; padding: 1rem; }
.demo-wrap { display: flex; flex-direction: column; gap: 8px; }
.jc-row { display: flex; align-items: center; gap: 12px; }
.jc-row > span { min-width: 120px; font-size: .8rem; color: #555; text-align: right; }
.jc-container {
display: flex;
flex: 1;
background: #f0f4ff;
border: 1px dashed #4472c4;
border-radius: 4px;
padding: 6px;
min-height: 44px;
}
.b {
background: #4472c4; color: white;
width: 40px; height: 32px;
display: flex; align-items: center; justify-content: center;
border-radius: 4px; font-weight: bold;
}
.jc-flex-start { justify-content: flex-start; }
.jc-center { justify-content: center; }
.jc-flex-end { justify-content: flex-end; }
.jc-space-between { justify-content: space-between; }
.jc-space-around { justify-content: space-around; }
.jc-space-evenly { justify-content: space-evenly; }
Demo: align-items
<div class="demo-wrap">
<div class="ai-row">
<span>stretch</span>
<div class="ai-container ai-stretch">
<div class="b b1">A</div><div class="b b2">B dài hơn</div><div class="b b3">C</div>
</div>
</div>
<div class="ai-row">
<span>flex-start</span>
<div class="ai-container ai-flex-start">
<div class="b b1">A</div><div class="b b2">B dài hơn</div><div class="b b3">C</div>
</div>
</div>
<div class="ai-row">
<span>center</span>
<div class="ai-container ai-center">
<div class="b b1">A</div><div class="b b2">B dài hơn</div><div class="b b3">C</div>
</div>
</div>
<div class="ai-row">
<span>flex-end</span>
<div class="ai-container ai-flex-end">
<div class="b b1">A</div><div class="b b2">B dài hơn</div><div class="b b3">C</div>
</div>
</div>
<div class="ai-row">
<span>baseline</span>
<div class="ai-container ai-baseline">
<div class="b b1" style="font-size:0.8rem">A nhỏ</div>
<div class="b b2" style="font-size:1.4rem">B to</div>
<div class="b b3" style="font-size:1rem">C</div>
</div>
</div>
</div>
body { font-family: sans-serif; padding: 1rem; }
.demo-wrap { display: flex; flex-direction: column; gap: 8px; }
.ai-row { display: flex; align-items: center; gap: 12px; }
.ai-row > span { min-width: 90px; font-size: .8rem; color: #555; text-align: right; }
.ai-container {
display: flex;
flex: 1; height: 70px;
background: #f0f4ff; border: 1px dashed #4472c4;
border-radius: 4px; padding: 4px; gap: 6px;
}
.b {
background: #4472c4; color: white;
padding: 6px 10px; border-radius: 4px; font-weight: bold;
}
.b1 { background: #4472c4; }
.b2 { background: #ed7d31; }
.b3 { background: #70ad47; }
.ai-stretch { align-items: stretch; }
.ai-flex-start { align-items: flex-start; }
.ai-center { align-items: center; }
.ai-flex-end { align-items: flex-end; }
.ai-baseline { align-items: baseline; }
Demo: flex-grow, flex-shrink, flex-basis
<div class="demo-wrap">
<h3>flex-grow: phân chia không gian dư</h3>
<div class="flex-container">
<div class="item grow0">grow:0<br>basis:100px</div>
<div class="item grow1">grow:1<br>basis:100px</div>
<div class="item grow2">grow:2<br>basis:100px</div>
</div>
<h3>flex: 1 (tất cả bằng nhau)</h3>
<div class="flex-container">
<div class="item equal">flex:1</div>
<div class="item equal">flex:1</div>
<div class="item equal">flex:1</div>
</div>
<h3>align-self (ghi đè align-items)</h3>
<div class="flex-container self-demo">
<div class="item self-start">align-self: flex-start</div>
<div class="item self-center">align-self: center</div>
<div class="item self-end">align-self: flex-end</div>
</div>
<h3>order</h3>
<div class="flex-container">
<div class="item order-a">order:3 (A)</div>
<div class="item order-b">order:1 (B)</div>
<div class="item order-c">order:2 (C)</div>
</div>
</div>
body { font-family: sans-serif; padding: 1rem; }
h3 { font-size: .9rem; color: #555; margin: .8rem 0 .3rem; }
.demo-wrap { display: flex; flex-direction: column; gap: 6px; }
.flex-container {
display: flex; gap: 6px;
background: #f0f4ff; border: 1px dashed #4472c4;
padding: 6px; border-radius: 4px;
}
.item {
background: #4472c4; color: white;
padding: 8px 10px; border-radius: 4px;
font-size: .8rem; text-align: center; font-weight: bold;
}
.grow0 { flex: 0 1 100px; background: #aaa; }
.grow1 { flex: 1 1 100px; background: #4472c4; }
.grow2 { flex: 2 1 100px; background: #ed7d31; }
.equal { flex: 1; background: #70ad47; }
.self-demo { height: 80px; align-items: stretch; }
.self-start { align-self: flex-start; background: #4472c4; }
.self-center { align-self: center; background: #ed7d31; }
.self-end { align-self: flex-end; background: #70ad47; }
.order-a { order: 3; background: #c55a11; }
.order-b { order: 1; background: #375623; }
.order-c { order: 2; background: #1f3864; }
Bình luận