justify-content và align-items, mỗi thứ một câu
Trong một flex container, justify-content dàn các item dọc theo trục chính (main axis, theo chiều của hàng) còn align-items xếp chúng thẳng hàng trên trục phụ (cross axis, lên xuống trong hàng). Cả hai đều đặt trên container:
Hộp được căn giữa theo cả hai chiều: cách đều mép đầu và mép cuối, cách đều cạnh trên và cạnh dưới. Bỏ height: 140px đi thì align-items: center không còn gì để làm, vì container co lại bằng đúng chiều cao của item.
Mọi giá trị của justify-content, có số đo
Mỗi hàng dưới đây là cùng ba item với một giá trị justify-content khác nhau. Các con số trong nhãn phía trên mỗi hàng là khoảng trống trình duyệt để lại: trước item đầu, giữa các item và sau item cuối.
Container rộng 420px và các item chiếm 180px, nên còn 240px không gian trống. Phần đó đi đâu:
| Giá trị | Không gian trống nằm ở | Khoảng trống trong demo |
|---|---|---|
flex-start (và start) | toàn bộ sau các item | 0 / 0 / 0 / 240 |
center | nửa trước, nửa sau | 120 / 0 / 0 / 120 |
flex-end (và end) | toàn bộ trước các item | 240 / 0 / 0 / 0 |
space-between | chỉ giữa các item | 0 / 120 / 120 / 0 |
space-around | bằng nhau ở hai bên mỗi item, nên hai mép nhận một nửa | 40 / 80 / 80 / 40 |
space-evenly | mọi khoảng bằng nhau, kể cả hai mép | 60 / 60 / 60 / 60 |
flex-start đi theo hướng flex còn start đi theo hướng viết. Chúng chỉ khác nhau với row-reverse hoặc column-reverse, khi flex-start nằm ở đầu bị đảo ngược.
Mọi giá trị của align-items
align-items hoạt động theo chiều vuông góc với hàng. Các item dưới đây có chiều cao khác nhau để bạn thấy mỗi giá trị xử lý chúng ra sao:
| Giá trị | Điều xảy ra trên trục phụ |
|---|---|
stretch (mặc định) | Item không đặt chiều cao sẽ giãn ra lấp đầy container |
flex-start (và start) | Item nằm ở trên cùng, giữ chiều cao riêng |
center | Item được căn giữa, giữ chiều cao riêng |
flex-end (và end) | Item nằm ở dưới cùng |
baseline | Item dịch chuyển để dòng chữ đầu tiên của chúng chung một đường cơ sở |
Trong hộp baseline, ba nhãn "Ag" nằm trên cùng một dòng dù nhãn đầu to hơn và nhãn thứ hai có padding phía trên. Đó là giá trị dành cho một hàng trộn tiêu đề lớn với chữ nhỏ, hoặc một nhãn với một ô nhập.
Bấm để căn chỉnh
Bấm vào bất kỳ ô nào của lưới 3 x 3. Hộp sẽ di chuyển đến đó, và CSS đưa nó đến đó được in ra bên dưới:
Các hàng của bộ chọn thay đổi align-items còn các cột thay đổi justify-content. Ô ở giữa chính là bài toán kinh điển "căn giữa một div".
Trong một cột, hai thuộc tính đổi vai
justify-content luôn đi theo trục chính. Với flex-direction: column, trục chính là chiều dọc, nên justify-content di chuyển item lên xuống còn align-items di chuyển chúng theo chiều ngang:
Nếu bạn nhầm hai thuộc tính, hãy đổi chỗ chúng thay vì viết lại bố cục.
align-self và margin auto: chỉ một item
align-self trên một item ghi đè align-items cho riêng item đó. Flexbox không có justify-self; để di chuyển một item dọc theo trục chính, hãy cho nó một margin auto, thứ chiếm toàn bộ không gian trống ở phía đó:
Item màu xanh lá tự xuống dưới cùng, còn item màu hổ phách bị đẩy về tận cuối hàng trong khi các item khác vẫn ở đầu.
Khi có nhiều dòng: align-content
align-items căn các item bên trong dòng của chúng. Khi container xuống thành nhiều dòng, align-content phân bố khoảng cách giữa chính các dòng, và nhận cùng các giá trị như justify-content. Nó không có tác dụng trong container nowrap, vì dòng duy nhất luôn lấp đầy chiều cao của container. Trang flex-wrap minh họa điều này.
Lỗi thường gặp
- Nhầm lẫn hai trục.
justify-contentlà hướng các item nối tiếp nhau,align-itemslà chiều vuông góc với nó. Trong một cột, căn giữa theo chiều dọc làjustify-content: center. - Không có không gian trống. Một item có
flex: 1chiếm hết không gian, nênjustify-contentkhông còn gì để phân bố. Điều tương tự xảy ra khi container làinline-flexvà rộng đúng bằng các item. - Không có chiều cao cho
align-items. Một container cao bằng nội dung không còn chỗ để căn chỉnh. Đặtheighthoặcmin-height. - Tìm
justify-selftrong flexbox. Thuộc tính này bị bỏ qua ở đó. Dùngmargin-inline-start: auto(hoặcmargin-left: auto) trên item. align-items: stretchmà không giãn. Item cóheightriêng sẽ giữ nguyên nó. Bỏ height đi (dùngmin-heightnếu cần chiều cao tối thiểu).- Đặt các thuộc tính trên item. Cả hai đều đặt trên flex container. Chỉ
align-selfmới đặt trên item.
Câu hỏi thường gặp
justify-content và align-items khác nhau thế nào?
justify-content phân bố các item dọc theo trục chính, tức hướng chúng nối tiếp nhau (ngang với flex-direction: row). align-items đặt vị trí của chúng dọc theo trục phụ (dọc khi là hàng). Trong một cột, hai trục đổi chỗ: justify-content chuyển sang theo chiều dọc.
space-between, space-around và space-evenly khác nhau thế nào?
space-between không để khoảng trống trước item đầu và sau item cuối, phần còn lại chia đều giữa các item. space-around cho mỗi item khoảng trống bằng nhau ở hai bên, nên hai mép chỉ nhận nửa khoảng. space-evenly làm mọi khoảng trống bằng nhau, kể cả hai mép.
Vì sao justify-content không hoạt động?
Thường là vì không còn không gian trống để phân bố: một item có flex-grow hoặc flex: 1, hoặc container chỉ rộng bằng các item (ví dụ display: inline-flex hoặc container được float). Kiểm tra thêm display: flex có nằm trên phần tử cha chứ không phải trên các item.
Vì sao align-items center không căn giữa theo chiều dọc?
Có lẽ container cao đúng bằng nội dung của nó, nên không còn chỗ nào để căn giữa. Hãy cho flex container một chiều cao hoặc min-height, các item sẽ di chuyển vào giữa.
align-self dùng để làm gì?
align-self ghi đè align-items của container cho một item. Ví dụ align-self: flex-end trên một phần tử con chỉ đưa phần tử đó về cuối trục phụ, còn các item khác vẫn ở chỗ align-items đã đặt.
Flexbox có justify-self không?
Không. Flexbox bỏ qua justify-self, vì trục chính được mọi item dùng chung. Để đẩy một item dọc theo trục chính, dùng margin auto, chẳng hạn margin-inline-start: auto. justify-self hoạt động trong grid.