12

I am trying to have a child CSS-grid respect the dimensions of the parent grid. How would I be able to achieve that?

I was initially writing something like this:

.site,
body,
html {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

.parent-grid {
  display: grid;
  height: 300px;
  width: 300px;
  grid-template-rows: 30px 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: 'nav' 'child';
  background-color: grey;
}

.nav {
  background-color: #0D47A1;
  grid-area: nav;
}

.child {
  grid-area: child;
}

.child-grid {
  display: grid;
  grid-template-rows: 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: 'test';
  background-color: grey;
}

.content {
  background-color: red;
  overflow: auto;
  grid-area: test;
}

* {
  box-sizing: border-box;
}
<div class="parent-grid">
  <div class="nav">Sidebar</div>
  <div class="child">
    <div class="child-grid">
      <div class="content">
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
      </div>
    </div>
  </div>
</div>

I would like to have 'content' be a scrollable area that doesn't expand the height of the parent (so it should be '270px').

Samuel Philipp
  • 10,631
  • 12
  • 36
  • 56
Matthew I
  • 1,043
  • 2
  • 10
  • 16

3 Answers3

14

The grid item (.child) is given min-height: auto by default. Apply min-height: 0 to .child to overrule this.

Then add height: 100% to .child-grid and overflow: auto to content...

.site,
body,
html {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

.parent-grid {
  display: grid;
  height: 300px;
  width: 300px;
  grid-template-rows: 10vh 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: 'nav' 'child';
  background-color: grey;
}

.nav {
  background-color: #0D47A1;
  grid-area: nav;
}

.child {
  grid-area: child;
  min-height: 0;
}

.child-grid {
  display: grid;
  grid-template-rows: 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: 'test';
  background-color: grey;
  height: 100%;
}

.content {
  background-color: red;
  overflow: auto;
  grid-area: test;
}

* {
  box-sizing: border-box;
}
<div class="parent-grid">
  <div class="nav">Sidebar</div>
  <div class="child">
    <div class="child-grid">
      <div class="content">
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
      </div>
    </div>
  </div>
</div>
sol
  • 22,311
  • 6
  • 42
  • 59
  • Michael_B's answer was informative but this more specific set of rules was what worked for me. My fault for not being clearer with my example. It's more like "parent-grid-areas: 'navbar' 'content'" and "content-grid-areas: 'itemlist map'" where itemlist is scrollable. Thanks – Matthew I Jan 12 '18 at 18:23
  • Sir, why min-height auto affects parent grid? Can you explain why this is happened? – xKralTr Sep 01 '23 at 07:51
10

Here's a quick and simple solution with no changes to your HTML. Just add this to your code:

.child { 
   overflow: auto;
}

This overrides the min-height: auto default setting on grid items, allowing them to shrink below the size of their content and create overflow conditions.

Full explanation here: Prevent content from expanding grid items

.site,
body,
html {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

.parent-grid {
  display: grid;
  height: 300px;
  width: 300px;
  grid-template-rows: 30px 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: 'nav' 'child';
  background-color: grey;
}

.nav {
  background-color: aqua;
  grid-area: nav;
}

.child {
  grid-area: child;
  overflow: auto;   /* NEW */
}

.child-grid {
  display: grid;
  grid-template-rows: 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: 'test';
  background-color: grey;
}

.content {
  background-color: red;
  overflow: auto;
  grid-area: test;
}

* {
  box-sizing: border-box;
}
<div class="parent-grid">
  <div class="nav">Sidebar</div>
  <div class="child">
    <div class="child-grid">
      <div class="content">
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
        <div>blah</div>
      </div>
    </div>
  </div>
</div>

Alternatively, instead of what you have here:

.parent-grid {
  display: grid;
  height: 300px;
  grid-template-rows: 30px 1fr;
}

Try this:

.parent-grid {
  display: grid;
  grid-template-rows: 30px 270px;
}

.content {
  overflow: auto;
  height: 100%;
}

I also removed an extra container (.child-grid) which doesn't appear to be necessary.

.site,
body,
html {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

.parent-grid {
  display: grid;
  height: 300px;
  width: 300px;
  grid-template-rows: 30px 270px;
  grid-template-columns: 1fr;
  grid-template-areas: 'nav' 'child';
  background-color: grey;
}

.nav {
  background-color: aqua;
  grid-area: nav;
}

.child {
  grid-area: child;
}

.content {
  background-color: red;
  overflow: auto;
  height: 100%;
}

* {
  box-sizing: border-box;
}
<div class="parent-grid">
  <div class="nav">Sidebar</div>
  <div class="child">
    <div class="content">
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
      <div>blah</div>
    </div>
  </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Cool + 1... Do you know why `overflow: auto` works by itself, but `min-height: 0` requires additional rules on the contents of `.child`? – sol Jan 11 '18 at 16:45
  • 1
    In terms of the `min-height: auto` default on grid (and flex) items, it can be overridden with `min-height: 0` or `overflow` with any value other than `visible`. Overriding with `min-height`, however, doesn't launch scrollbars. See my answer in the link reference I posted (and see [**this answer**](https://stackoverflow.com/a/36247448/3597276) too, which goes into more detail). – Michael Benjamin Jan 11 '18 at 16:49
0

Well, give a dedicated height to your child grid:

height: 240px;

and set

overflow: auto;

So, indeed, height is ensured. And if necessary, scrollbars will appear. Not sure, if the fairly recent feature of css grids is really the best thing to use here. You may want to have a look at flexbox: https://codepen.io/fnocke/details/RxMKOK

Or –even more compatible– you could indeed stick with normal display: block;. As long as you specify heights and set the overflow, that should do as well.

Frank N
  • 9,625
  • 4
  • 80
  • 110