CSS - Mastering Flexbox
Bài đăng này đã không được cập nhật trong 4 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-axisbằ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-startvà đ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-startvàmain-endnhữ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-itemsẽ điều hướng theo trục ngang.

row-reverse: cácflex-itemsẽ đ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ưrownhưng chúng được điều hướng theo chiều dọc.

column-reserve: tương tự nhưrow-reversenhư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ưwrapnhư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-starttheoflex-direction

flex-end: flex item sẽ bắt đầu từmain-endtheoflex-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 theobaselinecủ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