0

I have the below html, where I set default flex properties are being used.

<div class="container">
  <div class="box"> BOX 1</div>
  <div class="box"> BOX 2</div>
  <div class="box box2"> BOX 3 .</div>
</div>

and styles are:

.container {
  border: 1px solid #59c;
  width: 60vw;
  background: #ccc;
  height: 200px;
  margin: 0 auto;
  display: flex;
  padding: 30px;
}

.box {
  font-size: 18px;
  font-weight: 800;
  background: #e5f;
  border: 1px solid #99c;
  padding: 20px;
}

Now, in my chrome browser I do see box 1 and box 2 has computed width of 94.52px, and box3 has 103.52px. The fiddle b666tkj9. Now when I do add below style:

.box2 {
   flex: 2 1;
}

and flex: 1 1; to the .box {} rules, the computed width becomes now 226.5px for Box 1 and 2, and Box 3 got 411px.

My parent container width is 864px. So, 864 - 103.53 + (94.52 * 2) is equal to 571.43px. So this amount of space is distributed then, but I am not able to do the math which can show how each box got its final width.

Can anyone help by explaining this?

Brian
  • 3,850
  • 3
  • 21
  • 37
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • This might help: https://stackoverflow.com/questions/34753491/how-does-flex-shrink-factor-in-padding-and-border-box – Asons Dec 05 '17 at 22:20
  • You have the width of your container set to `60vw`. This sets the actual width of the container to the user's viewport width, which obviously varies among users. Therefore, the flex container and items will be different widths for different users. Nobody will get the same pixel lengths in your example. You should set a fixed width so that everybody is seeing the same thing. – Michael Benjamin Dec 05 '17 at 22:59
  • @Michael_B The question was not that it is not matching in other devises. The question was that in the same device my match was not matching with the ratio of width I am calculating. BTW, none of the answers you linked to, are really the exact duplicate of this question. – Arup Rakshit Dec 06 '17 at 04:47
  • 1
    Given that you refer to the items width prior to adding the `flex` property, and what is not clearly stated in the duplicate immediate links, nor in the given answer, is that when you use `flex: ` the `flex-basis` value is set to `0`. This means that each items content size is not taken into account when calculating the items width, it is only the, in this case having a positive space to distribute, the `flex-grow` value, which will size them 1/4, 1/4 and 2/4, though with the info in my previous comment's link, border and padding are removed before the calculations is made. – Asons Dec 06 '17 at 08:24
  • @ArupRakshit, my point was that we can help you more effectively if we can reproduce the problem. – Michael Benjamin Dec 06 '17 at 12:33
  • @Michael_B I gave a JS fiddle, does that help? The I way I am doing the math is wrong I am sure. So I am looking for help about the math how it is being calculated. If any one point me to the algorithm in W3C spec, I will try to understand from there. I skimmed through the W3C spec, but didn't see what I am looking for. – Arup Rakshit Dec 06 '17 at 13:06
  • @ArupRakshit May I ask how the given answer does not provide an answer? ... Combined with my 2nd comment, that should be it, or no? – Asons Dec 06 '17 at 13:15
  • 1
    @ArupRakshit And it is defined here: https://www.w3.org/TR/css-flexbox-1/#flex-flex-grow-factor ... also check Figure 7 ... and here https://www.w3.org/TR/css-flexbox-1/#flex-common ... check `flex: ` – Asons Dec 06 '17 at 13:21
  • @LGSon I didn't say that, it was not helpful. Did I? :) I was commenting to other one. thanks for your help. – Arup Rakshit Dec 06 '17 at 15:40
  • Thanks ... and no, of course you didn't :) ... so used to users upvote useful comments so I was simply wondering. – Asons Dec 06 '17 at 16:44
  • @LGSon I am trying to learn CSS since last 4-5 months, still not enough confident. :) Any good references you would like to share which helped u to become skilled in CSS? – Arup Rakshit Dec 06 '17 at 18:28
  • I've doing it for 20+ years and still ran into issues, so give it time :) ...when it comes to Flexbox, which might not be the easiest start with, this guide is great: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ – Asons Dec 06 '17 at 18:33
  • @LGSon I created [chat](https://chat.stackoverflow.com/rooms/160642/css-guidance) to get some direction from you. :) Would you mind to join? – Arup Rakshit Dec 06 '17 at 18:35

1 Answers1

1

The flex-grow CSS property specifies the flex grow factor of a flex item. It specifies what amount of space inside the flex container the item should take up. The flex grow factor of a flex item is relative to the size of the other children in the flex-container.

flex-grow MDN Article

As you can see, the size is relative to the other children. Given that your container is 864px wide, the children will be 184.5px wide not including padding or borders. We get to that number by dividing the width by the total grow values after subtracting the padding and border widths of the flex children out of the total width: (864 - 21*6) / 4 = 184.5 (21*6 accounts for three left borders, three right borders, three left padding values, and three right padding values). So with flex-grow set to 1,1,2, you get 184.5px,184.5px,369px respectively. Include the padding and border to get to the original width total: 184.5+184.5+369 + 40+40+40 + 2+2+2 = 864. So you have the right idea. It's just that the "width" of the children is the width excluding padding and border width.

Ultimately, you can see this illustrated below. 1,1,2 translates to 184.5px,184.5px,369px when only calculating using the "content" portion of the box model width for the flex children:

.container {
  border: 1px solid #59c;
  width: 864px;
  background: #ccc;
  height: 200px;
  margin: 0 auto;
  display: flex;
  padding: 30px;
}

.box {
  font-size: 18px;
  font-weight: 800;
  background: #e5f;
  border: 1px solid #99c;
  padding: 20px;
  
  flex: 1 1;
}

.box2 {
   flex: 2 1;
}

.box{position:relative}
.box:after{content:'184.5px';position:absolute;left:20px;right:20px;bottom:50%;text-align:center;border-bottom:2px solid;}
.box:before{content:'';position:absolute;left:20px;right:20px;bottom:50%;border:1px solid;border-width:0 2px;height:8px;margin-bottom:-3px;}
.box2:after{content:'369px';}
<div class="container">
  <div class="box"> BOX 1</div>
  <div class="box"> BOX 2</div>
  <div class="box box2"> BOX 3 .</div>
</div>
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129