Cách thức hoạt động của Flexbox

Đăng bởi Neo trong mục Hướng dẫn vào 04 tháng 2, 2017 | Comments

Bài gốc: How Flexbox works — explained with big, colorful, animated gifs, mình xem thấy tác giả minh họa khá dễ hiểu nên dịch lại.

Flexbox hứa hẹn sẽ giải quyết nhiều vấn đề hiện đang tồn tại trong CSS thuần (ví dụ như căn chỉnh chiều dọc). Nhưng để có thể làm chủ và sử dụng được flexbox thì lại là việc không hề dễ dàng.

Nguyên tắc cơ bản của Flexbox là làm cho việc dàn trang linh hoạt và trực quan hơn. Để thực hiện được điều này, các thành phần bao ngoài (containers) được tự quyết định cách phân bố các phần tử con (items) – bao gồm cả kích thước và khoảng cách giữa chúng.

Trong bài viết này, chúng ta sẽ nghiên cứu 5 thuộc tính nổi trội nhất của Flexbox, khám phá chức năng cũng như cách sử dụng chúng và kết quả đạt được.

Thuộc tính #1: Display: Flex

Hãy xem ví dụ trang web dưới đây:

Display flex

Có 4 thẻ divs kích cỡ khách nhau được đánh dấu với các màu khác nhau đặt trong thẻ div container màu xám. Mặc định mỗi thẻ div sẽ có thuộc tính là display: block. Mỗi ô vuông vì vậy sẽ chiếm hết bề ngang của mỗi dòng.

Để bắt đầu với Flexbox, bạn cần đưa container của bạn về dạng của flex container như sau:

#container {
  display: flex;
}

Display flex

Chưa có thay đổi gì ngoài việc các thẻ div hiển thị trên cùng một dòng. Tuy nhiên đây lại là một sự thay đổi rất đáng kể. Và chúng ta gọi nó là một flex context.

Bây giờ bạn có thể bắt đầu định vị trí cho chúng mà không gặp nhiều khó khăn như khi sử dụng CSS thông thường

Thuộc tính #2: Flex Direction

Một Flexbox container có hai trục: một trục chính (main axis) và một trục dọc vuông góc với trục chính (cross axis) mặc định hiển thị như dưới đây:

flex axes

Mặc định, các items được sắp xếp theo hướng của trục chính, từ trái qua phải. Đây là lí do tại sao các ô vuông hiển thị trên cùng một dòng khi bạn sử dụng display: flex.

Tuy nhiên, bạn có thể thay đổi trục chính bằng thuộc tính flex-direction.

#container {
  display: flex;
  flex-direction: column;
}

flex direction

Có một sự khác biệt quan trọng tạo ra ở đây: flex-direction: column không sắp xếp các ô vuông trên trục dọc (across axis) thay vì trục chính (main axis). Mà là  tự trục chính thay đổi, xoay từ ngang thành dọc.

Bạn có thể sắp xếp flex-direction theo một số cách khác như: row-reverse (hiển thị theo hàng nhưng đổi ngược vị trí các items) và column-reverse (hiển thị theo cột nhưng đổi ngược vị trí các items)

row-reverse và column-reverse

Thuộc tính #3: Justify Content

justify-content sắp xếp các items theo theo trục chính.

Chúng ta sẽ nghiên cứu chi tiết hơn về sự khác nhau giữa trục chính và trục vuông góc với nó. Trước hết, hãy quay lại với flex-direction: row.

#container {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

Với thuộc tính justify-content , bạn có 5 giá trị tùy ý sử dụng:

  1. Flex-start
  2. Flex-end
  3. Center
  4. Space-between
  5. Space-around

justify-content

Sự khác nhau giữa space-aroundspace-between hơi khó để nhận ra. 

Với space-between, các ô vuông sẽ được căn cách đều nhau, không bao gồm khoảng cách giữa ô vuông đầu và cuối với container.

Trong khi đó, với space-around, các ô vuông khoảng được căn cách đều nhau ở cả hai bên. Có nghĩa là khoảng cách giữa ô vuông ngoài cùng phía đầu và cuối với container sẽ bằng một nửa khoảng cách giữa các ô vuông với nhau (Giả sử mỗi ô vuông đều có một giá trị căn lề bằng nhau và không bị ghi đè, vì vậy khoảng cách giữa 2 ô vuông sẽ gấp đôi).

Chú ý: Hãy nhớ rằng thuộc tính justify-content hoạt động theo trục chính, và flex-direction làm thay đổi trục chính. Đây là điều quan trọng nhất để bạn chuyển sang phần tiếp theo

Thuộc tính #4: Align Items

Nếu như bạn đã nắm được thuộc tính justify-content thì bạn sẽ không gặp khó khăn với thuộc tính align-items

Trong khi thuộc tính justify-content hoạt động theo trục chính, thuộc tính align-items lại áp dụng đối với trục dọc (cross axis).

flex axes

Hãy thiết lập lại flex-direction: row để hai trục hiển thị như hình trên.

Tiếp theo, chúng ta hãy tìm hiểu về các giá trị của thuộc tính align-items

  1. flex-start
  2. flex-end
  3. center
  4. stretch
  5. baseline

3 giá trị đầu tiên giống với giá trị của thuộc tính justify-content. Tuy nhiên, 2 giá trị sau thì có đôi chút khác biệt.

Với giá trị stretch, các items sẽ tự kéo chiều cao để vừa khít với container

Với baseline, các item sẽ được xếp theo phần đáy của thẻ <p> bên trong

align items

Chú ý: Đối với giá trị align-items: stretch, chiều cao của các ô vuông đã được đặt height: auto để tránh bị ghi đè bởi thuộc tính chiều cao.

Với giá trị baseline, hãy cẩn thận nếu bạn bỏ thẻ <p>, các ô vuông sẽ được căn lề dưới như hình sau:

align items baseline

Để minh họa rõ hơn cho trục chính và trục vuông góc với nó, hãy kết hợp thuộc tính justify-content với thuộc tính align-items và xem sự khác biệt giữa 2 giá trị center của flex-direction

align items

Với row, các ô vuông hiển thị ngang theo trục chính. Với column, các ô vuông hiển thị dọc theo trục dọc.

Các ô vuông được căn giữa cả theo trục ngang và dọc trong 2 trường hợp, cả 2 trường hợp đều ko thay đổi

Thuộc tính #5: Align Self

Thuộc tính align-self cho phép bạn sắp xếp một item cụ thể.

Nó sẽ đè lên thuộc tính align-item của 1 ô vuông (item). Tất cả thuộc tính đều như nhau, bởi vì mặc định nó là auto, nên các ô vuông sẽ theo thuộc tính align-items của container bao nó.

#container {
  align-items: flex-start;
}
.square#one {
  align-self: center;
}
// Chỉ ô vuông #one được căn giữa.

Hãy xem kết quả. Đặt thuộc tính align-self cho 2 ô vuông, và thuộc tính align-items: center và  flex-direction: row với các ô vuông còn lại.

align self

Lời kết

Mặc dù chỉ là những tìm hiểu cơ bản về Flexbox, tôi tin những điều này cũng cung cấp cho bạn những kiến thức để dàn trang một cách cơ bản nhất cũng như sắp xếp nội dung chính bài viết của bạn.

Cảm ơn vì đã đọc!

Bạn có thích bài viết này?

Neo's picture

Neo

Nhìn mặt trời từ năm 1984 nhưng tới tận 2002 mới được thấy cái máy tính đầu tiên của mình. Đầu năm 2007 thì quyết định theo cái nghề cao quý là thiết kế web Big Grin. Hiện mình đang sống tại Hà Nội. Sở thích: làm website và giúp đỡ mọi người phát triển website theo chiều hướng tốt đẹp hơn.

Trang chủ - Twitter