Search code examples
cssflexbox

Why does width: 100% shrink this div within a flex parent?


I'm not so much looking for a solution as I am trying to understand what is happening.

In the code below, I have a flex enabled div with two child elements.

  • I explicitly set its width of the first child to 18rem.
  • I set the width of the second child to 100%.

.flex {
  display: flex;
}

.w-72 {
  width: 18rem;
}

.w-full {
  width: 100%;
}

.bg-blue-300 {
  --tw-bg-opacity: 1;
  background-color: rgb(147 197 253 / var(--tw-bg-opacity));
}

.bg-orange-200 {
  --tw-bg-opacity: 1;
  background-color: rgb(254 215 170 / var(--tw-bg-opacity));
}
<div class="flex">
  <nav class="bg-blue-300 w-72">Nav</nav>
  <article class="w-full bg-orange-200">Article</article>
</div>

enter image description here

I thought this would expand the <article> to fill the remaining horizontal width, but it actually causes the width of the neighboring <nav> to shrink. (Try running this code with and without w-full to see for yourself.)

Why does this happen?


Solution

  • A default setting on a flex container is flex-shrink: 1. This means that flex items will automatically shrink to avoid overflowing the container.

    To force flex items to respect their defined lengths, you must disable flex-shrink.

    Add this to your code:

    .w-72 {
      width: 18rem;
      flex-shrink: 0; /* new */
    }
    

    (The equivalent shorthand for the code above would be flex: 0 0 18rem.)

    .flex {
      display: flex;
    }
    
    .w-72 {
      width: 18rem;
      flex-shrink: 0; /* NEW */
    }
    
    .w-full {
      width: 100%;
    }
    
    .bg-blue-300 {
      --tw-bg-opacity: 1;
      background-color: rgb(147 197 253 / var(--tw-bg-opacity));
    }
    
    .bg-orange-200 {
      --tw-bg-opacity: 1;
      background-color: rgb(254 215 170 / var(--tw-bg-opacity));
    }
    <div class="flex">
      <nav class="bg-blue-300 w-72">Nav</nav>
      <article class="w-full bg-orange-200">Article</article>
    </div>