3

I have a DIV with "display: flex;" that contains 2 child DIVs next to each other. The first one is just a DIV that contains some ordered list items and the second DIV contains some images. The second DIV has display: flex and flex-wrap: wrap applied to it.

For some reason, when I give the first DIV a width of 200px, it's not working... it doesn't get a width of 200px. But if instead I give it a min-width of 200px, then it works and gets a width of 200px. I need to understand why does width not work while min-width works...

PLEASE VIEW THIS IMAGE BEFORE ANSWERING MY QUESTION!

/* Parent container that contains 2 child DIVs */

.parent_flex_container {
  display: flex;
}


/* First child DIV */

#desktop_sidemenu {
  width: 200px;
}


/* Second child DIV */

.flex_container {
  display: flex;
  flex-wrap: wrap;
}


/* Images of the second child DIV */

.Cac {
  max-width: 50%;
  height: 50%;
  margin-bottom: 20px;
  padding: 0 5px;
}
<div class="parent_flex_container">
  <div id="desktop_sidemenu">
    <nav>
      <ul>
        <li><a href="#">Arabic</a></li>
        <li><a href="#">Green tea</a></li>
      </ul>
    </nav>
  </div>

  <div>
    <div id="Featured_grid">
      <div class="grid_title_holder">
        <h2>Featured</h2>
      </div>

      <div class="flex_container">
        <div class="Cac">
          <img src="images/cover1.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover2.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover1.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover2.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover1.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover2.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover1.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>
        <div class="Cac">
          <img src="images/cover2.jpg" alt="" title="" />
          <p class="Artist_name_holder">Artist Name</p>
          <p class="Song_title_holder">Song Title</p>
        </div>

      </div>
    </div>

  </div>

</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Oxin
  • 63
  • 6

2 Answers2

1

I need to understand why does width not work while min-width works...

Because flex items are set, by default, to flex-shrink: 1, which means that they can shrink in order to minimize overflow of the container.

Your actual code (what the browser sees) is this:

#desktop_sidemenu {
   width: 200px;   /* author defined */
   flex-shrink: 1; /* default setting */
}

You need to disable flex-shrink:

#desktop_sidemenu {
   width: 200px;
   flex-shrink: 0;
}

Now, because the item can't shrink below 200px, it's equivalent to min-width: 200px.

For more details, see "The flex-shrink factor" in my answer here:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

So let's start with this when you using flexbox each child items will have 3 different elements which are:

  • flex-basis

  • flex-grow

  • flex-shrink

Where each of them has a different responsibility.

flex-basis

Flex-basis controls the default size of an element before it is manipulated by other Flexbox properties. It could be used as a width or height property. Let's see the below example:

.flexbox {
  display: flex;
}
.red {
  background: red;
  flex-basis: 100px;
}
.green {
  background: green;
  flex-basis: 100px;
}
.blue {
  background: blue;
  flex-basis: 100px;
}
<div class="flexbox">
  <div class="red">1</div>
  <div class="green">2</div>
  <div class="blue">3</div>
</div>

flex-grow

Now, when it comes to the property called flex-grow, the default is 0. That means the squares are not allowed to grow to take up space in the container. You can see the example below for more resolution:

.flexbox {
  display: flex;
}
.red {
  background: red;
  flex-grow: 0;
}
.green {
  background: green;
  flex-grow: 0;
}
.blue {
  background: blue;
  flex-grow: 0;
}
<div class="flexbox">
  <div class="red">1</div>
  <div class="green">2</div>
  <div class="blue">3</div>
</div>

So whats make a difference here, Well, let’s try incrementing flex-grow to 1 for every square:

.flexbox {
  display: flex;
}
.red {
  background: red;
  flex-grow: 1;
}
.green {
  background: green;
  flex-grow: 1;
}
.blue {
  background: blue;
  flex-grow: 1;
}
<div class="flexbox">
  <div class="red">1</div>
  <div class="green">2</div>
  <div class="blue">3</div>
</div>

flex-shrink

Flex-shrink is the opposite of flex-grow, determining how much a square is allowed to shrink. ts main use is to specify which items you want to shrink, and which items you don’t. By default, every square has a flex-shrink of 1. To see how shrink works see the below snippet:

.flexbox {
  display: flex;
}
.red {
  background: red;
  flex-grow: 0;
  flex-basis: 100px;
  flex-shrink: 1;
}
.green {
  background: green;
  flex-grow: 0;
  flex-basis: 100px;
  flex-shrink: 0;
}
.blue {
  background: blue;
}
<div class="flexbox">
  <div class="red">1</div>
  <div class="green">2</div>
  <div class="blue">3</div>
</div>

NOTE: you have to resize the browser to see the difference in the above squares.


Actual answer

So your problem lies here in the flex-shrink property, hence default value of flex-shrink is 1 so it will look like this:

#desktop_sidemenu {
  width: 200px;
  flex-shrink: 1; /* default setting of browser */
}

So that is why the width property alone does not do the work for you which means your first div will be shrinked in order to prevent the boxes get out of order, then all you have to do to make it work is to give it a min-width: 200px or flex-shrink: 0.

NOTE: there is a shorthand for these three property called flex which you can give these three properties as one with the following order:

flex: 0 0 200px; /* flex-grow flex-shrink flex-basis */

For more information about these kinds of stuff, you can follow the MDN here.

SMAKSS
  • 9,606
  • 3
  • 19
  • 34