4

When I set the .sidebar width to be 100%, it gets smaller than before.

However, when I remove the body's font-size: 1.3rem and toggle the .sidebar's width: 100%, it gets slightly larger.

I know that when we set the font-size to be 1.3rem, .primary-content's horizontal width (if it didn't wrap) should still be the same ratio as the .sidebar's width (if it didn't wrap).

So I'm not sure how flexbox calculates width: 100%

body {
  font-size: 1.3rem;
}

h1 {
  margin-top: 0;
}

.container {
  width: 80%;
  max-width: 1100px;
  margin: 0 auto;
}

.row {
  display: flex;
}

.primary-content {
  background-color: moccasin;
}

.sidebar {
  /* width: 100%; */
  padding: 1em;
  text-align: center;
  color: #fff;
  background-color: #136c72;
}
<main class="main container row">
  <section class="primary-content">
    <h2>Quality designs made custom, on demand, just for you</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
      et dolore magna aliqua. Ut enim ad minim veniam.</p>
  </section>
  <aside class="sidebar">
    <h2>Cheap</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
  </aside>
</main>

Here's the codepen.

https://codepen.io/Fullchee/pen/OJMBovq

disinfor
  • 10,865
  • 2
  • 33
  • 44
Fullchee Zhang
  • 489
  • 5
  • 13

1 Answers1

5

It's all about the initial width here. To understand this let's take another simple example with less code:

.box {
  display: flex;
  width: 50%;
  border: 2px solid red;
  margin: auto;
}

.box>div {
  border: 1px solid green;
}
<div class="box">
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
</div>


<div class="box">
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
  <div style="width:100%;">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
</div>

It's trivial, that the second case seems a bit strange because the width is reduced but this is logical.

First, you should notice that both elements have the same content and the content need to wrap inside each one because there is not enough space.

If we reduce the content it will be different:

.box {
  display: flex;
  width: 50%;
  border: 2px solid red;
  margin: auto;
}

.box>div {
  border: 1px solid green;
}
<div class="box">
  <div>
    Lorem ipsum dolor sit amet, 
  </div>
  <div>
    Lorem ipsum dolor sit amet, 
  </div>
</div>


<div class="box">
  <div>
    Lorem ipsum dolor sit amet,
  </div>
  <div style="width:100%;">
    Lorem ipsum dolor sit amet,
  </div>
</div>

To understand both cases, you need to understand the flexbox algorithm that I will summarize in 3 points:

  1. We first set the initial width of each element
  2. If the total width is bigger that the container width, we shrink both elements
  3. The shrink factor consider the negative free space (total width - container width) and the width of each element.

The trick is in the (1).

Without width:100% we will have the following in (1)

$('.box div').each(function() {
  console.log($(this).width());
})
.box {
  display: flex;
  width: 50%;
  border: 2px solid red;
  margin: auto;
}

.box>div {
  border: 1px solid green;
  flex-shrink:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
</div>

Both elements have the same width so both will shrink the same way to get the following:

$('.box div').each(function() {
  console.log($(this).width());
})
.box {
  display: flex;
  width: 50%;
  border: 2px solid red;
  margin: auto;
}

.box>div {
  border: 1px solid green;
  flex-shrink:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
</div>

Now if you make the second element width:100% it will have a smaller initial width

$('.box div').each(function() {
  console.log($(this).width());
})
.box {
  display: flex;
  width: 50%;
  border: 2px solid red;
  margin: auto;
}

.box>div {
  border: 1px solid green;
  flex-shrink:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
  <div style="width:100%">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
</div>

The first one is almost 3 times bigger than the second one thus they will not shrink the same way and at the end the second will remain smaller (it will be kept at almost 3 times smaller)

$('.box div').each(function() {
  console.log($(this).width());
})
.box {
  display: flex;
  width: 50%;
  border: 2px solid red;
  margin: auto;
}

.box>div {
  border: 1px solid green;
  flex-shrink:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
  <div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
  <div style="width:100%">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nulla nisi, accumsan vel purus nec, pretium dictum ex. Suspendisse pellentesque velit eget turpis porttitor efficitur
  </div>
</div>

Same logic apply to your code!

The same logic also apply when smaller content is used but in this case width:100% can make the initial width of the second item bigger so we end having a bigger element (like in the second snippet above)


Some related questions where you will get more details around the calculation and the flexbox algorithm:

How flexbox calculates flex-item's width if no flex-basis or width are set?

Why is a flex item limited to parent size?

The unpredictable wrapping habits of CSS


In case you want to increase the width of your element you can make the first element to shrink more:

body {
  font-size: 1.3rem;
}

h1 {
  margin-top: 0;
}

.container {
  width: 80%;
  max-width: 1100px;
  margin: 0 auto;
}

.row {
  display: flex;
}

.primary-content {
  background-color: moccasin;
}

.sidebar {
  padding: 1em;
  text-align: center;
  color: #fff;
  background-color: #136c72;
}
<main class="main container row">
  <section class="primary-content">
    <h2>Quality designs made custom, on demand, just for you</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
      et dolore magna aliqua. Ut enim ad minim veniam.</p>
  </section>
  <aside class="sidebar">
    <h2>Cheap</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
  </aside>
</main>

<main class="main container row">
  <section class="primary-content" style="flex-shrink:1.2;">
    <h2>Quality designs made custom, on demand, just for you</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
      et dolore magna aliqua. Ut enim ad minim veniam.</p>
  </section>
  <aside class="sidebar">
    <h2>Cheap</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
  </aside>
</main>

You can also define flex-shrink for both and make sure it's bigger for the first element:

Temani Afif
  • 245,468
  • 26
  • 309
  • 415