Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill remaining screen height below non-fixed header of unkown size

Tags:

html

css

I want to achieve the layout of the snippet below:

  • non-fixed navbar at the top with unknown height
  • fill the remaining screen space with the #title div
  • the article continues after the title (not visible on the screen initially, only after scrolling down)

The problem with this snippet is, that it completely breaks the semantic hierarchy of the HTML. The #uglyWrapper splits the article in two parts.

I could use #title { height: calc(100vh - $nav-height) }, but the top bar is a flexbox itself. So $nav-height is unknwon.

Is there a CSS-only solution, that doesn't mess with this HTML structure:

body
    nav
    article
        #title
        text

Snippet demonstrating, how it should look like:

#uglyWrapper {
  height: 100%;
  display: flex;
  flex-direction: column;
}

#title {
  background-color: lightblue;
  height: 100%;
}

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

nav {
  background-color: grey;
}
<body>
  <div id="uglyWrapper">
    <nav>top nav with unknown height, not fixed</nav>
  <!--  article -->
    <div id="title">Full height title image</div>
  </div>
  Article continues <br>
  much text <br>
  much text <br>
  much text
  <!-- /article -->
</body>

Addressing mfluehr's answer:

This approach doesn't fill the remaining space. Instead it fills the entire screen height and gets clipped by the header bar. I left the details about the image intentionally out of the question asking for a div instead. Because there are other elements in that div, that require precise layouting. So covering up an area of unknown size is problematic. Please don't get stuck on the details of the image and use to the minimal example. I can get it working from there.

like image 538
Streamfighter Avatar asked Oct 20 '21 13:10

Streamfighter


2 Answers

Apply absolute positioning to the <nav>. Since the title image will use object-fit: cover, it shouldn't matter if a chunk from the top is covered by the navigation.

#title {
  background-color: lightblue;
  height: 100vh;
}

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

nav {
  background-color: grey;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}
<body>
  <nav>top nav with unknown height, not fixed</nav>
  <article>
    <div id="title">Full height title image</div>
    much text <br>
    much text <br>
    much text
  </article>
</body>
like image 162
mfluehr Avatar answered Oct 12 '22 23:10

mfluehr


I'm not sure, but try this solution with by adding display: grid on the #uglyWrapper element.

#uglyWrapper {
  height: 100%;
  display: grid; /* new line */
  grid-template-rows: auto 1fr 0%; /* new line */
}

#uglyWrapper {
  height: 100%;
  display: grid; /* new line */
  grid-template-rows: auto 1fr 0%; /* new line */
}

nav {
  background-color: hsl(0 0% 50% / 0.5);
  height: 100%;
}

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

#title {
  background-color: lightblue;
}
<div id="uglyWrapper">
  <nav>top nav with unknown height, not fixed</nav>
  <!--  article -->
  <div id="title">Full height title image</div>
  Article continues <br /> much text <br /> much text <br />
  <!-- /article -->
</div>
like image 24
Anton Avatar answered Oct 13 '22 01:10

Anton