Flexbox toàn tập

Bài viết này sẽ hướng dẫn cho bạn mọi thứ về flexbox, bao gồm tất cả các thuộc tính cho phần tử cha (flex container) và phần tử con (flex items).
Flexbox toàn tập
Flexbox toàn tập

Thuật ngữ

  • Flex Layout: Flexible Box - vùng linh hoạt
  • Flex container / Container: phần tử cha
  • Flex items: phần tử con
  • Components: các thành phần nhỏ của ứng dụng

 

Giới thiệu

Flex Layout (bắt đầu được đề xuất sử dụng bởi W3C từ tháng 10 năm 2017) nhằm cung cấp một phương thức dàn trang hiệu quả hơn cho việc bố trí, căn chỉnh và phân phối không gian giữa các flex items trong một container, ngay cả khi kích thước của chúng là động hoặc không xác định.

Ý tưởng chính phía sau của flex layout là cung cấp cho container khả năng thay đổi chiều rộng / chiều cao (và thứ tự) của các flex items nhằm lấp đầy không gian có sẵn một cách tốt nhất (chủ yếu là để phù hợp với tất cả các loại thiết bị và kích thước màn hình). Flex layout mở rộng các flex items để lấp đầy không gian trống có sẵn hoặc thu nhỏ chúng để chống tràn (overflow).

Quan trọng nhất, Flex layout được thực thi theo cách trái ngược với kiểu dàn trang truyền thống (theo từng block theo chiều dọc và inline theo chiều ngang). Mặc dù những thứ đó hoạt động tốt cho các trang, nhưng chúng thiếu tính linh hoạt để hỗ trợ các ứng dụng lớn hoặc phức tạp (đặc biệt khi nói đến thay đổi hướng, thay đổi kích thước, kéo dài, thu nhỏ, v.v.).

Lưu ý: Flex layout thích hợp nhất cho các components của ứng dụng hoặc các bố cục quy mô nhỏ (small-scale layouts), trong khi Grid layout dành cho bố cục quy mô lớn hơn (large-scale layouts).

 

Khái niệm cơ bản

Bởi flexbox là một bộ module chứ không phải một thuộc tính riêng lẻ, cho nên nó liên quan đến rất nhiều thứ bao gồm các bộ thuộc tính của nó. Một số thuộc tính được định nghĩa cho container (phần tử cha - parent element, hay vùng linh hoạt - flex container), trong khi một số thuộc tính khác được định nghĩa cho các phần tử con - flex items.

Nếu cách thức dàn trang thông thường đều dựa trên hướng block và inline thì flex layout được thiết kế dựa trên flex-flow direction. 

Flex Flow Directions

Các thành phần sẽ được sắp xếp theo trục chính - main axis (từ main-start tới main-end) hoặc theo trục chéo - cross axis (từ cross-start tới cross-end).

  • main-axis: trục chính của một flex container là nơi mà các flex items được bố trí dọc theo đó. Hãy nhớ, nó không nhất thiết phải nằm ngang hay nằm dọc, nó hoàn toàn phụ thuộc vào thuộc tính flex-direction của container.
  • main-start | main-end: các flex items đặt bên trong container được sắp xếp theo chiều ngang, bắt đầu từ main-start cho đến main-end.
  • main-size: kích thước chính của flex items. Nó có thể là width - chiều rộng hoặc height - chiều cao, tùy thuộc vào trục chính - main axis của container.
  • cross-axis: trục chéo của một container. Nó nằm vuông góc với trục main-axis. Hướng của nó phụ thuộc vào hướng của main-axis.
  • cross-start | cross-end: mang ý nghĩa tương tự với main-start và main-end, nhưng theo hướng vuông góc với chúng.
  • cross-size: kích thước của flex items. Nó có thể là width - chiều rộng hoặc height - chiều cao, tùy thuộc vào trục chéo - cross axis của container.

 

Các thuộc tính dành cho parent - Container

Flex Container

 

display

Thuộc tính này giúp chỉ định một flex container. Các phần tử con trực tiếp của flex container sẽ trở thành flex items.

.container {
  display: flex | inline-flex;
}

 

flex-direction

Thuộc tính này giúp chúng ta thiết lập main axis, từ đó xác định hướng hiển thị của các flex items bên trong containerFlexbox là một khái niệm bố cục đơn hướng (single-direction layout concept). Bạn hãy nhớ các flex items được bố trí chủ yếu theo hàng ngang hoặc dọc.

.container { 
  flex-direction: row | column | row-reverse | column-reverse; 
}
  • row (được thiết lập mặc định): chuyển trục main axis theo chiều ngang. Các flex items được hiển thị từ trái qua phải (ở chế độ ltr), và phải qua trái (ở chế độ rtl).
  • row-reverse: tương tự như row, nhưng đảo ngược thứ tự các flex items.
  • column: chuyển trục main axis theo chiều dọc. Các flex items được hiển thị từ trên xuống dưới (ở chế độ ltr), và từ dưới lên trên (ở chế độ rtl).
  • column-reverse: tương tự như column, nhưng đảo ngược thứ tự các flex items.

 

flex-wrap

Theo mặc định, trình duyệt sẽ cố gắng sắp xếp tất cả flex items trên cùng một hàng. Bạn có thể thay đổi nó và cho phép các flex items xuống dòng khi cần thiết với thuộc tính này.

.container { 
  flex-wrap: nowrap | wrap | wrap-reverse; 
}
  • nowrap (mặc định): tất cả flex items sẽ được xếp trên cùng một hàng.
  • wrap: các flex items sẽ được bọc trên nhiều dòng, từ trên xuống dưới.
  • wrap-reverse: tương tự với wrap, nhưng theo thứ tự từ dưới lên trên.

Bạn có thể tham khảo một số ví dụ trực quan về flex-wrap ở https://css-tricks.com/almanac/properties/f/flex-wrap/.

 

flex-flow

Đây là một cách viết tắt, giúp chúng ta chỉ định cả 2 thuộc tính flex-direction và flex-wrap. Giá trị mặc định của flex-flow là row nowrap.

.container { 
  flex-flow: column wrap; 
}

 

justify-content

Justify Content

Thuộc tính này giúp xác định sự liên kết giữa các flex items dọc theo main axis. Nó giúp phân phối thêm không gian trống giữa các flex items trên cùng một hàng (flex line). Ngoài ra thuộc tính này còn thực hiện một số kiểm soát cho việc căn chỉnh các mục khi chúng tràn hàng (overflow).

.container { 
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe; 
}
  • flex-start (được thiết lập mặc định): các flex items được sắp xếp về phía bắt đầu của flex-direction.
  • flex-end: các flex items được sắp xếp về nơi kết thúc của flex-direction.
  • start: các flex items được sắp xếp về phía bắt đầu của hướng ghi (writing-mode direction).
  • end: các flex items được sắp xếp về nơi kết thúc của hướng ghi (writing-mode direction).
  • left: các flex items được sắp xếp về phía bên trái của container, trừ khi nó không hợp lý với flex-direction thì nó sẽ hoạt động như start.
  • right: các flex items được sắp xếp về phía bên phải của container, trừ khi nó không hợp lý với flex-direction thì nó sẽ hoạt động như end.
  • center: các flex items được căn giữa theo flex lines.
  • space-between: các mục được sắp xếp đều bên trong flex lines, các mục đầu tiên được xếp ở phần đầu của flex lines, các mục cuối cùng được sắp xếp tại phần cuối của flex lines.
  • space-around: các flex items được sắp xếp đều trên hàng với không gian bằng nhau giữa chúng. Cần lưu ý rằng, về mặt trực quan, trông có vẻ không gian giữa các mục là không đều nhau, điều này là do các flex items đều có cùng không gian trống ở hai bên.
  • space-evenly: các mục được phân phối khoảng trống là như nhau, kể cả khoảng cách giữa hai mục đầu và cuối so với container.

Bạn cũng cần lưu ý rằng, các trình duyệt khác nhau đều có một vài khác biệt nhất định cho các giá trị này. Ví dụ như space-between hầu như chưa được hỗ trợ từ Edge, cũng như các giá trị left | right | start | end vẫn chưa có ở Chrome. Các giá trị an toàn nhất là flex-start | flex-end | center.

Bạn có thể tham khảo liên kết sau để biết thêm chi tiết https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content.

Ngoài ra chúng ta còn có thêm một tham số bổ sung: safe | unsafe. Việc sử dụng safe đảm bảo rằng cho dù bạn tùy chỉnh position như thế nào, bạn cũng không thể đẩy một phần tử ra bên ngoài màn hình theo cách nội dung đó không cuộn được (hay còn gọi là mất dữ liệu - data loss).

 

align-items

Align items

Giá trị này chỉ định behaviour mặc định của các flex items theo trục chéo trên flex line hiện tại. Bạn có thể nghĩ về nó như là một phiên bản justify-content theo trục chéo cross axis.

.container { 
  align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe; 
}
  • stretch: kéo dài chiều cao để lấp đầy container (tuy nhiên vẫn tuân theo min-width/max-width).
  • flex-start / start: các flex items được sắp xếp về phía đầu trục chéo. Giá trị flex-start áp dụng cho flex-direction trong khi start áp dụng cho hướng ghi (writing-mode direction).
  • flex-end / end: các flex items được sắp xếp về phía cuối trục chéo. Giá trị flex-end áp dụng cho flex-direction trong khi end áp dụng cho hướng ghi (writing-mode direction).
  • center: các flex items được căn giữa theo trục chéo.
  • baseline: các mục được căn chỉnh theo đường cơ sở.

Ngoài ra, tham số safe | unsafe có thể được sử dụng kèm theo để ngăn chặn việc căn chỉnh các phần tử khiến nội dung không truy cập được.

 

align-content

Align content

Thuộc tính này căn chỉnh các flex lines của container khi có khoảng trống bên trong trục chéo (cross axis), tương tự với cách mà justify-content căn chỉnh các flex items theo trục chính (main axis).

Lưu ý: thuộc tính này sẽ vô hiệu khi container của bạn chỉ có duy nhất 1 flex line.

.container { 
  align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe; 
}
  • flex-start / start: các flex items được sắp xếp về phía đầu của container. Giá trị flex-start áp dụng cho flex-direction trong khi start áp dụng cho hướng ghi (writing-mode direction).
  • flex-end / end: các flex items được sắp xếp về phía cuối của container. Giá trị flex-end áp dụng cho flex-direction trong khi end áp dụng cho hướng ghi (writing-mode direction).
  • center: các flex items được phân phối vào chính giữa container.
  • space-between: các flex items được sắp xếp đồng đều, dòng đầu tiên ở sát phía đầu, dòng cuối cùng ở sát phía cuối.
  • space-around: các flex items được sắp xếp đồng đều với khoảng cách bằng nhau giữa mỗi flex line.
  • space-evenly: các flex items được phân phối đồng đều với khoảng cách bằng nhau giữa chúng.
  • stretch (default): các dòng được kéo dài độ cao nhằm chiếm hết không gian giữa chúng.

 

 

Các thuộc tính dành cho children - Flex Items

Flex Items

order

Flex order

Theo mặc định, thứ tự các flex items trùng khớp với thứ tự của chúng trong mã HTML. Tuy nhiên, bạn có thể hoàn toàn tùy chỉnh thứ tự sắp xếp của chúng qua thuộc tính này.

.item { 
  order: 3; /* giá trị mặc định là 0 */ 
}

 

flex-grow

Flex grow

Thuộc tính này giúp xác định khả năng thay đổi kích thước của flex items khi cần thiết. Giá trị hợp lệ ở đây là một số nguyên đóng vai trò như tỉ lệ. Nó sẽ chỉ định lượng không gian mà các flex items có thể đạt đến bên trong container.

Khi tất cả các flex ỉtems được đặt flex-grow là 1, không gian bên trong container sẽ được chia đều cho toàn bộ chúng. Nếu một vài flex item có giá trị bằng 2, thì kích thước của chúng sẽ gấp đôi so với các flex items còn lại (điều này không hoàn toàn đúng nhưng ít nhất hệ thống sẽ cố gắng để đạt được điều đó).

flex-grow được sử dụng khi tổng kích thước các flex items bên trong container của bạn nhỏ hơn kích thước của container, và bạn muốn nội dung bên trong container được lấp đầy.

.item { 
  flex-grow: 1; /* giá trị mặc định là 0 */ 
}

Giá trị nhỏ hơn 0 là không hợp lệ.

 

flex-shrink

Thuộc tính này chỉ định khả năng thu nhỏ kích thước của flex items khi cần thiết.

Ngược lại so với flex-growflex-shrink được sử dụng khi tổng kích thước các flex items lớn hơn kích thước của container, và bạn muốn các flex items co lại cho phù hợp với container.

.item { 
  flex-shrink: 2; /* giá trị mặc định là 0 */ 
}

Giá trị nhỏ hơn 0 là không hợp lệ.

 

flex-basis

Thuộc tính này xác định kích thước mặc định của một phần tử trước khi không gian còn lại được phân phối. Các giá trị hợp lệ bao gồm:

  • number: một đơn vị đo lường xác định (20%5rem100px...).
  • auto: mang ý nghĩa hệ thống sẽ tự động xem xét kích thước (width/height) của flex items (điều này được thực hiện tạm thời cho tới khi không cần nữa).
.item { 
  flex-basis: 100px | 20% | 100rem | ... | auto; /* giá trị mặc định là auto */ 
}

Nếu giá trị được thiết lập về 0, không gian thừa xung quanh nội dung sẽ không được tính vào. Nếu giá trị được thiết lập thành auto, không gian thừa sẽ được phân phối dựa trên giá trị flex-grow của chúng.

 

flex

Đây là cách viết tắt để thiết lập cả 3 thuộc tính flex-growflex-shrink, và flex-basis. Tham số thứ hai (flex-shrink) và thứ ba (flex-basis) là không bắt buộc.

.item { 
  flex: 1; /* flex-grow = 1, flex-shrink = 1, flex-basis = 0 */ 
  flex: 1 1 0; 
}

Giá trị mặc định của thuộc tính này là 0 1 auto.

Thuộc tính này được khuyên dùng hơn là việc thiết lập các thuộc tính con một cách riêng lẻ.

 

align-self

Align self

Bạn có thể hiểu thuộc tính này giống như align-items, nhưng chỉ tác dụng cho một số flex items riêng lẻ.

.item { 
  align-self: auto | flex-start | flex-end | center | baseline | stretch; 
}

Lưu ý rằng các thuộc tính như floatclearvertical-align sẽ không có tác dụng đối với các flex items.

 

Kết luận

Bài viết tới đây là kết thúc rồi. Cá nhân mình cảm nhận flexbox cực kỳ hay và hiệu quả cho việc dàn trang, nhất là với các trang có hỗ trợ mobile view.

Hi vọng thông qua bài viết này, các bạn sẽ nắm vững kiến thức về flexbox hơn. Nếu có câu hỏi gì thì các bạn cứ liên hệ với mình nhé.

 

Liên kết tham khảo

Comments

Mục lục

Bài viết nổi bật

PHP là ngôn ngữ được sử dụng rộng rãi nhất trên thế giới trong lập trình web. Nó cũng bị ghét nhất. Nhưng tại sao nhiều developer lại ghét nó đến vậy? Hôm nay chúng ta hãy cùng tìm hiểu lý do xem chúng có thuyết phục không nhé ^_^
Ở bài viết này mình sẽ hướng dẫn bạn bắt đầu xây dựng một ứng dụng HMVC với Laravel, và tận dụng sức mạnh của Composer khi quản lí modules.
Trong quá trình làm việc với Laravel Eloquent ORM, chắc hẳn các bạn từng thực hiện khá nhiều tác vụ lặp đi lặp lại - mà bạn không hề biết Laravel đã hỗ trợ sẵn. Thông qua vài mẹo và thủ thuật nhỏ trong bài viết này, mình hi vọng sẽ giúp các bạn giảm bớt sự phức tạp khi viết code cũng như bớt nhàm chán khi thực hiện các tác vụ lặp đi lặp lại theo cách thông thường.
Có khá nhiều bạn đã yêu cầu mình một bài viết về Repository Design Pattern. Vậy mục đích của nó là gì? Nó có thực sự cần thiết cho ứng dụng của bạn hay không? Những điểm mạnh, điểm yếu của nó là gì? Chúng ta cùng đi sâu tìm hiểu qua bài viết này nhé.
Như đã được thông báo vào năm 2018, React Native đã và đang được đội ngũ phát triển của Facebook nỗ lực tái kiến trúc nhằm giúp nền tảng này trở nên mạnh mẽ hơn và giải quyết một số vấn đề phổ biến mà các nhà phát triển đã gặp phải trong vài năm qua.

Related posts

Redux là một framework quản lý state dựa trên ý tưởng: tất cả các state của ứng dụng sẽ được lưu xuống một global state và sử dụng các reducer function để tương tác với chúng.
Styled-Components là một thư viện giúp bạn tổ chức và quản lý styles trong các dự án sử dụng React tuân theo đề xuất từ Facebook.
Decorators trong Typescript
484
Các bạn dev nào từng làm Angular chắc sẽ khá quen thuộc với Decorators đúng không? Nhưng bạn thật sự đã hiểu rõ về nó hay chưa? Chúng ta hãy cùng nhau ôn bài một tí nhé ^_^
PHP là ngôn ngữ được sử dụng rộng rãi nhất trên thế giới trong lập trình web. Nó cũng bị ghét nhất. Nhưng tại sao nhiều developer lại ghét nó đến vậy? Hôm nay chúng ta hãy cùng tìm hiểu lý do xem chúng có thuyết phục không nhé ^_^
Là developer, chúng ta luôn tìm cách để tiết kiệm thời gian cho các dự án của mình. Đó là lý do tại sao các thư viện được tạo ra để giảm bớt các khó khăn khi triển khai những thứ lặp đi lặp lại. Với các frontend framework như React, việc chia sẻ chức năng chung cho các dự án khác nhau trở nên dễ dàng hơn bao giờ hết.
Snappy là một thư viện PHP cho phép tạo các thumnails, snapshots và PDF từ URL hoặc trang HTML. Tác giả Barryvdh đã viết thư viện Laravel Snappy giúp việc tích hợp với Laravel dễ dàng hơn.
Bạn có thể sử dụng tính năng kiểm tra kiểu dữ liệu của Typescript để xác định các interface cho các components, nhằm chắc chắn rằng component của bạn chỉ nhận được các thông tin đầu vào chính xác.
Bài viết này cung cấp một cái nhìn tổng quan ngắn gọn về TypeScript, tập trung vào hệ thống kiểu dữ liệu của nó.
Hooks là một tính năng bổ sung mới từ React 16.8 trở đi. Chúng cho phép bạn sử dụng State và các tính năng khác của React mà không cần viết một class.
Giới thiệu series react
326
Một vài kiến thức cơ bản cũng như nâng cao mà mình sẽ tổng hợp lại trong quá trình làm việc cũng như self learning
JWT Tokens là một cách thức lưu trữ thông tin xác thực hiệu quả, nhưng làm cách nào để chúng ta có thể giúp chúng an toàn hơn? Có 2 cách thường dùng để lưu trữ JWT Tokens là LocalStorage và Cookies. Bây giờ chúng ta sẽ bắt đầu "mổ xẻ" các ưu - nhược điểm của mỗi loại nhé.
Như đã được thông báo vào năm 2018, React Native đã và đang được đội ngũ phát triển của Facebook nỗ lực tái kiến trúc nhằm giúp nền tảng này trở nên mạnh mẽ hơn và giải quyết một số vấn đề phổ biến mà các nhà phát triển đã gặp phải trong vài năm qua.

Tin mới nhất

Redux là một framework quản lý state dựa trên ý tưởng: tất cả các state của ứng dụng sẽ được lưu xuống một global state và sử dụng các reducer function để tương tác với chúng.
Styled-Components là một thư viện giúp bạn tổ chức và quản lý styles trong các dự án sử dụng React tuân theo đề xuất từ Facebook.
Decorators trong Typescript
484
Các bạn dev nào từng làm Angular chắc sẽ khá quen thuộc với Decorators đúng không? Nhưng bạn thật sự đã hiểu rõ về nó hay chưa? Chúng ta hãy cùng nhau ôn bài một tí nhé ^_^
PHP là ngôn ngữ được sử dụng rộng rãi nhất trên thế giới trong lập trình web. Nó cũng bị ghét nhất. Nhưng tại sao nhiều developer lại ghét nó đến vậy? Hôm nay chúng ta hãy cùng tìm hiểu lý do xem chúng có thuyết phục không nhé ^_^
Là developer, chúng ta luôn tìm cách để tiết kiệm thời gian cho các dự án của mình. Đó là lý do tại sao các thư viện được tạo ra để giảm bớt các khó khăn khi triển khai những thứ lặp đi lặp lại. Với các frontend framework như React, việc chia sẻ chức năng chung cho các dự án khác nhau trở nên dễ dàng hơn bao giờ hết.
Snappy là một thư viện PHP cho phép tạo các thumnails, snapshots và PDF từ URL hoặc trang HTML. Tác giả Barryvdh đã viết thư viện Laravel Snappy giúp việc tích hợp với Laravel dễ dàng hơn.
IRAC (Issue - Rule - Analysis - Conclusion) là một phương pháp phổ biến và quen thuộc với sinh viên luật và dân luật nói chung. Cá nhân mình thấy phương pháp này khá hay và hoàn toàn có thể áp dụng vào bất cứ công việc hoặc ngành nghề nào.
Bạn có thể sử dụng tính năng kiểm tra kiểu dữ liệu của Typescript để xác định các interface cho các components, nhằm chắc chắn rằng component của bạn chỉ nhận được các thông tin đầu vào chính xác.
Bài viết này cung cấp một cái nhìn tổng quan ngắn gọn về TypeScript, tập trung vào hệ thống kiểu dữ liệu của nó.
Hooks là một tính năng bổ sung mới từ React 16.8 trở đi. Chúng cho phép bạn sử dụng State và các tính năng khác của React mà không cần viết một class.
Giới thiệu series react
326
Một vài kiến thức cơ bản cũng như nâng cao mà mình sẽ tổng hợp lại trong quá trình làm việc cũng như self learning
JWT Tokens là một cách thức lưu trữ thông tin xác thực hiệu quả, nhưng làm cách nào để chúng ta có thể giúp chúng an toàn hơn? Có 2 cách thường dùng để lưu trữ JWT Tokens là LocalStorage và Cookies. Bây giờ chúng ta sẽ bắt đầu "mổ xẻ" các ưu - nhược điểm của mỗi loại nhé.
Redux là một framework quản lý state dựa trên ý tưởng: tất cả các state của ứng dụng sẽ được lưu xuống một global state và sử dụng các reducer function để tương tác với chúng.
Styled-Components là một thư viện giúp bạn tổ chức và quản lý styles trong các dự án sử dụng React tuân theo đề xuất từ Facebook.
Decorators trong Typescript
484
Các bạn dev nào từng làm Angular chắc sẽ khá quen thuộc với Decorators đúng không? Nhưng bạn thật sự đã hiểu rõ về nó hay chưa? Chúng ta hãy cùng nhau ôn bài một tí nhé ^_^
PHP là ngôn ngữ được sử dụng rộng rãi nhất trên thế giới trong lập trình web. Nó cũng bị ghét nhất. Nhưng tại sao nhiều developer lại ghét nó đến vậy? Hôm nay chúng ta hãy cùng tìm hiểu lý do xem chúng có thuyết phục không nhé ^_^
Là developer, chúng ta luôn tìm cách để tiết kiệm thời gian cho các dự án của mình. Đó là lý do tại sao các thư viện được tạo ra để giảm bớt các khó khăn khi triển khai những thứ lặp đi lặp lại. Với các frontend framework như React, việc chia sẻ chức năng chung cho các dự án khác nhau trở nên dễ dàng hơn bao giờ hết.