1

I have an element with grid display which has 3 columns - SectionOne, SectionTwo, SectionThree. Column in the middle is also a grid which contains 3 rows - SectionTwoTop, SectionTwoCenter, SectionTwoBottom. I want:

  1. .content to take up only space available in the viewport (so it wouldn't cause the page to overflow).
  2. Elements SectionOne, SectionTwoCenter, and SectionThree to overflow if content within them does not fit into a viewport.
  3. .footer to be visible at the bottom.

Now, the problem is not so much the .content itself but the current layout where I want to add these changes. I just cannot achieve the result that I want within that layout. Anyway, I would prefer only to make changes to .content and its child elements and not to the surrounding layout.

Here is a relevant code:

index.css

.container-blueprint {
  display: grid;
  grid-template-columns: min-content 1fr min-content;
  grid-template-rows: 1fr;
  gap: 0px 0px;
  grid-auto-flow: row;
  grid-template-areas:
    "SectionOne SectionTwo SectionThree"
    "SectionOne SectionTwo SectionThree"
    "SectionOne SectionTwo SectionThree";
}

.SectionOne {
  overflow-y: auto;
  grid-area: SectionOne;
  width: 300px;
}

.SectionTwo {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: min-content 1fr min-content;
  gap: 0px 0px;
  grid-auto-flow: row;
  grid-template-areas:
    "SectionTwoTop SectionTwoTop SectionTwoTop"
    "SectionTwoCenter SectionTwoCenter SectionTwoCenter"
    "SectionTwoBottom SectionTwoBottom SectionTwoBottom";
  grid-area: SectionTwo;
}

.SectionThree {
  overflow-y: auto;
  grid-area: SectionThree;
  width: 100px;
}

.SectionTwoTop {
  height: 100px;
  grid-area: SectionTwoTop;
}

.SectionTwoCenter {
  overflow-y: auto;
  grid-area: SectionTwoCenter;
}

.SectionTwoBottom {
  height: 100px;
  grid-area: SectionTwoBottom;
}

/* Other styles. */

html,
body {
  height: 100%;
  margin: 0;
  box-sizing: border-box;
}

body {
  display: grid;
  min-height: 100vh;
  grid-template-columns: auto 1fr;
  grid-template-rows: min-content min-content 1fr min-content;
}

.container-blueprint * {
  border: 1px solid red;
  position: relative;
}

.header {
  grid-area: 1/1/2/3;
}

.nav {
  grid-area: 2/2/3/3;
}

.sidebar {
  grid-area: 2/1/4/2;
}

.content {
  grid-area: 3/2/4/3;
}

.footer {
  grid-area: 4/1/5/3;
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <link href="index.css" rel="stylesheet" />
  </head>
  <body>
    <div class="header">[HEADER]</div>
    <div class="nav">[NAV]</div>
    <div class="sidebar">[SIDEBAR]</div>

    <!-- BEGIN  -->
    <div class="content">
      <div class="container-blueprint">
        <div class="SectionOne">[SECTION ONE]</div>
        <div class="SectionTwo">
          <div class="SectionTwoTop">[SECTION TWO TOP]</div>
          <div class="SectionTwoCenter">[SECTION TWO CENTER]</div>
          <div class="SectionTwoBottom">[SECTION TWO BOTTOM]</div>
        </div>
        <div class="SectionThree">[SECTION THREE]</div>
      </div>
    </div>
    <!-- END -->

    <div class="footer">[FOOTER]</div>
    <script src="index.js"></script>
  </body>
</html>

Here is a link to an interactive demo:

Edit admiring-rgb-945x63

I can achieve what I want by using calc(100vh - <height of the top content>) on the relevant elements but I do not want to use this approach because I may not know height of the elements and it feels like a bad approach overall (for example, after height in top elements changes, I need to update calc() function again to prevent page overflow or gap below). I tried various approaches with flex and table display options but I cannot for the life of me get the result that I want.

Karolis
  • 255
  • 3
  • 15

1 Answers1

2

I finally did it. I only needed to add these rules:

.content {
    min-height: 0;
}

.container-blueprint {
    height: 100%;
}
Karolis
  • 255
  • 3
  • 15