Giới thiệu
Flexbox mặc định co giãn item theo nội dung và không gian khả dụng. Để cố định chiều rộng một item trong flex container, dùng property flex (shorthand) hoặc width kết hợp flex-shrink: 0.
Cú pháp Flex Shorthand
.item { flex: <flex-grow> <flex-shrink> <flex-basis>; }
/* flex-grow: khả năng lớn lên | flex-shrink: khả năng co lại | flex-basis: kích thước ban đầu */
Ví dụ 1: Item đầu cố định 200px, 2 item còn lại chia đều không gian
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flex Fixed Width Item</title>
<style>
* { box-sizing: border-box; }
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 2rem; background: #fafafa; }
.flexContainer {
display: flex; gap: 16px; max-width: 900px; margin: 0 auto;
background: white; padding: 1rem; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.item { padding: 2rem; border-radius: 8px; color: white; font-weight: 600; text-align: center; }
/* Item 1: CỐ ĐỊNH 200px - không co, không lớn */
.itemFixed {
flex: 0 0 200px; /* grow=0, shrink=0, basis=200px */
background: linear-gradient(135deg, #ff6b6b, #ee5a5a);
}
/* Item 2 & 3: CHIA ĐỀU không gian còn lại */
.itemFlex {
flex: 1; /* grow=1, shrink=1, basis=0% */
background: linear-gradient(135deg, #4ecdc4, #3dbdb5);
}
.itemFlex:nth-child(3) { background: linear-gradient(135deg, #a66cfe, #9055ff); }
.label { font-size: 0.85rem; opacity: 0.9; margin-top: 0.5rem; }
</style>
</head>
<body>
<h2 style="margin-bottom:1.5rem; color:#2c3e50; text-align:center;">Flex Fixed Width Demo</h2>
<p style="text-align:center; color:#666; margin-bottom:2rem;">Resize cửa sổ: Item đỏ luôn 200px, 2 item xanh/tím chia đều phần còn lại</p>
<div class="flexContainer">
<div class="item itemFixed">Fixed 200px<div class="label">flex: 0 0 200px</div></div>
<div class="item itemFlex">Flex 1<div class="label">flex: 1</div></div>
<div class="item itemFlex">Flex 1<div class="label">flex: 1</div></div>
</div>
</body>
</html>
Giải thích các giá trị flex
| Giá trị | flex-grow | flex-shrink | flex-basis | Hành vi |
|---|---|---|---|---|
flex: 0 0 200px | 0 | 0 | 200px | Cố định - không co, không lớn |
flex: 1 | 1 | 1 | 0% | Chia đều không gian thừa |
flex: auto | 1 | 1 | auto | Dựa trên width/content, sau đó chia thừa |
flex: initial | 0 | 1 | auto | Mặc định - co lại nhưng không lớn |
flex: none | 0 | 0 | auto | Cố định theo content/width |
Ví dụ 2: Mixed Fixed + Auto + Content-based
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flex Mixed Widths</title>
<style>
* { box-sizing: border-box; }
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 2rem; background: #fafafa; }
.demoRow {
display: flex; gap: 12px; margin-bottom: 1.5rem;
border-radius: 8px; overflow: hidden; background: #f0f0f0; padding: 8px;
}
.demoRow > div { padding: 1rem; border-radius: 6px; font-weight: 600; color: white; }
/* Case 1: Auto resize (fill remaining) */
.d1 { flex: auto; background: #ff6b6b; } /* Dựa trên content, sau đó fill */
/* Case 2: Fixed 66px */
.d2 { width: 66px; flex-shrink: 0; background: #4ecdc4; } /* width + flex-shrink:0 = fixed */
/* Case 3: Content-based (no grow/shrink) */
.d3 { flex: none; background: #a66cfe; } /* Chỉ bằng content, không co/lớn */
/* Case 4: Fixed height demo */
.d4 { height: 100px; background: #e74c3c; } /* Chỉ demo height */
/* Responsive: Stack on mobile */
@media (max-width: 600px) {
.demoRow { flex-direction: column; }
.d2 { width: 100%; }
}
</style>
</head>
<body>
<h2 style="margin-bottom:1.5rem; color:#2c3e50; text-align:center;">Flex Width Patterns</h2>
<div class="demoRow">
<div class="d1">Auto Resize (flex: auto)</div>
<div class="d2">66px Fixed</div>
<div class="d3">Content Only (flex: none)</div>
</div>
<div class="demoRow">
<div class="d4">Fixed Height 100px</div>
</div>
</body>
</html>
Các pattern thường gặp
1. Sidebar cố định + Content fluid
.layout { display: flex; }
.sidebar { flex: 0 0 280px; } /* Fixed 280px */
.content { flex: 1; min-width: 0; } /* min-width:0 quan trọng cho text overflow */
2. Navbar: Logo fixed, Menu flex, User avatar fixed
.navbar { display: flex; align-items: center; gap: 1rem; }
.logo { flex: 0 0 auto; } /* Fit content */
.menu { flex: 1; } /* Fill space */
.avatar { flex: 0 0 40px; } /* Fixed 40px */
3. Card: Image fixed width, Content flex
.card { display: flex; gap: 1rem; }
.cardImage { flex: 0 0 120px; } /* Fixed thumbnail */
.cardContent { flex: 1; min-width: 0; }
Lưu ý quan trọng
- flex-shrink: 0 là chìa khóa để cố định width - ngăn item co nhỏ hơn basis.
- min-width: 0 trên item
flex: 1chứa text dài - cho phép text truncate/ellipsis hoạt động. - Kết hợp
gapthay vì margin cho spacing nhất quán. - Tránh dùng
widthđơn lẻ trên flex item - dùngflex-basis(thành phần thứ 3 của flex shorthand).