12/08/2018, 17:13

Dàn trang bằng css flexbox

Trong CSS, nếu chúng ta muốn dàn layout của trang thì sẽ sử dụng các thuộc tính float và kỹ thuật clear float để chia cột website như ý muốn. Hoặc muốn thuận tiện hơn thì sử dụng các CSS Grid Framework để tiết kiệm thời gian. Nhưng đôi khi việc chia cột đôi khi rất tốn thời gian với kỹ thuật truyền ...

Trong CSS, nếu chúng ta muốn dàn layout của trang thì sẽ sử dụng các thuộc tính float và kỹ thuật clear float để chia cột website như ý muốn. Hoặc muốn thuận tiện hơn thì sử dụng các CSS Grid Framework để tiết kiệm thời gian. Nhưng đôi khi việc chia cột đôi khi rất tốn thời gian với kỹ thuật truyền thống này, còn dùng framework thì lại khiến website chúng ta có thêm nhiều đoạn CSS không cần thiết. Hoặc là nếu chúng ta dàn trang trên kỹ thuật thông thường hiện nay thì ở mỗi thiết bị khác nhau mình phải cân đối lại kích thước khá phức tạp.

Ta có thể giải quyết một số vấn đề gặp phải khi làm bằng những cách cũ với flexbox của CSS3.

Flexbox là gì?

Flexbox là một layout mode mà nó sẽ tự cân đối kích thước của các phần tử bên trong để hiển thị trên mọi thiết bị. 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.

Hiện nay, theo lời khuyên từ Mozilla thì chúng ta sử dụng Flexbox để thiết lập bố cục trong phạm vi nhỏ (ví dụ như những khung trong website) và khi thiết lập bố cục ở phạm vi lớn hơn (như chia cột website) thì vẫn nên sử dụng kiểu thông thường là dàn trang theo dạng lưới (grid layout).

Cấu trúc của flexbox

sơ đồ cấu trúc Flexbox từ Mozilla Developer Network.

Hai thành phần chính trong một flexbox gồm có container và item:

  • Container: thành phần bao ngoài chứa các item bên trong, cách hiển thị của các item bên trong sẽ dựa trên thiết lập của container này.
  • Item: thành phần con nằm trong container, ở đây có thể thiết lập các thông số về kích thước cũng như thứ tự hiển thị....

Ngoài ra còn có một số thành phần khác như:

  • main start, main end: main start là điểm bắt đầu của container và main end là điểm kết thúc. Các item bên trong container sẽ được hiển thị từ main start đến main end. Chiều vuông góc của nó là cross start, "cross end" có ý nghĩa tương tự và luôn vuông góc với main start và main end.
  • main axis: trục điều hướng các item. Main axis là trục dọc thì các item hiển thị lần lượt theo chiều dọc của container, tương tự với chiều ngang. Ta có thể sử dụng thuộc tính flex-direction để thay đổi chiều của trục main axis. Tương tự với cross start và cross end, cross axis luôn vuông góc với main axis.
  • main size: kích thước của mỗi item (chiều dài hoặc chiều rộng) phụ thuộc vào main axis.
  • cross size: kích thước của mỗi item (chiều dài hoặc chiều rộng) dựa theo trục cross axis.

Flexbox example

Ta sẽ sử dụng các thành phần như ví dụ sau để hiểu hơn một số thuộc tính của flexbox:

//html
<div class="container">
  <div class="item item1">Item 1</div>
  <div class="item item2">Item 2</div>
  <div class="item item3">Item 3</div>
  <div class="item item4">Item 4</div>
</div>

//css
.container {
  background: red;
  max-awidth: 960px;
  max-height: 1000px;
  margin: 0 auto;
  padding: 5px;
}
.item {
  background: blue;
  margin: 5px;
  color: white;
  height: 50px;
  text-align: center;
  line-height: 50px;
  awidth: 50px;
}

Ta sẽ bắt đầu set flexbox cho container

.container {
  display: flex;
}

Sẽ thấy ngay các item được hiển thị theo chiều ngang mặc định của main axis

flex-direction

Muốn đổi hướng của trục chỉ cần thêm thuộc tính flex-direction vào container

flex-direction: row | column | row-reverse | column-reverse
  • row: hiển thị theo hàng
  • column: hiển thị theo cột
  • row-reverse: hiển thị theo hàng nhưng thứ tự các item bị đảo ngược
  • column-reverse: hiển thị theo cột nhưng thứ tự các item bị đảo ngược

flex-wrap

Bây giờ ta thử thêm chiều rộng cho từng item xem chúng sẽ hiển thị thế nào với flexbox

.item {
  awidth: 1000px;
}

Ở đây mình set chiều rộng của 1 item thậm chí còn lớn hơn chiều rộng của container, nhưng các item vẫn hiển thị vừa vào trong container và chiều rộng tự thu hẹp hợp lý để hiển theo theo trục main axis. Lý do là mặc định, flexbox tự căn chỉnh các phần tử hiển thị đều nhau theo trục main axis của nó dựa theo kích của container. Vì vậy cho dù bạn có chỉnh chiều rộng vượt quá giới hạn của nó thì nó vẫn không bị nhảy lung tung.

Nếu muốn thay đổi kích thước của item lớn hơn là kích thước mặc định mà flexbox định nghĩa ta có thể sử dụng flex-wrap, mặc định của nó là no-wrap

flex-wrap: wrap

Lúc này ta có thể thay đổi kích thước của item, tuy nhiên nó vẫn không thể vượt ra ngoài container.

order

Ta có thể dùng để thay đổi thử tự hiển thị các item theo trục main axis, Mặc định thứ tự sắp xếp sẽ bắt đầu từ bên trái qua phải, từ trên xuống dưới.

.item1 {
  order: 4;
}
.item2 {
  order: 3;
}
.item3 {
  order: 1;
}
.item4 {
  order: 2;
}

flex-grow

Khi thiết lập flex-grow cho 1 phần tử là 1, nó sẽ lấy phần trống còn lại của container để đắp vào. Nếu thiết lập flex-grow cho phần tử khác là 2 thì nó sẽ lấy phần dư của container gấp đôi của flex-grow: 1

.item2 {
  flex-grow: 1;
}
.item2 {
  flex-grow: 2;
}

flex-shrink

Mặc định tất cả các item đều có flex-shrink: 1. Điều này có nghĩa khi ta thu nhỏ trình duyệt lại, các phần tử đều co lại bằng nhau. Bạn có thể thay đổi sự co lại của các item bằng cách thiết lập thông số flex-shrink

.item3 {
  flex-shrink: 2;
}

flex-basis

Sử dụng nếu bạn muốn gán một kích thước nhất định cho item, có thể dùng giá trị tuyệt đối hay tương đối (phụ thuộc kích thước của container)

.item3 {
  flex-basis: 500px;
}

justify-content

Mặc định các item được hiển thị đều từ main start đến main end, tuy nhiên nếu container vẫn còn khoảng trống thì ta có thể dùng thuộc tính justify-content để điều chỉnh lại vị trí bắt đầu của các item.

.container {
  display: flex;
  justify-content: flex-start | flex-end | center | space-between | space-around
}

Tổng kết

Flexbox có thể nói là khá dễ tiếp cận và có thể thay thế cho cách dùng float thông thường để dàn trang. Để có thể làm việc một cách thuận lợi nhất, kết hợp flexbox cho những component nhỏ và các css grid framework cho toàn cục.

0