Nội dung bài viết
Sau khi hoàn thành bài trước về các thuộc tính align, justify-content và order. Hôm nay mình sẽ giới thiệu nốt cho các bạn các thuộc tính còn lại của flexbox. Là những thuộc tính quan trọng và khó hiểu cho nên bài này khá dài nhưng mình khuyến khích các bạn nên đọc hết để hiểu rõ và áp dụng chúng 1 cách hiệu quả nha.
# Flex-basis
Set chiều rộng hoặc chiều cao của phần tử dựa vào flex-direction row hay column
. Mặc định là flex-direction: row
cho nên lúc này flex-basis
sẽ tương ứng với thuộc tính width
của phần tử và khi flex-direction: column
thì lúc này flex-basis
sẽ là height
của phần tử.
Thuộc tính flex-basis
sẽ đè lên thuộc tính width hoặc height
của phần tử tùy thuộc vào giá trị của flex-direction
. Các bạn có thể thay giá trị cho flex-direction
vào Codepen dưới đây để hiểu hơn nha.
See the Pen CSS Flexbox basis by EvonDev (@blackzero) on CodePen.
# Flex-grow
Thuộc tính này khá là phức tạp nè, nó cho các phần tử giãn theo độ rộng của container, để mình giải thích cho các bạn qua từng hình ảnh nha. Đầu tiên mình cho các phần tử có độ rộng là 120px.
Mặc định giá trị trong thuộc tính flex-grow
là 0. Nghĩa là các phần tử sẽ không tự động co giãn kích thước khi chiều rộng của container bao ngoài thay đổi. Hơi khó hiểu nhỉ ? Để mình tăng flex-grow
lên 1 cho các phần tử coi sao.
Wow. Các phần tử tự động giãn ra đều nhau sao cho vừa với khung container luôn, hay thật. Ủa vậy flex-grow: 1
là gì nhỉ, mình tăng lên 999 có sao không ? Không có bị gì luôn.
Giá trị của flex-grow
rất là linh động chứ không tuyệt đối nghĩa là khi set giá trị flex-grow
cho các phần tử thì các phần tử đều có tỉ lệ với nhau. Ví dụ set tất cả các phần tử flex-grow
là 1 thì tất cả đều như nhau tỉ lệ 1:1, nếu set 999 cho toàn bộ thì cũng vậy vì bằng nhau hết mà đơn giản về hết cũng là 1:1.
See the Pen CSS Flexbox grow – row by EvonDev (@blackzero) on CodePen.
Nhưng mà giả sử set các phần tử đều là flex-grow: 1
, nhưng set riêng phần tử thứ 3 giá trị khác thì sẽ như thế nào nhỉ ?
Chỗ này có áp dụng toán học nên mình sẽ giải thích cho các bạn hiểu. Bây giờ mình có 6 phần tử, ta set flex-grow: 1
cho các phần tử thì các phần tử sẽ bằng nhau vì container sẽ chia đều cho 6. Mỗi phần tử sẽ chiếm 1/6 đúng không nào ?
Nhưng khi mình tăng ô số 3 lên flex-grow: 2
. Thì lúc này giá trị của flex-grow
của các phần tử cộng lại sẽ là 7 cho nên container sẽ chia đều cho 7 vì 1 + 1 + 2 + 1 + 1 + 1. Ô số 3 có flex-grow: 2
nên sẽ chiếm 2/7 của container còn các phần tử còn lại chiếm 1/7.
See the Pen CSS Flexbox grow – row2 by EvonDev (@blackzero) on CodePen.
Khi tăng ô số 3 lên flex-grow:3
. Thì giá trị flex-grow
của các phần tử cộng lại sẽ là 8 và container sẽ chia đều cho 8(1+1+3+1+1+1). Ô số 3 sẽ chiếm 3/8 và các ô còn lại chiếm 1/8. Và cứ thế tiếp tục nếu các bạn tăng.
Như đã nói ở trên thuộc tính flex-grow
làm cho các phần tử tỉ lệ với nhau. Giả sử các phần tử đều có flex-grow: 4
và ô số 3 có thuộc tính flex-grow: 12
thì nó cũng tương tự như là 1 với 3.
Tips của mình hay dùng cho dễ hiểu đó là cứ lấy cái giá trị flex-grow của cái ô có số to nhất chia cho ô có số nhỏ nhất thì sẽ ra được tỉ lệ các phần tử so với nhau. Như ở trên 12/4 được 3 suy ra các ô còn lại sẽ bằng 1/3 ô lớn nhất.
Một điều nữa là khi dùng với flex-direction: column
thì flex-grow
sẽ giãn theo chiều dọc và lúc này nó sẽ là height(chiều cao) chớ không phải chiều rộng(width) nha. Cái này các bạn áp dụng tương tự để tự luyện tự hiểu cho mau lên trình nha.
# Flex-shrink
Thuộc tính này thì nó ngược lại so với thuộc tính flex-grow
ở trên, nó không giãn ra mà lại co lại khi chúng ta thay đổi độ rộng của container xuống. Mặc định giá trị trong flex-shrink
là 1 nghĩa là cho phép các phần tử co lại khi độ rộng container giảm xuống.
Các bạn thấy chứ các phần tử nó sẽ co lại khi chúng ta resize trình duyệt nhỏ xuống. Nhưng nếu các bạn set cho nó flex-shrink: 0
thì nó sẽ không co giãn và lúc này nó sẽ lấy giá trị của thuộc tính width.
See the Pen CSS Flexbox shrink by EvonDev (@blackzero) on CodePen.
Ở đây các bạn thấy phần tử số 3 có flex-shrink: 0
. Thì khi co giãn lại tới ngưỡng độ rộng 120px(thuộc tính width) của nó thì nó vẫn sẽ giữ độ rộng đó chứ không co lại hơn nữa như các phần tử có flex-shrink: 1
. Mình có note trong Codepen ở trên. Các bạn vào test xem đúng không nhá.
Cũng như flex-grow
thì trong flex-shrink
các phần tử cũng tỷ lệ với nhau nha. Phần tử A có flex-shrink: 6
và các phần tử còn lại có flex-shrink: 2
. Thì cũng tương tự là 3:1. Ủa nếu ô có flex-shrink: 3
còn các ô khác flex-shrink: 1
thì khi co lại nó sẽ có độ rộng bằng 1/3 so với những cái còn lại à ?
Trước khi đi sâu vào giải thích thì mình xin giới thiệu thêm 1 thuộc tính khác nữa trước đã nhé. Đó là flex
(thuộc tính nhá)
# Flex
Flex là viết tắt của 3 thuộc tính flex-grow flex-shrink và flex-basis
. Nó như thế này. flex: flex-grow flex-shrink flex-basis
. Mặc định grow(0) shrink(1) và basis(auto).
Các bạn xem ví dụ dưới đây cả hai đều có flex-basis
như nhau. Nhưng mà ở box1 thì lại có flex-grow:2
nghĩa là box1 sẽ dài gấp đôi box2 khi độ rộng container giãn ra. Nhưng box2 thì lại có flex-shrink:2
nghĩa là khi container nhỏ xuống thì box2 sẽ co lại và có chiều dài bằng 1/2 box1 đúng không nhỉ ?
Chỗ này sao mà rối loạn quá ? Sao trong hình GIF lúc container giãn ra mình thấy box1 có gấp đôi box2 đâu hay khi co container lại box2 có bằng 1/2 box1 đâu. Đây chính là điểm luôn làm mình cũng như các bạn rối não khi làm việc với flexbox
Khi kết hợp 2 giá trị flex-shrink và flex-grow
lại với nhau thì phức tạp lắm, không chỉ là tỉ lệ về các con số đâu mà là về tốc độ grow(giãn ra) hay shrink(co lại) nữa đó. Nào cùng vào phần hại não phía dưới nha.
# Giải thích grow và shrink khi kết hợp
Giả sử ban đầu ta có container có độ rộng tối đa là 640px sau khi tính toán bao gồm padding 2 bên của container. Lúc này có 2 phần tử như ở trên có flex-basis
là 300px(bằng nhau về chiều rộng).
See the Pen CSS Flexbox shrink+grow by EvonDev (@blackzero) on CodePen.
Khi các bạn resize trình duyệt lại sao cho container còn 430px thì lúc này chúng ta sẽ mất là 640 – 430 = 210px. Ô số 1 do có flex-shrink: 1
nên nó mất 70px(chiều rộng của nó bây giờ sẽ là 300 – 70 = 230px), còn ô số 2 có flex-shrink: 2
nên sẽ mất đi 140px(chiều rộng sẽ còn 300 – 140x = 160px).
Các bạn lại resize trình duyệt tiếp cho đến khi độ rộng container xuống 340px thì chúng ta mất 640 – 340 = 300px. Ô số 1 có flex-shrink: 1
nên sẽ mất 100px(còn 200px) còn ô số 2 sẽ mất 200px(còn 100px) do có flex-shrink: 2
.
Tương tự với flex-grow
. Khi tăng độ rộng container lên 940px. Thì container được tăng thêm 300px(640 + 300 = 940). Ô số 1 có flex-grow: 2
nên sẽ tăng lên thêm 200px(tổng sẽ là 500px) còn ô số 2 có flex-grow: 1
nên sẽ chiếm 1/3 là 100px nên nó sẽ tăng thêm độ rộng 100px(tổng sẽ là 400px).
Các bạn nên inspect các phần tử trong Codepen để xem sự thay đổi. Khi độ rộng container giảm xuống so với ban đầu thì chúng ta tính theo
flex-shrink
và ngược lại khi độ rộng container tăng lên so với ban đầu thì tính theoflex-grow
. Phần tăng lên hay giảm xuống của container sẽ chia tỉ lệ choflex-shrink
hayflex-grow
tương ứng của các phần tử
Các bạn xem hình GIF và Codepen từ từ mới thông được. Nếu khó thông quá thì bình luận hoặc inbox cho mình. Mình sẽ giải đáp cho nha.
See the Pen CSS Flexbox shrink+grow2 by EvonDev (@blackzero) on CodePen.
# Lời kết
Phù!!! Bài viết về css flexbox đến đây là hết. Các bạn ráng học nhé. Có gì không hiểu cứ bình luận hoặc thấy mình viết sai hay giải thích sai thì góp ý giúp mình để mình cải thiện lại cách viết cũng như kiến thức. Cám ơn các bạn đã đọc bài và chúc các bạn một ngày tốt lành.
Bài viết có tham khảo và hình ảnh lấy từ medium.freecodecamp.org
.
Bài viết hay lắm anh!
Cám ơn em nha. Chia sẻ cho mọi người cùng học nhé
Em cảm ơn anh, nhờ những bài viết của anh em ngộ ra được nhiều điều lắm anh ạ :)))
Cám ơn em nha. Chúc em học tốt
bài viết chi tiết quá, nhưng mình chưa hiểu cách viết tắt Flex:1; nghĩa là thế nào ạ
Nó là viết tắt của flex-grow flex-shrink flex-basis á bạn. flex: 1 sẽ là flex-grow: 1, flex-shrink: 1 và flex-basis: 0
Flex: 1 = grow
Flex: 1 1 = grow shrink
Flex: flex-grow , flex-shrink, flex-basis
Trong docs mdn có nè bạn
One-value syntax: the value must be one of:
<number>
: In this case it is interpreted asflex: <number> 1 0
; the<flex-shrink>
value is assumed to be 1 and the<flex-basis>
value is assumed to be0
.Là grow = 1 và shrink = 1 luôn đó bạn!
Bài viết của anh rất hay ạ <3 Em hi vọng anh sẽ sớm ra những bài viết chất lượng hơn nữa <3
Bài viết hay lắm anh, cảm ơn anh nhiều!!!
Cám ơn bạn nè
Bài viết chi tiết!
rất tuyệt vời cảm ơn bạn nhiều
Thanks <3
Nội dung hay quá cám ơn bạn
e cam on anh
ra tiếp đi anh ơi
ok
Em là newbie mới tập tành, may đọc được bài viết của anh, cảm ơn anh rất nhiều ạ! <3
Anh cám ơn em đã đọc bài nè. Chúc em học tập tốt nha
Bài viết chi tiết quá
hay anh
Cám ơn em nè
70px đó đâu ra vậy ạ?
có thuộc tính nào mà để width của box-con bằng width của box-cha ko ạ
hay