4

When the ancestor in the code below is display: block it is working as intended. When it's display: flex the nested grid shrinks.

I'd like to understand why this happens.

Just uncomment the display: block in the code below to see the result. The grid stops to span the whole area it's allowed to.

.ctnr{
  display: flex;
  //display: block;
  flex-flow: column;
  align-items: stretch;
}
header{ background: red; height: 2rem; }
main{
 max-width: 15rem;
 height: 25rem;
 margin: auto;
 overflow: auto;
}

.grid{
  display: grid;
 height: 25rem;
  align-items: stretch;
  grid-template-areas: 
  "c1 c1 c1 c2 c3 c3 c3"
  "c4 c4 c4 c4 c3 c3 c3"
  "c4 c4 c4 c4 c5 c6 c6"
  "c4 c4 c4 c4 c7 c7 c7";
 grid-gap: 10px;
}
.grid article{
 cursor: pointer;
}
.grid article:nth-child(odd){
  background: yellow;
}
.grid article:nth-child(even){
  background: cyan;
}
.c1{ grid-area: c1; }
.c2{ grid-area: c2; }
.c3{ grid-area: c3; }
.c4{ grid-area: c4; }
.c5{ grid-area: c5; }
.c6{ grid-area: c6; }
.c7{ grid-area: c7; }
<div class="ctnr">
  <header></header>
  <main>
    <div class="grid">
      <article class="c1">1</article>
      <article class="c2">2</article>
      <article class="c3">3</article>
      <article class="c4">4</article>
      <article class="c5">5</article>
      <article class="c6">6</article>
      <article class="c7">7</article>
    </div>
  </main>
  <footer></footer>
</div>

This is resolved by giving a width to main

main{
    width: 90%;
    max-width: 15rem;
    // ...
}

This "resolve" the issue, however I don't really get what's happening here. For instance the header is not shrinking even tho it has no width.

https://jsfiddle.net/6k2313ub/1/

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Ced
  • 15,847
  • 14
  • 87
  • 146

1 Answers1

4

This is the source of your problem:

main {
    max-width: 15rem;
    height: 25rem;
    margin: auto;
    overflow: auto;
}

The main element is set to a max-width: 15rem.

This leaves a lot of free space on the line (100% - 15rem).

The main element is also set to margin: auto. Being that main is a flex item, this rule tells it to consume all free space on the line equally from each side. This has the effect of squeezing out all free space and centering the item vertically and horizontally.

But flex auto margins don't work like this in block layout, which is why there's a rendering difference with display: block.

If you want the item to keep full width, like in block layout, use min-width instead of max-width. This does the trick:

main {
    min-width: 15rem; /* adjusted */
    height: 25rem;
    margin: auto;
    overflow: auto;
}

revised demo 1

OR, just add width: 100%. This also does the trick:

main {
    width: 100%; /* new */
    max-width: 15rem;
    height: 25rem;
    margin: auto;
    overflow: auto;
}

revised demo 2

So, margin: auto makes a big difference in flex layout. If you apply the same rule to the header, you would get a similar result.

revised demo 3

Learn more about flex auto margins here:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Summary: `margin:auto` doesn't work the same inside a flexbox. The last link will be a lot to process. Great ! – Ced Aug 06 '17 at 20:50
  • Just FYI, if you used `align-self: center` instead of `margin: auto`, you would get the same effect. Both methods consume free space on the line. That's how flex works. Block layout is different in this respect. – Michael Benjamin Aug 06 '17 at 21:00