Flexbox hay là Flexible Box được dùng để thay thế Floats trong việc thiết kế layout cho trang web. Khi mà float chỉ có khả năng dàn ngang boxes, flexbox sẽ cho chúng ta toàn quyền tùy chỉnh alignment
, direction
, order
, và size
của boxes.
Ở bài này chúng ta sẽ tìm hiểu flexbox thông qua những ví dụ, và sau khi hoàn thành chúng ta sẽ được một layout như sau:
Cài đặt
Bắt đầu bằng việc tạo ra file flexbox.html
:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Some Web Page</title>
<link rel='stylesheet' href='styles.css'/>
</head>
<body>
<div class='menu-container'>
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='signup'>Sign Up</div>
<div class='login'>Login</div>
</div>
</div>
</body>
</html>
Sau đó tạo ra file styles.css
:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.menu-container {
color: #fff;
background-color: #5995DA; /* Blue */
padding: 20px 0;
}
.menu {
border: 1px solid #fff; /* For debugging */
width: 900px;
}
Cuối cùng tải các file ảnh, giải nén chúng và đặt trong folder images
:
Tổng quan về Flexbox
Trong flexbox có hai khái niệm là flex containers và flex items:
Flex containers
Bây giờ chúng ta sẽ thay đổi file styles.css
bằng cách thêm thuộc tính display
:
.menu-container {
/* ... */
display: flex;
}
Mục đích là để cho browser biết chúng ta đang sử dụng flex để xây dựng layout:
Aligning những phần tử flex
.menu-container {
/* ... */
display: flex;
justify-content: center; /* Add this */
}
Bằng việc định nghĩa justify-content: center
chúng ta sẽ cho các items
căn giữa theo chiều ngang, nó tương tự như định nghĩa margin: 0 auto
vậy.
Các giá trị có thể có của justify-content
là:
- center
- flex-start
- flex-end
- space-around
- space-between
Phân phối lại các flex items
Chúng ta có thể left/right alignment với floats
và căn giữa bằng auto-margins, nhưng flexbox còn có thể layout các items đều nhau trong containers nữa.
Thay đổi .menu
trong styles.css
:
.menu {
border: 1px solid #fff;
width: 900px;
display: flex;
justify-content: space-around;
}
Nào, hãy lần lượt thử các giá trị còn lại của justify-content
để xem sự khác biệt.
Nhóm các flex items
Bằng cách thêm các thẻ <div>
bao bọc những items muốn nhóm chúng ta sẽ đạt được mục đích.
Ví dụ chúng ta muốn có hai links Sign Up và Login gom thành một nhóm, ta tùy chỉnh lại <div class='menu'>
như sau:
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='links'>
<div class='signup'>Sign Up</div> <!-- This is nested now -->
<div class='login'>Login</div> <!-- This one too! -->
</div>
</div>
Và kết quả sẽ như bên dưới, nhớ lại rằng class .signup
và .login
mặc định sẽ display: block
khi container chứa chúng không định nghĩa display: flex
.
Thay đổi styles.css
để display: flex
cho .links
:
.links {
border: 1px solid #fff; /* For debugging */
display: flex;
justify-content: flex-end;
}
.login {
margin-left: 20px;
}
Tới giờ chúng ta dùng border
cho việc debug
, ta có thể gỡ chúng đi.
Căn chỉnh ngang-dọc các items
Có hai thuộc tính quan trọng trong flexbox là justify-content
và align-items
để căn chỉnh các phần tử con.
Thay đổi flexbox.html
:
<div class='header-container'>
<div class='header'>
<div class='subscribe'>Subscribe ▾</div>
<div class='logo'><img src='images/awesome-logo.svg'/></div>
<div class='social'><img src='images/social-icons.svg'/></div>
</div>
</div>
Tiếp theo align .menu
của chúng ta:
.header-container {
color: #5995DA;
background-color: #D6E9FE;
display: flex;
justify-content: center;
}
.header {
width: 900px;
height: 300px;
display: flex;
justify-content: space-between;
}
Hãy nhớ rằng justify-content
để căn chỉnh theo chiều ngang, và align-items
để căn chỉnh theo chiều dọc, thay đổi styles.css
như dưới:
.header {
/* ... */
align-items: center; /* Add this */
}
Tương tự justify-content
, align-items
cũng có những giá trị có thể có như sau, thử đi nào!
- center
- flex-start (top)
- flex-end (bottom)
- stretch
- baseline
Thử giá trị align-items: stretch
, ta thấy rằng không có sự thay đổi, tuy nhiên, tiếp tục thêm border
cho các items để xem điều gì xảy ra.
.header {
/* ... */
align-items: stretch; /* Change this */
}
.social,
.logo,
.subscribe {
border: 1px solid #5995DA;
}
Wrapping các flex items
Khi số lượng các items nhiều làm tràn giao diện, flex-wrap
sẽ thể hiện vai trò của nó.
Một lần nữa thay đổi flexbox.html
:
<div class='photo-grid-container'>
<div class='photo-grid'>
<div class='photo-grid-item first-item'>
<img src='images/one.svg'/>
</div>
<div class='photo-grid-item'>
<img src='images/two.svg'/>
</div>
<div class='photo-grid-item'>
<img src='images/three.svg'/>
</div>
</div>
</div>
Đối với styles.css
:
.photo-grid-container {
display: flex;
justify-content: center;
}
.photo-grid {
width: 900px;
display: flex;
justify-content: flex-start;
}
.photo-grid-item {
border: 1px solid #fff;
width: 300px;
height: 300px;
}
Nó sẽ hiển thị tốt, tuy nhiên điều gì xảy ra khi số lượng items lớn hơn 3, thử thêm 2 items nữa xem sao:
<div class='photo-grid-item'>
<img src='images/four.svg'/>
</div>
<div class='photo-grid-item last-item'>
<img src='images/five.svg'/>
</div>
Mặc định, chúng sẽ bị tràn ra như thế này:
Sửa lại như thế này nha :
.photo-grid {
/* ... */
flex-wrap: wrap;
}
Okie, những items bị tràn đã đẩy xuống dưới, tiếp tục nghịch @@ :
.photo-grid {
width: 900px;
display: flex;
justify-content: center; /* Change this */
flex-wrap: wrap;
}
Hai items dưới đã vào giữa :
Hướng của flex container
Mặc định flex-direction
trong flex có giá trị là row
, cho nên khi thêm display: flex
cho container bao bọc chúng, ta thấy các items sẽ lập tức dàn hàng ngang, để chúng dàn hàng dọc thì ta thay đổi flex-direction: column
.
.photo-grid {
/* ... */
flex-direction: column;
}
Kết quả như thế này, nó sẽ hữu ích trong trường hợp ta muốn responsive
cho mobile.
Thuộc tính Alignment
Thay đổi flex-direction: column
thì vai trò của justify-content
và align-items
sẽ hoán đổi cho nhau.
Thử thay đổi như sau :
.photo-grid {
/* ... */
flex-direction: column;
align-items: center; /* Add this */
}
Thứ tự của flex container
Đến giờ thứ tự xuất hiện các items sẽ bình thường như thứ tự các thẻ trong file html, chúng ta cũng có thể thay đổi thứ tự này.
.photo-grid {
width: 900px;
display: flex;
justify-content: center;
flex-wrap: wrap;
flex-direction: row-reverse; /* <--- Really freaking cool! */
align-items: center;
}
Kết quả :
Thứ tự của flex item
Thứ tự thay đổi theo flex-direction
sẽ áp dụng toàn bộ items, ta cũng có thể thứ tự riêng mỗi items nếu muốn.
Thay đổi styles.css
:
.photo-grid {
/* ... */
flex-direction: row; /* Update this */
align-items: center;
}
.first-item {
order: 1;
}
.last-item {
order: -1;
}
Alignment cho flex item
Align riêng hai items ứng với class .social
và .subcribe
để chúng nằm bên dưới.
.social,
.subscribe {
align-self: flex-end;
margin-bottom: 20px;
}
Kết quả :
Nhắc lại một số giá trị có thể dùng là :
- center
- flex-start (top)
- flex-end (bottom)
- stretch
- baseline
Flexible items
Tất cả các ví dụ trên layout các items với kích thước mỗi item là cố định, bây giờ nếu muốn stretch
chúng theo container :
Trước tiên, thêm vào file flexbox.html
phần footer :
<div class='footer'>
<div class='footer-item footer-one'></div>
<div class='footer-item footer-two'></div>
<div class='footer-item footer-three'></div>
</div>
Thay đổi styles.css
:
.footer {
display: flex;
justify-content: space-between;
}
.footer-item {
border: 1px solid #fff;
background-color: #D6E9FE;
height: 200px;
flex: 1;
}
Trong đó, flex: 1
đảm bảo các items sẽ chiếm hết không gian container và kích thước của các items mặc định sẽ bằng nhau.
Ta có thể thay đổi flex
cho một item con để thấy chúng có kích thước khác với các item còn lại, chẳng hạn với .footer-three
:
.footer-three {
flex: 2;
}
Thay đổi chiều rộng cho static item
.footer-one,
.footer-three {
background-color: #5995DA;
flex: initial;
width: 300px;
}
Flex items và auto-margins
Thay đổi file .html :
<div class='menu-container'>
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='signup'>Sign Up</div>
<div class='login'>Login</div>
</div>
</div>
và file .css :
.signup {
margin-left: auto;
}
Tóm lại
- Dùng
display: flex;
để tạo ra một flex container. - Dùng
justify-content
để căn ngang các items. - Dùng
align-items
để căn dọc các items. - Dùng
flex-direction
nếu muốn các items theo hướng chiều dọc chứ không phải ngang. - Dùng
row-reverse
hoặccolumn-reverse
để đảo ngược thứ tự mặc định. - Dùng
order
để tùy chỉnh thứ tự một item cụ thể. - Dùng
align-self
để căn dọc một item cụ thể. - Dùng
flex
để tạo ra một flexible boxes có thể stretch và shrink.
Tham khảo
https://internetingishard.com/html-and-css/flexbox/