Friday, February 23, 2018

Grab available height of div without knowing its height or being able to set height 100%

Leave a Comment

I would like to center the Dasboard h1 in the attached markup. It is not possible for me to know the size of the div or is it possible for me to set height: 100% for every preceding div for this.

I would have thought this was possible with flexbox but every example I see has height 100% or height: 100vh in all the parent elements. I could just use display: table or dispaly: table-cell if that was the case.

html {    min-height: 100%;    position: relative;  }    body {    height: 100%;    background-color: #f7f7f4;  }    #root {    height: 100%;    padding-bottom: 170px;  }    .wrapper {      max-width: 750px;  }    .grid {      list-style: none;      margin: 0;      padding: 0;      margin-left: -30px;  }    .grid__item {      display: inline-block;      padding-left: 30px;      vertical-align: top;      width: 100%;      -webkit-box-sizing: border-box;      box-sizing: border-box;  }    .one-half {      width: 50%;  }    .private-banner__container {      height: 98px;  }    .private-banner__layout {      width: 100%;      height: 100%;      display: table;  }    .private-banner__right, .private-banner__left {      display: table-cell;      vertical-align: middle;  }    .footer__footer {      padding-top: 48px;      padding-bottom: 48px;  }    ul {      margin-left: 38px;      margin-left: 2.375em;  }    .footer__footer ul li:not(last-of-type) {      margin-right: 48px;  }    .footer__footer li {    display: inline;  }
<html lang="en">      <body>      <div id="root">        <header role="banner">          <div class="wrapper private-banner__container">            <div class="grid private-banner__layout">              <div class="grid__item one-half     private-banner__left"><h1>Logo</h1></div>              <div class="grid__item one-half     private-banner__right"><a href="/business/dashboard">Home</a><a class="link__default" tabindex="0">Log Out</a></div>            </div>          </div>        </header>        <div>          <div class="wrapper">            <div class="grid">              <div class="grid__item     ">                <h1>Dashboard</h1></div>            </div>          </div>        </div>        <footer class="footer__footer">          <div class="wrapper">            <div class="grid">              <div class="grid__item     ">                <ul>                  <li><a target="_blank" href="/static/about">About</a></li>                  <li><a target="_blank" href="/static/accessibility">Accessibility</a></li>                  <li><a target="_blank" href="/static/cookies">Cookies</a></li>                  <li><a target="_blank" href="/static/privacy">Privacy</a></li>                </ul>              </div>            </div>          </div>        </footer>      </div>    </body>    </html>

3 Answers

Answers 1

If I am right, you are trying to achieve something like this.

<header id="header" height="120px"></header> <div    id="content" height="fill the rest of the height"></div> <footer id="footer" height="120px"></footer> 

In this case you will need to use CSS flex. Flex works fine horizontally without any fix, because by default any Block level element has width=100% i.e fills the whole available width of the parent. But it does not have a default height. The height of a block element is calculated as a total of all it's children's height. A div's default height is it's content's height. Even the <html>,<body> tags does not span the whole height of the window, it spans the height of it's contents.

So to make flex work vertically and divide your screen into header,footer and auto-adjusting content, you need to set height starting from the top, set <html>,<body> and #root to 100%

html, body, #root {    height: 100%;    margin: 0;    paddding: 0; } 

Now your #root div is occupying the whole screen height, so you can set your header,footer and contents height using flex.

#root {    display: flex;    flex-direction: column; } header {     height: 120px; } #content {     flex: 1;     overflow-y: auto; /* scrollbar for content */ } footer {     height: 120px; } 

This same work of flex can be done by javascript

We run a javascript code that runs when the page is loaded, calculates the screen height and assign the perfect height for the content div, that solves it nice and neat.

window.onload = function () {     var headerHeight = document.getElementById('header').clientHeight;     var footerHeight = document.getElementById('footer').clientHeight;     var contentheight = screen.availHeight - headerHeight - footerHeight;     document.getElementById('content').style.height = contentheight + 'px'; } 

And for centering the <h1> header, just use text-align property, it's enough.

h1 {     text-align: center; } 

You don't need to set vertical-align to middle unless your <h1> tag has a height specified.

Answers 2

html {    min-height: 100%;    position: relative;  }    body {    height: 100%;    background-color: #f7f7f4;  }    #root {    height: 100%;    padding-bottom: 170px;  }    .wrapper {      max-width: 750px;  }    .grid {      list-style: none;      margin: 0;      padding: 0;      margin-left: -30px;  }    .grid__item {      display: inline-block;      padding-left: 30px;      vertical-align: top;      width: 100%;      -webkit-box-sizing: border-box;      box-sizing: border-box;  }    .one-half {      width: 50%;  }    .private-banner__container {      height: 98px;  }    .private-banner__layout {      width: 100%;      height: 100%;      display: table;  }    .private-banner__right, .private-banner__left {      display: table-cell;      vertical-align: middle;  }    .footer__footer {      padding-top: 48px;      padding-bottom: 48px;  }    ul {      margin-left: 38px;      margin-left: 2.375em;  }    .footer__footer ul li:not(last-of-type) {      margin-right: 48px;  }    .footer__footer li {    display: inline;  }     .grid__item.db {    display: flex;    align-items: center;    justify-content: center;  }
<html lang="en">      <body>      <div id="root">        <header role="banner">          <div class="wrapper private-banner__container">            <div class="grid private-banner__layout">              <div class="grid__item one-half     private-banner__left"><h1>Logo</h1></div>              <div class="grid__item one-half     private-banner__right"><a href="/business/dashboard">Home</a><a class="link__default" tabindex="0">Log Out</a></div>            </div>          </div>        </header>        <div>          <div class="wrapper">            <div class="grid">              <div class="grid__item db">                <h1>Dashboard</h1></div>            </div>          </div>        </div>        <footer class="footer__footer">          <div class="wrapper">            <div class="grid">              <div class="grid__item">                <ul>                  <li><a target="_blank" href="/static/about">About</a></li>                  <li><a target="_blank" href="/static/accessibility">Accessibility</a></li>                  <li><a target="_blank" href="/static/cookies">Cookies</a></li>                  <li><a target="_blank" href="/static/privacy">Privacy</a></li>                </ul>              </div>            </div>          </div>        </footer>      </div>    </body>    </html>

Answers 3

vertical-align:middle CSS property along with text-align:center. I always try and keep it simple, in other words unless you must add a wrapper element, don't. So, that was the final thing I did was to remove some unnecessary div nesting you had in there.

Specifically, all I changed was that I added:

h1{ vertical-align:middle; text-align:center; } 

and then removed the grid-item and grid divs.

html {    min-height: 100%;    position: relative;  }    body {    height: 100%;    background-color: #f7f7f4;  }    #root {    height: 100%;    padding-bottom: 170px;  }    .wrapper {      max-width: 750px;  }    .grid {      list-style: none;      margin: 0;      padding: 0;      margin-left: -30px;  }    .grid__item {      display: inline-block;      padding-left: 30px;      vertical-align: top;      width: 100%;      -webkit-box-sizing: border-box;      box-sizing: border-box;  }    .one-half {      width: 50%;  }    .private-banner__container {      height: 98px;  }    .private-banner__layout {      width: 100%;      height: 100%;      display: table;  }    .private-banner__right, .private-banner__left {      display: table-cell;      vertical-align: middle;  }    .footer__footer {      padding-top: 48px;      padding-bottom: 48px;  }    ul {      margin-left: 38px;      margin-left: 2.375em;  }    .footer__footer ul li:not(last-of-type) {      margin-right: 48px;  }    .footer__footer li {    display: inline;  }    h1{  vertical-align:middle;  text-align:center;  }
<html lang="en">      <body>      <div id="root">        <header role="banner">          <div class="wrapper private-banner__container">            <div class="grid private-banner__layout">              <div class="grid__item one-half     private-banner__left"><h1>Logo</h1></div>              <div class="grid__item one-half     private-banner__right"><a href="/business/dashboard">Home</a><a class="link__default" tabindex="0">Log Out</a></div>            </div>          </div>        </header>        <div>                  <h1>Dashboard</h1>          </div>        <footer class="footer__footer">          <div class="wrapper">            <div class="grid">              <div class="grid__item     ">                <ul>                  <li><a target="_blank" href="/static/about">About</a></li>                  <li><a target="_blank" href="/static/accessibility">Accessibility</a></li>                  <li><a target="_blank" href="/static/cookies">Cookies</a></li>                  <li><a target="_blank" href="/static/privacy">Privacy</a></li>                </ul>              </div>            </div>          </div>        </footer>      </div>    </body>    </html>

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment