Giới thiệu
Flexbox Layout có tên chính thức là Css Flexible Box Layout Module là module mới trong CSS3 nhằm cải thiện việc sắp xếp, căn chỉnh cũng như hướng của các thành phần HTML một các tự động theo mọi kích thước. Đặc tính của các container Flexbox là có thể tùy chỉnh size, khoảng cách của các thành phần con trong nó. Nói theo cách khác, bạn không cần thiết lập kích thước của phần tử, không cần cho nó float, chỉ cần thiết lập nó hiển thị chiều ngang hay chiều dọc, lúc đó các phần tử bên trong có thể hiển thị theo ý muốn.
Khái niệm cơ bản
Flexbox Container (Phần tử cha)
1.1 Cách sử dụng:
– Để phần tử cha này được sử dụng Flexbox chúng ta có 2 cách để set giá trị cho nó: (Nhìn hình ảnh ví dụ để thấy sự khác nhau)
.flex-container { display: -webkit-flex; /* Safari */ display: flex; }
Hoặc:
.flex-container { display: -webkit-inline-flex; /* Safari */ display: inline-flex; }
– Khi container được set là flexbox thì các thành phần con trong nó sẽ là flex item.
1.2 Các thuộc tính:
Flex-direction
– Thuộc tính này quy định cách trình bày các item trong khung, bằng cách đặt hướng cho khung theo một trục chính. Chúng có thể được trình bày theo hai hướng, giống như hàng ngang hay hàng dọc.. và có 4 giá trị cụ thể
.flex-container { flex-direction: row | row-reverse | column | column-reverse; }
Trong đó:
-
-
- Row: trái qua phải (Giá trị mặc định)
-
-
-
- Row-reverse: phải qua trái
-
-
-
- Column: trên xuống dưới
-
-
-
- Column-reverse: dưới lên trên
-
Flex-wrap
– Mặc định các item sẽ co để vừa vào một dòng, tuy nhiên không phải lúc nào nhu cầu của chúng ta cũng như thế, đó là lý do thuộc tính này được tạo ra.
.flex-container{ flex-wrap: nowrap | wrap | wrap-reverse; }
Trong đó:
-
-
- nowrap: Tất cả các item sẽ nằm trên một dòng (Giá trị mặc định)
-
-
-
- wrap: Nếu các item của bạn quá lớn để hiển thị trên một dòng các item sẽ tự động xuống dòng theo thứ tự từ trên xuống dưới.
-
-
-
- wrap-reverse: Giống như wrap nhưng thứ tự từ dưới lên trên.
-
Flex-flow
– Thuộc tính này là một dạng viết tắt của hai thuộc tính flex-direction và flex-wrap với giá trị mặc định row nowrap.
.flex-container{ flex-flow: <flex-direction> <flex-wrap>; }
Justify-content
– Thuộc tính này sắp xếp các item theo trục chính của dòng hiện tại trong khung. Nó giúp bổ sung không gian còn thừa ngay cả khi các item trên một dòng không thể co giãn hoặc đã đạt đến kích thước tối đa. (Nói một cách đơn giản nó giúp các item căng chỉnh theo chiều của thuộc tính flex-direction: Ví dụ flex-direction: row; nó sẽ căng chỉnh theo chiều ngang…).
.flex-container { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | ...; }
Trong đó:
-
-
- Flex-start: Các item dồn về bên trái (Giá trị mặc định)
-
-
-
- Flex-end: Các item dồn về bên phải
-
-
-
- Center: Các item tập trung vào giữa hàng
-
-
-
- Space-between: Các item cách đều nhau, item đầu tiên sẽ sát ở đầu và item cuối sẽ sát ở cuối.
-
-
-
- Space-around: Các item được phân bố đều trong dòng với không gian xung quanh chúng bằng nhau. Với giá trị này bạn sẽ thấy khoảng cách ở 2 đầu nhỏ hơn khoảng cách giữa các item vì khoảng cách ở 2 đầu được tính chỉ bằng ½ khoảng cách giữa các item.
-
-
-
- Space-evenly: Khoảng cách ở giữa các item luôn luôn bằng nhau.
-
– Còn rất nhiều giá trị với nhiều tính năng hấp dẫn của thuộc tính này(start,end, left, right, safe, unsafe), hãy trải nghiệm nhé 😀
Đối với thuộc tính này chúng ta có vài lưu ý nhỏ:
-
- Giá trị Space-between không hỗ trợ cho một vài phiên bản trình duyệt Edge
- Các giá trị start/end/left/right không hoạt động trên trình duyệt Chrome
-> Nên sử dụng các giá trị: flex-start, flex-end, center để đảm bảo trang web của bạn hoạt động an toàn nhé 🙂
Hoặc có thể tham khảo hình ảnh dưới đây để sử dụng các giá trị khác tốt hơn nhé
Align-items
– Hãy nghĩ về nó như thuộc tính Justify-content nhưng căn chỉnh phân phối không gian trên trục ngược lại. 🙂
.flex-container { align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe; }
Trong đó:
-
-
- Stretch (Giá trị mặc định): Các item được kéo dài để lấp đầy container
-
-
-
- Flex-start/start/self-start: Các item được đặt ở đầu trục chéo, sự khác biệt giữa các giá trị này là các vấn đề liên quan đến quy tắc hướng uốn và quy tắc chế độ viết.
-
-
-
- Flex-end/end/self-end: Giống như các giá trị start nhưng các item được đặt ở cuối trục chéo.
-
-
-
- Center: Các item được căn giữa trục chéo
-
-
-
- Baseline: Các item con bám theo đường baseline của hàng(Baseline là định nghĩa trong typography. Các bạn có thể xem bài này để hiểu baseline trong typography là gì thì sẽ hiểu ngay giá trị baseline trong flexbox.)
-
Align-content
– Thuộc tính này giúp sắp xếp các flex items khi có khoảng trống thừa trong trục của flex container (giống như Justify-content với chiều ngang) và có giá trị mặc định là Stretch (Thông thường khi chúng ra responsive thì trên thiết bị màn hình nhỏ các item nên được xuống dòng, thuộc tính này sinh ra giúp căng chỉnh các item một cách tốt nhất). Các giá trị cũng có ý nghĩa như Justify-content nên mình sẽ không giải thích và chỉ cho ví dụ minh họa thôi nhé. 🙂
– Lưu ý thuộc tính này chỉ có giá trị khi có nhiều hơn 1 item nhé.
.flex-container { align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe; }
-
-
- Stretch(mặc định)
-
-
-
- Flex-start
-
-
-
- Flex-end
-
-
-
- Center
-
-
-
- Space-between
-
-
-
- Space-around
-
-
-
- Space-evenly
-
Flexbox Item
– Flexbox item nhắm trực tiếp đến các item để chúng ta có thể kiểm soát chúng một cách tối đa nhất có thể.
2.1 Các thuộc tính:
Order
– Mặc định các item có thứ tự như source code html của bạn, nhưng đôi khi chúng ta không thể control nó (Ví dụ generate bằng vòng lặp item được tạo ra đầu tiên nhưng mình muốn nó ở vị trí thứ 3). Thuộc tính này sẽ giải quyết giúp bạn vấn đề này nhé.
.item { order: <number>; /* mặc định là 0 */ }
Flex-grow: (Thuộc tính này khá phức tạp nè)
– Định nghĩa khả năng giãn của một item theo chiều rộng của container. Nó chỉ định bao nhiêu không gian còn lại trong flex-container nên được chỉ định cho vật phẩm.
– Kích thước chính là chiều rộng hoặc chiều cao của vật phẩm phụ thuộc vào giá trị flex-direction
– Khái niệm “Không gian còn lại” nghĩa là kích thước của flex-container trừ đi kích thước của tất cả các item còn lại.
– Nếu các item đều set giá trị là 1 thì không gian chứa sẽ được chia đều cho tất cả các item.
– Đi vào ví dụ thực tế để dễ hiểu hơn nhé:
-
-
- Đầu tiên mình cho các phần tử có độ rộng là 70px. 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.
-
-
-
- Ở đây mình sẽ set flex-grow tất cả các item với giá trị là 1 thử nhé:
-
-
-
- Như ta thấy các phần tử tự động giãn ra đều nhau vừa với container. Thật ra ở đây giá trị là 1 hoặc 1000 cũng như nhau vì chúng sẽ linh hoạt bằng nhau hết 1000:1000 thì đơn giản là 1:1 thôi.
- Tiếp theo mình sẽ thử trường hợp set phần tử thứ 2 giá trị khác lớn hơn 1, các phần tử còn lại vẫn giữ nguyên giá trị 1
-
-
-
- Có sự khác biệt rõ ràng ở item 2 mình sẽ giải thích nhé: Chúng ta có 6 item ta set giá trị 1 cho mỗi item thì mỗi item sẽ chiếm ⅙ nhưng khi ta tăng giá trị của ô số 2 lên 2 thì lúc này tổng giá trị của các phần tử sẽ là 7 cho nên container sẽ được chia đều cho 7 và item 2 có flex-flow: 2 nên sẽ chiếm 2/7 còn các item còn lại chiếm 1/7.
- Một tips nhỏ là bạn có thể lấy item có giá trị lớn nhất chia cho giá trị nhỏ nhất thì sẽ ra được tỉ lệ các phần tử so với nhau, ví dụ 2/1 là 2 suy ra các phần tử còn lại sẽ bằng ½ ô lớn nhất.
-
– Ở đây mình có một lưu ý: 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)
Flex–shrink
– Thuộc tính này ngược lại so với thuộc tính flex-grow, 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.
– 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, dù bạn co giãn bao nhiêu width cũng không thay đổi.
Flex-basic
– Thuộc tính này xác định kích thước của một item trước khi không gian còn lại được phân phối. Giá trị mặc định là auto(Phần tử sẽ được tự động kích thước dựa trên nội dung của nó hoặc trên bất kỳ giá trị chiều cao hoặc chiều rộng nào nếu chúng được xác định.). Bạn có thể xác định giá trị pixel, phần trăm hoặc (r)em…
.item { flex-basis: | auto; }
Flex
– Flex là viết tắt của 3 thuộc tính flex-grow flex-shrink và flex-basis. Mặc định grow(0) shrink(1) và basis(auto).
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
– Khi kết hợp 2 giá trị flex-shrink và flex-grow lại với nhau thì khá phức tạp, 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ên cẩn thận tránh để bị rối nhé 🙂
Align-self
– Thuộc tính này tương tự với thuộc tính align-items của flex-container nhưng khác ở chỗ là áp dụng riêng lẻ cho các phần tử mà bạn muốn thay đổi giá trị của nó.
.flex-item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
Thực hành
Git: https://github.com/mytruong-z/complete-guide-to-flexbox
Demo: https://demo-guide-to-flexbox.herokuapp.com/
Tham Khảo
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Lời kết
Vậy là đã xong, mong các bạn sẽ rút kết được các thông tin bổ ích và cần thiết về Flexbox nhé 🙂