Uniform width using flex and border

I am using box-sizing: border-box;

with variable thickness border

within flexbox. I want the items inside the flexbox to have equal width, but it calculates the width

item without borders.

Here's an example: width

my container 100px

, so every item should be 20px

; however they are 19.2px

(x4) and 23.2px

.

.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100px;
}

.container .block {
  height: 28px;
  flex: 1;
  border: 1px solid black;
  box-sizing: border-box;
}

.container .block.selected {
  border: 3px solid blue;
}
      

<div class="container">
  <span class="block">0</span>
  <span class="block">1</span>
  <span class="block selected">2</span>
  <span class="block">3</span>
  <span class="block">4</span>
</div>
      

Run code


+3


source to share


5 answers


box-sizing: border-box

used to change the default CSS field model used for calculations width

and height

elements.

So it would be like this:

  • total width

    = border

    + padding

    +content width

    and

  • total height

    = border

    + padding

    +content height

But this does not happen in flex-grow

, but inflex-basis

Here is a nice tutorial about flexbox


So you can use flex:0 20%

instead flex:1

,



.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100px;
}

.container .block {
  height: 28px;
  flex: 0 20%;
  border: 1px solid black;
  box-sizing: border-box;
}

.container .block.selected {
  border: 3px solid blue;
}
      

<div class="container">
  <span class="block">0</span>
  <span class="block">1</span>
  <span class="block selected">2</span>
  <span class="block">3</span>
  <span class="block">4</span>
</div>
      

Run code


Note: if you have more elements than 5 then you can use calc()

like this flex: 0 calc(100%/8)

where 8 is the number of elements you will have

Fragment with a lot of elements

.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100px;
}

.container .block {
  height: 28px;
  flex: 0 calc(100%/8);
  border: 1px solid black;
  box-sizing: border-box;
}

.container .block.selected {
  border: 3px solid blue;
}
      

<div class="container">
  <span class="block">0</span>
  <span class="block">1</span>
  <span class="block selected">2</span>
  <span class="block">3</span>
  <span class="block">4</span>
  <span class="block">5</span>
  <span class="block">6</span>
  <span class="block">7</span>
</div>
      

Run code


+6


source


The property does not set the width or height of flex items. The challenge is to distribute the free space in the container between flex items. flex-grow

You have all the elements set to , which is shorthand for: flex: 1

  • flex-grow: 1

  • flex-shrink: 1

  • flex-basis: 0

This distributes the free space on the line evenly between the elements.

BUT borders (and additions) are counted separately.



flex-grow

doesn't care about because it applies to > and which, as mentioned earlier, are not functions . box-sizing: border-box

box-sizing

width

height

flex-grow

Use a property instead , which is equivalent (in line is the direction container) and will respect : flex-basis

width

box-sizing

flex: 0 0 20%;

      

.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100px;
}

.container .block {
  height: 28px;
  flex: 0 0 20%; /* adjustment */
  border: 1px solid black;
  box-sizing: border-box;
}

.container .block.selected {
  border: 3px solid blue;
}
      

<div class="container">
  <span class="block">0</span>
  <span class="block">1</span>
  <span class="block selected">2</span>
  <span class="block">3</span>
  <span class="block">4</span>
</div>
      

Run code


+4


source


Instead of setting the flex to one unit, you can set the flex to the base to 20% and then the width will be divided equally:

.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100px;
}

.container .block {
  height: 28px;
  flex-basis: 20%;
  border: 1px solid black;
  box-sizing: border-box;
}

.container .block.selected {
  border: 3px solid blue;
}
      

<div class="container">
  <span class="block">0</span>
  <span class="block">1</span>
  <span class="block selected">2</span>
  <span class="block">3</span>
  <span class="block">4</span>
</div>
      

Run code


+2


source


One way would be to install the add- 2px

on .block

and uninstall it for.selected

.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100px;
}

.container .block {
  height: 28px;
  flex: 1;
  border: 1px solid black;
  box-sizing: border-box;
  padding: 2px;
}

.container .block.selected {
  border: 3px solid blue;
  padding: 0px;
}
      

<div class="container">
  <span class="block">0</span>
  <span class="block">1</span>
  <span class="block selected">2</span>
  <span class="block">3</span>
  <span class="block">4</span>
</div>
      

Run code


+1


source


Your problem here is flex: 1;

to change it to flex: 1 0 20%;

even for more items. there is no need to calculate the width using calc

as mentioned earlier.

also just change this:

.container .block {
  height: 28px;
  flex: 1;
  border: 1px solid black;
  box-sizing:         border-box;
}

      

in

.container .block {
  height: 28px;
  flex: 1 0 20%;
  border: 1px solid black;
    -moz-box-sizing:    border-box;
  -webkit-box-sizing: border-box;
    box-sizing:         border-box;
}

      

DEMO: https://jsfiddle.net/4aww81wv/

+1


source







All Articles