Edi Smutko
Edi Smutko

Reputation: 83

creating equal width flex items

I'm using flex for layout purposes, but the browser does not spread the width equally between items.

.parent {
  display: flex;
  width: 200px;
}

.btn1 {
  flex: 1 1 auto;
}
<div class="parent">
  <div class="btn1">
    <button align="left" style="width:100%">Ok</button>
  </div>
  <button align="left" class="btn1">Cancel</button>
  <div>

Now, I want the buttons to split the container length 50% / 50%.

But that's not what's happening. I tried using flex: 1 1 auto and flex: 1 1 0 but with no success.

I know that I can use the OK button directly and it will solve my problem, but in my particular scenario it's important to wrap it with a div.

Now, as I understand it, flex should be able to spread the width equally and that's my goal here.

One more thing though, I noticed that the button content seems to have an effect on the width and I want to ignore this effect somehow.

Thanks!

JSFiddle example: https://jsfiddle.net/edismutko/cvytLkyp/3/

Upvotes: 4

Views: 5454

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371221

flex-basis: auto vs flex-basis: 0

You're sizing your flex items with flex: 1 1 auto.

However, if you want to distribute space evenly among items, you need to use flex: 1 1 0.

The difference is the flex-basis component.

With flex-basis: 0, every item is considered to have a zero width and flex-grow distributes container space equally among them. This results in all items having the same length.

With flex-basis: auto, the size of the item is factored into the flex-grow calculation and container space is distributed proportionally among items.

So when you want equal length items use flex: 1 1 0, which is the same as flex: 1.

Here's a more detailed explanation: Make flex-grow expand items based on their original size


Default rules on button elements

Browsers apply styles to elements by default. For instance, Chrome adds padding and border widths to button elements.

enter image description here

Reset those defaults.

Now you have two equal width flex items. (Additional styling is up to you.)

.parent {
  display: flex;
  width: 200px;
}

.btn1 {
  flex: 1;
}

button {
  padding: 1px 0;
  border-left-width: 0;
  border-right-width: 0;
}
<div class="parent">
  <div class="btn1">
    <button align="left" style="width:100%">Ok</button>
  </div>
  <button align="left" class="btn1">Cancel</button>
  <div>


box-sizing: border-box

Something else to consider is including the padding and border lengths in the width / flex-basis calculation. Why are borders causing div to overflow container?

Upvotes: 5

Related Questions