0

I want to center the section block vertically with the remainder of the available vertical space on the screen. It should be 100vh - (height of navbar), but I don't know how to achieve that in css

I'm currently setting section height: 100vh but this causes the scrollbar to appear

html, body {
  margin: 0;
  padding: 0;
}

* {
    box-sizing: border-box;
}

nav {
 display: flex;
 justify-content: space-between;
 border: 1px solid red
}

section {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  border: 1px solid blue
}
<html>
<body>
<nav>
  <div>
    <a>link 1</a>
    <a>link 2</a>
    <a>link 3</a>
  </div>
  <div>
   <a>download</a>
  </div>
</nav>
<section>
 <h1>This is Centered Vertically</h1>
 <div>
    <h3>However height: 100vh causes a scrollbar to appear</h3>
 </div>
</section>
</body>
</html>
Millhorn
  • 2,953
  • 7
  • 39
  • 77
Colin Cheung
  • 148
  • 2
  • 13

4 Answers4

1

Using flex and flex:1 solves the problem without using calc() (works with dynamic sized navbar).

(NOTE: using 100vh is not recommended since it ignores mobile navigation bars, so in mobile browsers like safari the content will remain scrollable. using 100% on body and html makes it "real" 100% height. see : CSS3 100vh not constant in mobile browser)

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

}
body {
  display: flex;
  flex-direction: column;

}

* {
    box-sizing: border-box;
}

nav {
 display: flex;
 justify-content: space-between;
 border: 1px solid red
}

section {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border: 1px solid blue
}
<html>
<body>
<nav>
  <div>
    <a>link 1</a>
    <a>link 2</a>
    <a>link 3</a>
  </div>
  <div>
   <a>download</a>
  </div>
</nav>
<section>
 <h1>This is Centered Vertically</h1>
 <div>
    <h3>However height: 100vh causes a scrollbar to appear</h3>
 </div>
</section>
</body>
</html>
ATP
  • 2,939
  • 4
  • 13
  • 34
  • @Kameron `calc` wont work for dynamic height navbar – ATP Sep 09 '22 at 14:23
  • @Kameron even OP's navbar is not static in some way. for example accessibility services can increase the font size and make it bigger, your assumption that's the navbar height is 26 is wrong, it depends on more criterions (number of lines etc.). – ATP Sep 09 '22 at 14:35
  • Valid arguments – Kameron Sep 09 '22 at 14:46
0

You can either hardcode the height of your navbar into CSS using calc:

/* replace 30px with whatever height your navbar has */
height: calc(100vh - 30px);

Or you can just apply the height of 100vh to the parent elemnt (in your case the body) and let flexbox handle the size of your content container.

Keep in mind that the scrollbar will still appear when the content of the <section> is bigger than your screen. If you want to scroll inside the section, you will have to add overflow: auto; and min-height: 0; to it.

html, body {
  margin: 0;
  padding: 0;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}

* {
    box-sizing: border-box;
}

nav {
 flex: none;
 display: flex;
 justify-content: space-between;
 border: 1px solid red
}

section {
  flex: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border: 1px solid blue
}
<html>
<body>
<nav>
  <div>
    <a>link 1</a>
    <a>link 2</a>
    <a>link 3</a>
  </div>
  <div>
   <a>download</a>
  </div>
</nav>
<section>
 <h1>This is Centered Vertically</h1>
 <div>
    <h3>However height: 100vh causes a scrollbar to appear</h3>
 </div>
</section>
</body>
</html>
whitespace
  • 180
  • 1
  • 6
0

This could be achieved with calc in css but you have to set some height to the navbar e.g.

nav {
 height: 80px; // or 10%
}

section {
 height: calc(100vh - 80px); // or calc(100vh - 10%) 
}
-1

Set the body to 100% height, make it a flex column and apply flex:1 to the section.

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

body {
  display: flex;
  flex-direction: column;
}

* {
  box-sizing: border-box;
}

nav {
  display: flex;
  justify-content: space-between;
  border: 1px solid red
}

section {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  flex: 1;
  border: 1px solid blue
}
<nav>
  <div>
    <a>link 1</a>
    <a>link 2</a>
    <a>link 3</a>
  </div>
  <div>
    <a>download</a>
  </div>
</nav>
<section>
  <h1>This is Centered Vertically</h1>
  <div>
    <h3>However flex:1 does not cause a scrollbar to appear</h3>
  </div>
</section>

View in full screen for proper viewing.

Paulie_D
  • 107,962
  • 13
  • 142
  • 161