Flexbox item wrapping


#21

I shouldn't speak so fast......According to tutorail above I tried to calculate myself and see what I get....

My CodePen Demo I have following....

Container = 500px;
first box = 120px;
second box = 70px;

Remaining space 500-120-70 = 310
We have 3 growth factors so we divide 310/3 = 103.33

we should get then...

first box = 120 + (2*103.33) = 326.66
second box = 70 + (1*103.33) = 173.33

Using web dev tool layout tool I get

first box = 319.333px
second box = 180.666px


#22

Did you account for the padding?


#23

Here is another example where I have nested the image and stars in a left column.
Then the text is nested in right column.

Now it's two divisions instead of three, that paves the way for a media query that can stack them into columns.

That keeps the image from getting too small and sets you up for mobiles at the same time.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Scaling Img & Flex Boxes</title>
<style>
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.container {
   display: flex;
   flex-flow: row wrap;
   width: 90%;
   margin: 0 auto;
   background: tomato;
}
.left, .image,
.stars, .right {
   display:flex;
}
.left {
   flex-flow: row nowrap;
   flex: 1 1 45%;  /*grow | shrink | basis */
}
   .image { /*nested in .left*/
      flex: 1 1 80%;  /*grow | shrink | basis */
   }
      .image img {
         display: block;
         width: 100%;
         max-width: 300px; /*actual image width*/
         height: auto;
         margin: auto;
      }
   .stars { /*nested in .left*/
      flex-flow: column wrap;
      flex: 1 1 20%;  /*grow | shrink | basis */
      justify-content: center;
      align-content: space-evenly;
      color: white;
      font-size: 2em;
      background: green;
   }
.right {
   flex-flow: row wrap;
   flex: 2 1 55%;   /*grow | shrink | basis */
   justify-content: center;
   align-content: space-evenly;
   background: orange;
}
   .right div {
      margin:5px;
      padding:5px;
      background:#fff;
      border-radius:5px;
   }

@media all and (max-width: 550px){
   .left,.right {flex: 1 1 100%;}
}
</style>

</head>
<body>

<div class="container">
   <div class="left">
      <div class="image">
         <img src="http://via.placeholder.com/300x200" width="300" height="200" alt="Image Alt Text">
      </div>
      <div class="stars">
         <div>&starf;</div>
         <div>&starf;</div>
         <div>&starf;</div>
         <div>&starf;</div>
      </div>
   </div>
   <div class="right">
      <div>going to school today</div>
      <div>went to see a movie</div>
      <div>it is very cold here today</div>
      <div>this is very long text that might go into second line</div>
      <div>what day is today</div>
   </div>
</div>

</body>
</html>

#24

How do you decide what the basis will be.?45% why?


#25

The flex-basis, when set as a <length> with a unit (% or px), is the initial width before flex-grow or flex-shrink makes adjustments.

I just decided on 45% for the left div because I could see that the right text div needed a little more than 50%.

So I just wound up with this..

.left {
   flex-flow: row nowrap;
   flex: 1 1 45%;  /*grow | shrink | basis */
}
.right {
   flex-flow: row wrap;
   flex: 2 1 55%;   /*grow | shrink | basis */
   justify-content: center;
   align-content: space-evenly;
   background: orange;
}

45% + 55% = 100% ( of .container width)

Now within the left div are it's children, image & stars

.image { /*nested in .left*/
      flex: 1 1 80%;  /*grow | shrink | basis */
   }
   .stars { /*nested in .left*/
      flex-flow: column wrap; /*stack the stars*/
      flex: 1 1 20%;  /*grow | shrink | basis */

80% + 20% = 100% ( of .left width )


Then when the media query kicked in I changed left and right...

@media all and (max-width: 550px){
   .left,.right {flex: 1 1 100%;}
}

To 100% each, that equals 200% of .container width, so they were forced to wrap.

Even though they are still rows, they stack to look like columns because I have row wrap on the container

.container {
   display: flex;
   flex-flow: row wrap;

#26

Doesnt

max-width: 250px

Over-rides..

width: 100%;

I guess my question is why do you need both properties?


#27

width: 100%; along with height:auto; is what allows the image to scale down (and maintain it's aspect ratio) when the available space is less than the image's native width, which = (img width attribute in the html)

max-width: <native image width>; is what keeps the image from distorting it's aspect ratio when the available space be greater than the image's native width.

Remove those rules (one at a time) and you will see what happens as you drag your browser window back and forth.

Some images distort worse than others, but that combination of rules is a standard practice for responsive images in the html.

The margin: auto; rule just centers the image in the available space, it's optional.


#28

Why doesn’t this property validate?

space-evenly is not a align-content value : space-evenly

#29

See the notes at MDN
Aligning Items in a Flex Container

Note: the value space-evenly is not defined in the flexbox specification and is a later addition to the Box Alignment specification. Browser support for this value is not as good as that of the values defined in the flexbox spec.

As a fallback you can use space-around;

align-content: space-around;  /* Distribute items evenly
                                 Items have a half-size space
                                 on either end */
align-content: space-evenly;  /* Distribute items evenly
                                 Items have equal space around them */

#30

Last question I swear :slight_smile:

As you said in previous post basis of 45%is saying that this element will take 45% of space of its container but what does 1 and 1 mean. It means that it can grow or shrink but this is not absolute value I imagine. Is it relative to other items in container and if so how much. If shrink value was set to 0 does that mean element can not shrink so what happens when browser window gets smaller?

Thanks


#31

Not a problem :slight_smile:

I'm sure you've looked through it but you can find most of the flexbox specs at MDN.

As you see by the css comment, flex: is the shorthand for flex-grow, flex-shrink, and flex-basis.

Initial value	as each of the properties of the shorthand:

    flex-grow: 0
    flex-shrink: 1
    flex-basis: auto

Yes, it is relative to the other items and the grow/shrink rates that are set on them, and the space available in the container.

flex-grow:0; means don't grow past flex-basis
flex-grow:1; means grow at 1x the rate of other items that grow
flex-grow:2; means grow at 2x (twice) the rate of other items that grow

And in like manner with flex-shrink

flex-shrink:0; means don't shrink past flex-basis
flex-shrink:1; means shrink at 1x the rate of other items that shrink
flex-shrink:2; means shrink at 2x (twice) the rate of other items that shrink

You can also use decimal values

flex-grow: 0.5; means grow at 1/2 the rate of other items that grow

The flex-grow and flex-shrink links give a good illustration of the flex factors in the examples found on those pages

As I understand it, that's how it works. The amount of other items, their size and flex factors, and the space available in the container all play a role in how adjustments get made.

Here's another tutorial I have been going through

Actually, you'll probably find that link more helpful as it has better illustrations and interactive examples. :slight_smile:


#32

A lot of people think that items with flex-grow will be based on the size of the other flex-items and may expect an item with:flex-grow:2 to be twice as big as other flex-items. Flex grow actually redistributes the remaining space and does not really relate to the size of the items.

If only one flex-item had flex-grow:1 and the others in the same context did not then the item with flex-grow:1 will be as wide as its content plus all the rest of the space on that line (if any). It may end up being 20 times bigger than other content and indeed if you added flex:grow:20 it would make no difference because the remaining space is already applied with 1.

If several elements have flex-grow:1 then the remaining space in the line is equally distributed between those items. They all may end up being different sizes because their content may be different.

Flex-grow effectively targets the remaining space on a line and distributes to items that have flex-grow applied. If they are all flex-grow:1 except that one item is flex-grow:2 then the item with 2 will have twice as much free space added as the others.


#33

I'm still trying to get my head wrapped around flexbox, but I am much further along than I was a couple of weeks ago. :slight_smile:

Yes, that 'remaining space' is the key condition.

I was referring to it as 'space available' in my closing comment above.

As I understand it, that's how it works. The amount of other items, their size and flex factors, and the space available in the container all play a role in how adjustments get made.

My definition of flex-grow would have been clearer with that key condition included.
I did make sure that it was pointed out though :slight_smile:

flex-grow:1; means grow at 1x the rate of other items that grow, when remaining space is available

Looking back at my example in post #23 I now see that there really is no flex factors happening. Being that all my flex-basis widths total out to 100%. It is basically a fluid layout that's just using flex to align everything.


#34

Ok that make sense in case of grow but what happens when items need to shrink?


#35

My take on this flex factor vs. remaining space condition, is that since flex-shrink is the opposite of flex-grow, then the conditions must be true for it to happen also.

And that neither flex-grow nor flex-shrink can happen, without that key component of 'remaining space available'.

As long as the total sum of (child) flex-basis values do not fill the parents width, then there will be 'remaining space available' that can be distributed into the flex factors, whether they be grow or shrink


#36

I placed one additional div here like this

<div class="myclass">I want to be hidden</div>

I gave it following rule..

.myclass {
   display: none !important;
 }

When browser windows reaches Xpx I would like to show this element....When I set it to..

display: block;

Element is still hidden


#37

Why did you give it the "!important" ?


#38

because rule assigned to div parent was of more importance


#39

ok this was resolved but I still had to use

!important

#40

Are you happy with that or you looking for another opinion?