Làm thế nào để làm cho các mục flexbox có cùng kích thước?


186

Tôi muốn sử dụng flexbox có một số mục có cùng chiều rộng. Tôi đã nhận thấy rằng flexbox phân phối không gian xung quanh đồng đều, thay vì chính không gian đó.

Ví dụ:

.header {
  display: flex;
}

.item {
  flex-grow: 1;
  text-align: center;
  border: 1px solid black;
}
<div class="header">
  <div class="item">asdfasdfasdfasdfasdfasdf</div>
  <div class="item">z</div>
</div>

Mục đầu tiên lớn hơn nhiều so với mục thứ hai. Nếu tôi có 3 mục, 4 mục hoặc n mục, tôi muốn tất cả chúng xuất hiện trên cùng một dòng với một khoảng trống bằng nhau cho mỗi mục.

Có ý kiến ​​gì không?

http://codepen.io/anon/pen/gbJBqM

Câu trả lời:


287

Đặt chúng sao cho chúng flex-basis0(để tất cả các phần tử có cùng điểm bắt đầu) và cho phép chúng phát triển:

flex: 1 1 0px

IDE hoặc kẻ nói dối của bạn có thể đề cập đến điều đó the unit of measure 'px' is redundant. Nếu bạn bỏ nó đi (như flex: 1 1 0:), IE sẽ không hiển thị chính xác điều này. Vì vậy, pxcần phải hỗ trợ Internet Explorer, như được đề cập trong các bình luận của @fabb;


65
Cần lưu ý rằng flexbất động sản là một tài sản viết tắt cho flex-grow, flex-shrinkflex-basistài sản. Bạn nên sử dụng tốc ký trên các thuộc tính riêng lẻ vì tốc ký đặt lại chính xác mọi thành phần không xác định để phù hợp với việc sử dụng chung. Giá trị ban đầu là 0 1 auto.
j08691

3
lưu ý rằng IE11 bỏ qua các giá trị cơ sở flex đơn vị: github.com/philipwalton/flexbugs#flexorms-4
fabb

9
Tôi đã phải thêm min-width: 0để đạt được bằng cách sử dụng các phần tử con với văn bản tràn. Xem css-tricks.com/flexbox-truncated-text
Iwazaru

77

Bạn có thể thêm flex-basis: 100%để đạt được điều này.

Ví dụ cập nhật

.header {
  display: flex;
}

.item {
  flex-basis: 100%;
  text-align: center;
  border: 1px solid black;
}

Đối với những gì nó có giá trị, bạn cũng có thể sử dụng flex: 1cho kết quả tương tự.

Tốc ký flex: 1tương tự như flex: 1 1 0, tương đương với:

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
  text-align: center;
  border: 1px solid black;
}

1
Điều này LAF không đúng. Giá trị flex mặc định là flex: 0 1 auto. Có nghĩa là thiết lập flex: 1sẽ dẫn đến flex: 1 1 auto. Điều này sẽ không hoạt động. Câu trả lời đúng flex: 1 1 0như đã nêu ở trên bởi Adam
r.sendecky

17
@ r.sendecky Không, bạn là người không chính xác. Như tôi đã nói trong câu trả lời của mình, tốc ký flex: 1kết quả flex: 1 1 0 không flex: 1 1 auto giống như bạn đang yêu cầu. Hãy xem thông số kỹ thuật chính thức của W3 trong phần 'tốc ký flex' : khi flex-basis"được bỏ qua từ tốc ký flex, giá trị được chỉ định là 0", không phải auto. Cảm ơn các downvote ngẫu nhiên.
Josh Crozier

2
@ r.sendecky - Ngoài ra, hãy xem ví dụ này tôi đã tạo để hình dung các biến thể.
Josh Crozier

1
Mate, tôi không bỏ phiếu ngẫu nhiên. Tôi kiểm tra trước khi viết. Và tôi đã kiểm tra nó. Câu trả lời của bạn không hoạt động - đơn giản như vậy. Tôi đã có chính xác cùng một vấn đề cách đây không lâu với flex: 1flex-direction: column. Chiều cao của trẻ em không giống nhau khi các yếu tố khác được đặt trong trẻ em. Điều duy nhất cố định nó là cài đặt flex: 1 1 0. Nó vẫn đứng ngày hôm nay với crom 55.0.2883.87
r.sendecky

4
@JoshCrozier xác nhận rằng flex: 1có hành vi tương tự flex: 1 1 0flex: 0 1 autocó hành vi khác nhau.
Ivan Durst

66

Bạn cần thêm width: 0để làm cho các cột bằng nhau nếu nội dung của các mục làm cho nó phát triển lớn hơn.

.item {
  flex: 1 1 0;
  width: 0;
}

5
Điều này dường như là cần thiết nếu nội dung của .itemnó khiến nó phát triển rộng hơn .itemtự nhiên.
Bungle

1
Tôi nghĩ bạn có ý flex: 1 1 0;, thay vìflex-grow: 1 1 0;
Súp gà

3
fyi, liên kết bị hỏng
Bobby Jack

thiết lập flex-basisđể 0phục vụ cùng một mục đích như thiết lập widthđến 0.
Stephen

Trong trường hợp sử dụng của tôi, tôi đã gói các biểu đồ tự động điều chỉnh theo kích thước và chiều rộng 0 của cha mẹ chúng là cần thiết để chúng hoạt động. Tôi không chắc chắn làm thế nào họ xác định được chiều rộng phù hợp, nhưng cơ sở flex chắc chắn không hoạt động trên chrome 72 (phát hành tháng 1 năm 2019).
Andy Groff

12

Câu trả lời được chấp nhận bởi Adam ( flex: 1 1 0) hoạt động hoàn hảo cho các thùng chứa flexbox có chiều rộng cố định hoặc được xác định bởi tổ tiên. Các tình huống mà bạn muốn trẻ em phù hợp với container.

Tuy nhiên, bạn có thể có một tình huống mà bạn muốn hộp đựng phù hợp với trẻ em, với những đứa trẻ có kích thước tương đương dựa trên đứa trẻ lớn nhất. Bạn có thể làm cho một hộp chứa flexbox phù hợp với trẻ em của nó bằng cách:

  • thiết lập position: absolutevà không thiết lập widthhoặc right, hoặc
  • đặt nó bên trong một bọc display: inline-block

Đối với các hộp đựng flexbox như vậy, câu trả lời được chấp nhận KHÔNG hoạt động, trẻ em không có kích thước bằng nhau. Tôi cho rằng đây là một hạn chế của flexbox, vì nó hoạt động giống nhau trong Chrome, Firefox và Safari.

Giải pháp là sử dụng lưới thay vì flexbox.

Bản trình diễn: https://codepen.io/brettdonald/pen/oRpORG

<p>Normal scenario — flexbox where the children adjust to fit the container — and the children are made equal size by setting {flex: 1 1 0}</p>

<div id="div0">
  <div>
    Flexbox
  </div>
  <div>
    Width determined by viewport
  </div>
  <div>
    All child elements are equal size with {flex: 1 1 0}
  </div>
</div>

<p>Now we want to have the container fit the children, but still have the children all equally sized, based on the largest child. We can see that {flex: 1 1 0} has no effect.</p>

<div class="wrap-inline-block">
<div id="div1">
  <div>
    Flexbox
  </div>
  <div>
    Inside inline-block
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
</div>

<div id="div2">
  <div>
    Flexbox
  </div>
  <div>
    Absolutely positioned
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>

<br><br><br><br><br><br>
<p>So let's try a grid instead. Aha! That's what we want!</p>

<div class="wrap-inline-block">
<div id="div3">
  <div>
    Grid
  </div>
  <div>
    Inside inline-block
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
</div>

<div id="div4">
  <div>
    Grid
  </div>
  <div>
    Absolutely positioned
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
body {
  margin: 1em;
}

.wrap-inline-block {
  display: inline-block;
}

#div0, #div1, #div2, #div3, #div4 {
  border: 1px solid #888;
  padding: 0.5em;
  text-align: center;
  white-space: nowrap;
}

#div2, #div4 {
  position: absolute;
  left: 1em;
}

#div0>*, #div1>*, #div2>*, #div3>*, #div4>* {
  margin: 0.5em;
  color: white;
  background-color: navy;
  padding: 0.5em;
}

#div0, #div1, #div2 {
  display: flex;
}

#div0>*, #div1>*, #div2>* {
  flex: 1 1 0;
}

#div0 {
  margin-bottom: 1em;
}

#div2 {
  top: 15.5em;
}

#div3, #div4 {
  display: grid;
  grid-template-columns: repeat(3,1fr);
}

#div4 {
  top: 28.5em;
}

0

Tôi không có chuyên gia về flex nhưng tôi đã đạt được điều đó bằng cách đặt cơ sở lên 50% cho hai mục tôi đang xử lý. Tăng lên 1 và co lại thành 0.

Kiểu dáng nội tuyến: flex: '1 0 50%',

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.