ChatGPT解决这个技术问题 Extra ChatGPT

How to make flexbox items the same size?

I want to use flexbox that has some number of items that are all the same width. I've noticed that flexbox distributes the space around evenly, rather than the space itself.

For example:

.header { display: flex; } .item { flex-grow: 1; text-align: center; border: 1px solid black; }

asdfasdfasdfasdfasdfasdf
z

The first item is a lot bigger than the second. If I have 3 items, 4 items, or n items, I want them all to appear on the same line with an equal amount of space per item.

Any ideas?

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


s
s.meijer

Set them so that their flex-basis is 0 (so all elements have the same starting point), and allow them to grow:

flex: 1 1 0px

Your IDE or linter might mention that the unit of measure 'px' is redundant. If you leave it out (like: flex: 1 1 0), IE will not render this correctly. So the px is required to support Internet Explorer, as mentioned in the comments by @fabb;


It should be noted that the flex property is a shorthand property for the flex-grow, flex-shrink and flex-basis properties. It's recommended to use the shorthand over the individual properties as the shorthand correctly resets any unspecified components to accommodate common uses. The initial value is 0 1 auto.
note that IE11 ignores unitless flex-basis values: github.com/philipwalton/flexbugs#flexbug-4
I had to add min-width: 0 to achieve using child elements with overflowing text. See css-tricks.com/flexbox-truncated-text
I just want to mention that the Internet Explorer (IE) should be ignored. This is an obsolete browser like e.g. Netscape Navigator. The IE was officially replaced by Microsoft Edge. The latest version also runs on Chromium (like Chrome and other modern browsers.) We as web developers should no longer support IE. It is your responsibility to get rid of this crutch. :) Never talk about IE again.
This does not seem to work if some of the items contain padding. Removing the padding makes all the child elements the same size. Any suggestions to avoid removing padding?
J
Jason Song

You need to add width: 0 to make columns equal if contents of the items make it grow bigger.

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

Detail: flex: 1 1 0 is the same as flex-grow: 1; flex-shrink: 1; flex-basis: 0; and if the parent container can not provide enough space for the native-size added together of every item (no space to grow), we need to make the width: 0 to give every item the same start point to grow.


This appears to be necessary if the contents of .item cause it to grow wider than .item would naturally be.
I think you mean flex: 1 1 0;, instead of flex-grow: 1 1 0;
fyi, link is broken
This should be the accpeted answer !
width: 0 makes it work for me. No idea why other answers above didn't make it
H
Håvard Geithus

You could add flex-basis: 100% to achieve this.

Updated Example

.header {
  display: flex;
}

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

For what it's worth, you could also use flex: 1 for the same results as well.

The shorthand of flex: 1 is the same as flex: 1 1 0, which is equivalent to:

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

This is not correct. The default flex value is flex: 0 1 auto. Which means setting flex: 1 will result in flex: 1 1 auto. This will not work. The correct answer is flex: 1 1 0 as stated above by Adam
@r.sendecky No, you are the one who is incorrect. As I stated in my answer, the shorthand of flex: 1 results in flex: 1 1 0 not flex: 1 1 auto like you are claiming. Take a look at the official W3 specification under the 'flex shorthand' section: when flex-basis is "omitted from the flex shorthand, its specified value is 0", not auto. Thanks for the random downvote.
@r.sendecky - Also, take a look at this example I created to visualize the variations.
Mate, I don't do random down-vote. I test before I write. And I did test it. Your answer does not work - simple as that. I had exactly the same issue not long ago with flex: 1 and flex-direction: column. The children height was not the same when other elements are placed within children. The only thing that fixed it was setting flex: 1 1 0. It still stand today with chromium 55.0.2883.87
@JoshCrozier confirmed that flex: 1 has the same behavior as flex: 1 1 0, and flex: 0 1 auto has different behavior.
B
Brett Donald

The accepted answer by Adam (flex: 1 1 0) works perfectly for flexbox containers whose width is either fixed, or determined by an ancestor. Situations where you want the children to fit the container.

However, you may have a situation where you want the container to fit the children, with the children equally sized based on the largest child. You can make a flexbox container fit its children by either:

setting position: absolute and not setting width or right, or

place it inside a wrapper with display: inline-block

For such flexbox containers, the accepted answer does NOT work, the children are not sized equally. I presume that this is a limitation of flexbox, since it behaves the same in Chrome, Firefox and Safari.

The solution is to use a grid instead of a flexbox.

When you run this snippet, make sure to click on full page to see the effect properly.

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; }

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

Flexbox
Width determined by viewport
All child elements are equal size with {flex: 1 1 0}

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.

Flexbox
Inside inline-block
We want all children to be the size of this text
Flexbox
Absolutely positioned
We want all children to be the size of this text






So let's try a grid instead. Aha! That's what we want!

Grid
Inside inline-block
We want all children to be the size of this text
Grid
Absolutely positioned
We want all children to be the size of this text


Is there a way to get the same effect without hardcoding the number of children in css?
@Davorin grid-template-columns: repeat(auto-fill, minmax(100px, auto)); More details at css-tricks.com/…
S
Steve

Im no expert with flex but I got there by setting the basis to 50% for the two items i was dealing with. Grow to 1 and shrink to 0.

Inline styling: flex: '1 0 50%',


A
Andrew

None of these answers solved my problem, which was that the items weren't the same width in my makeshift flexbox table when it was shrunk to a width too small.

The solution for me was simply to put overflow: hidden; on the flex-grow: 1; cells.


Or alternatively, you could use @Josh_Crozier's answer and conditionally set flex-wrap: wrap; when the browser window is below a certain width. This will cause the items to wrap and take up 100% of the parent width.
i
isherwood

None of these solutions worked for me, so I thought I'd share what did.

.header { display: flex; } .item { width: 100%; } /* Demo styles, for aesthetics. */ .demo { margin: 3rem; } .demo .item { text-align: center; padding: 3rem; background-color: #eee; margin: 0 1.5rem; }

1
2
3
1
2
1
2
3
4
5


Some explanation would be great. A code dump isn't an ideal answer. Please see How to Answer.
H
Hyzyr

This will work even if you wrapping items, like a Grid, but not so simple you should show where it will wrap in media queries))

example:

.flex-item{
     flex: 0 0 calc(25% - (45px / 4 ))
}

works like this:

$n: 4; // number of columns
$gap: 15px; // margin pixels

.flex-parent{
    display: flex;
    gap: $gap;
}
.flex-item{
     flex: 0 0 calc(100% / $n - (($n - 1) * $gap / $n ) );
}

4 cols) flex: 0 0 calc(25% - (30px / 4 ) ); 3 cols) flex: 0 0 calc(33.3% - (20px / 3) ); 2 cols) flex: 0 0 calc(50% - (10px / 2) );
M
Mr.Bil

on the child element of flex

flex: 1 1 25%

this will allow to have 4 items if you want to add more items then you can decrease the %