CSS - Mastering Flexbox
Bài đăng này đã không được cập nhật trong 3 năm
Khi bạn làm về fontend hay bắt đầu học và tìm hiểu về CSS chắc hẳn bạn đã biết hoặc nghe về Flexbox. Vậy flexbox là gì? Sử dụng flexbox như thế nào? Khi nào nên sử dụng flexbox? Nên trong bài viết này chúng ta sẽ cùng tìm hiểu về flexbox cũng như công dụng của nó.
Flexbox là gì?
Flexbox nhằm mục đích cung cấp một giải pháp hiểu quả trong việc bố trí, sắp xếp và phân bố các phần tử(item) bên trong một container
. Chúng sẽ tự cân đối các phần tử trong container
khi các phần tử không được xác định kích thước rõ ràng. Với flexbox ta có thể dễ dàng căn chỉnh hướng, bố cục, kích thước hay vị trí của các phần tử trong container
.
Flexbox tiện ích là vậy nhưng chúng ta chỉ nên sử dụng khi cần layout cho các component
hay những bố cục có phạm vi nhỏ. Còn nếu muốn layout cho phạm vi lớn hơn hay trang web ta nên sử dụng Grid.
Khái niệm cơ bản
Trược khi đi tìm hiểu về các thuộc tính của flexbox ta sẽ tìm hiểu về cấu trúc của nó và một số thuật ngữ cần nhớ.
Tất cả các phần tử trong container
đều được layout theo main-axis
và được bắt đầu từ main-start
đến main-end
hoặc cross-axis
và bắt đầu từ cross-start
đến cross-end
.
main-axis
: trục chính để điều hướng các flex item hiển thị trongcontainer
. Ta có thể thay đổimain-axis
bằng cách dùng thuộc tínhflex-direction: row | column
.main-start
|main-end
: khi ta sử dụng flexbox để layout thì điểm bắt đầu củacontainer
được gọi làmain-start
và điểm kết thúc được gọi làmain-end
.main-size
: là kích thước của mỗi flex item dựa vàomain-axis
.cross-axis
: là trục vuông góc với trục chínhmain-axis
.cross-start
|cross-end
: tương tự nhưmain-start
vàmain-end
những nó được tính theocross-axis
.cross-size
: là kích thước của mỗi flex item dựa vàocross-axis
.
Thuộc tính Flexbox
Để sử dụng flexbox để layout trước hết ở container ta phải sử dụng display: flex
. Ta có đoạn HTML và CSS sau.
<div class="container radius">
<div class="item radius"></div>
<div class="item radius"></div>
<div class="item radius"></div>
</div>
.radius {
border-radius: 3px;
}
.container {
background-color: #907fa4;
padding: 10px;
}
.item {
background-color: #a6d6d6;
margin: 10px;
height: 100px;
}
Giao diện sẽ như sau:
Khi ta thêm display: flex
vào container
ta sẽ có.
Vì mặc định thẻ div sẽ có display: block
nên khi ta có 3 thẻ div thì tương ứng với mỗi thẻ dev sẽ ở trên cùng một dòng và có chiều rộng là full cửa sổ trình duyệt còn khi ta thêm display: flex
vào container
. Thì 3 thẻ div trong container
sẽ nằm trên cùng một dòng (vì mặc định khi sử dụng flexbox ta sẽ có flex-direction: row
lát ta sẽ tìm hiểu ở bên dưới) và chiều rộng của nó sẽ theo content trong thẻ div. Ở đây mình có set thêm width: 100px
cho mỗi item trong container
cho dễ nhìn.
.item {
background-color: #a6d6d6;
margin: 10px;
height: 100px;
width: 100px;
}
flex-direction
Thuộc tính flex-direction
dùng để điều hướng cho main-axis
của flexbox.
flex-direction: row | row-reverse | column | column-reserve
row
: đây là giá trị mặc định khi ta sử dụng flex box, cácflex-item
sẽ điều hướng theo trục ngang.
row-reverse
: cácflex-item
sẽ điều hướng theo trục ngang nhưng các phần tử sẽ bị đảo ngược.
column
: tương tự nhưrow
nhưng chúng được điều hướng theo chiều dọc.
column-reserve
: tương tự nhưrow-reverse
nhưng chúng được điều hướng theo chiều dọc.
flex-wrap
Mặc định các flex item sẽ được fit vào 1 dòng. Nhưng khi các flex item có tổng chiều dài lớn hơn container
nếu ra muốn khi bị tràn ra thì các flex item tự động bị đẩy xuống dòng mới thì như thế nào?. Lúc này ta cần đến thuộc tính flex-wrap
.
flex-wrap: nowrap | wrap | wrap-reverse
nowrap
: đây là thuộc tính mặc định, các item sẽ không được xuống dòng khi tràn ra mà sẽ được hiển thị trên một dòng.
wrap
: các item sẽ tự động xuống dòng khi tràn và chúng sẽ được hiển thị trên nhiều dòng từ cao xuống thấp.
wrap-reverse
: tương tự nhưwrap
nhưng chúng được hiển thị từ dưới lên trên.
flex-flow
flex-flow
là shorthand của flex-direction
và flex-wrap
.
flex-flow: column wrap
tức là flex-direction: column + flex-wrap: wrap
.
justify-content
Đây là thuộc tính để căn chỉnh các flex item theo main-axis
. Nó sẽ phân chia những phần còn thừa của container một cách linh hoạt theo ý ta muốn. Ở đây mình sẽ đề cập đến một số thuộc tính hay dùng.
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly
flex-start
: đây là giá trị mặc định, flex item sẽ bắt đầumain-start
theoflex-direction
flex-end
: flex item sẽ bắt đầu từmain-end
theoflex-direction
center
: các flex item sẽ được căn ở giữa theomain-axis
space-between
: các flex item sẽ được căn tương đối với nhau, phần tử đầu tiền bắt đầu ởmain-start
, phần tử cuối cùng ởmain-end
space-around
: các flex item sẽ được cách đều nhau
space-evenly
: các flex item sẽ có khoảng cách đều nhau, tính cả ở 2 đầu
align-item
align-item
giúp ta layout các flex item theo chiều của trục cross-axis
(vuông góc với hướng flex-direction
).
align-items: stretch | flex-start | flex-end | center | baseline
stretch
: giá trị mặc định, các phần tử sẽ có độ dài theo chiềucross-axis
(max-width hoặc max-height)
flex-start
: các flex-item sẽ được bắt đầu theo chiềucross-axis
ở vị trícross-start
flex-end
: các flex-item sẽ được bắt đầu theo chiềucross-axis
ở vị trícross-end
center
: các flex-item sẽ được căn ở chính giữa theo chiềucross-axis
baseline
: các flex item sẽ được căn theobaseline
của chúng
order
order
cho phép ta sắp xếp các flex item theo thứ tự mà ta mong muốn. Thứ tự sẽ được sắp xếp từ thấp đến cao.
order: <number>
flex-grow
flex-grow
giúp ta xác định chiều dài cho các flex item một cách "dynamic" theo container. Ví dụ ta có 3 flex item chiếm 500px theo chiều dài và container của ta còn thừa 500px nữa khi ta xét flex-grow
lần lượt là 1, 2, 3 tương ứng với 3 flex item thì 500px còn thừa sẽ được chia cho các flex item tướng ứng với số phần ta định nghĩa flex-grow
. Lúc này chiều dài của các container sẽ được giãn ra theo flex-grow
. Giả sử tổng flex-grow
các flex item là 6 thì tùy theo số flex-grow
ta sẽ chia phần còn thừa của container ra là 1/6, 2/6 và 3/6.
flex-grow: <number>
Trong phần này ta sẽ có một ví dụ thực tế sau:
Ở đây trang mp3 ta có danh sách hiển thị bài hát của bảng xếp hàng. Phân tích ta có thể thấy ở đây chỉ có tên bài hát là thay đổi các phần còn lại đã có width cố định. Nếu chia ra ta sẽ để flex item chứa tên bài hát có flex-grow: 1
để phần tử này sẽ chiếm toàn bộ phần còn lại của container.
flex-shrink
Khi ta thu nhỏ trình duyệt các phần tử sẽ đồng thời co lại nếu ta muốn một phần từ co lại nhiều hơn thì sao? Lúc này ta sẽ dùng đến flex-shrink
mặc định giá trị này sẽ là 1 (các phần tử sẽ bớt chiều rộng của mình như nhau). Nếu ta để giá trị này lớn hơn các phần tử flex còn lại thì flex item này sẽ bị co lại nhiều hơn (mất chiều rộng nhiều hơn các phần tử khác) theo một công thức.
Nhìn vào gif ta có thể thấy flex item thứ 2 bị co lại nhiều hơn so với 1 và 3 mặc dù flex item thứ 2 to hơn rất nhiều.
flex-basis
flex-basis
là độ rộng tượng đối của các flex item(giống như width và height).
Tổng kết
Như vậy qua bài viết này mình đã giới thiệu cho các bạn về Flexbox. Flexbox rất hữu dụng giúp ta có thể layout dễ dàng cho các phần tử thay vì trước đây sử dụng float. Mình hy vọng qua bài viết này các bạn có thể sử dụng thành thạo flexbox và áp dụng nó cho dự án của mình. Cảm ơn các bạn đã theo dõi đến hết bài viết .
All rights reserved