1

So I am just starting to learn some basic CSS and now I have come across some behavior I don't understand. I have a <div> inside an <article> and the <div>s height is set to 100%. Now if all the parents parents of the <div> have their height specified then the height is equal to the parents height, however when it is not the case then <div>s height is smaller.

Here is a simple example when not all heights are specified:

html {
  height: 100%;
}

article {
  background-color: red;
  height: 100%;
}

#side-nav {
  background-color: blue;
  float: left;
  min-width: 10%;
  height: 100%;
  padding: auto;
  margin: 0;
}

#main-content {
  margin-left: 10%;
  width: 90%;
}
<!DOCTYPE html>
<html>
  <head>
    <title>some title</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <nav id="top-nav">
      <div id="main-nav-bar">
        <a class="nav-bar-opt">opt1</a>
        <a class="nav-bar-opt">opt2</a>
        <a class="nav-bar-opt">opt3</a>
      </div>
    </nav>
    <article id="article">
      <div id="side-nav">
        <ul>
          <li><a class="art-link">bullet</a></li>
          <li><a class="art-link">point</a></li>
          <li><a class="art-link">list</a></li>
        </ul>
      </div>
      <div id="main-content">
        <h1>
          title
        </h1>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris condimentum sodales nulla a imperdiet. Ut interdum rhoncus luctus. Fusce porttitor eu nulla eu consectetur. Vivamus et pretium dolor, quis lobortis mauris. Quisque dignissim auctor nisl placerat placerat. Vivamus ultrices leo nec tincidunt ornare. Nulla accumsan euismod metus nec congue. 
        </p>
        <h3>
          title
        </h3>
        <p>
         Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris condimentum sodales nulla a imperdiet. Ut interdum rhoncus luctus. Fusce porttitor eu nulla eu consectetur. Vivamus et pretium dolor, quis lobortis mauris. Quisque dignissim auctor nisl placerat placerat. Vivamus ultrices leo nec tincidunt ornare. Nulla accumsan euismod metus nec congue.
        </p>
        <ul>
          <li>another</li>
          <li>bullet</li>
          <li>point</li>
          <li>list</li>
        </ul>
      </div>
    </article>
  </body>
</html>

note that the <div>(colored in blue) is smaller than the direct parent <article>(colored in red).

So now my question is if there is a reason for this behavior and if there is some workaround to avoid specifying all heights?

Girisha C
  • 1,922
  • 1
  • 12
  • 20
iaquobe
  • 555
  • 1
  • 6
  • 23

3 Answers3

2

You don't specify a height for your <body>, as such the rest of the height is stuck trying to figure out what it's 100% of.

Culyx
  • 529
  • 10
  • 18
  • you also need to remove the `height: 100%` property from the html selector – Yvonne Aburrow Oct 03 '18 at 18:34
  • 1
    @YvonneAburrow Absolutely not! – Asons Oct 03 '18 at 18:36
  • well i did with my solution – Yvonne Aburrow Oct 03 '18 at 18:38
  • @YvonneAburrow No, you didn't, as when viewed full page, your solution doesn't fill the browser window. – Asons Oct 03 '18 at 18:39
  • ah, thanks, missed that – Yvonne Aburrow Oct 03 '18 at 18:41
  • yes you are right, sorry about that – Yvonne Aburrow Oct 03 '18 at 18:48
  • I thought it meant 100% of the parents size, doesn't the `
    ` still have a size even if it isn't in written in the code?
    – iaquobe Oct 03 '18 at 19:11
  • @jaklh width does a better job of that since alot of elements sort of figure that out automatically (like block elements, which are basically 100% width to start with); height on the other hand tends to expand based on the content. I'd recommend messing around with some Dev tools to see what exactly is going on with your DOM. – Culyx Oct 03 '18 at 21:33
  • @jaklh When using `height: 100%`, as you do on the left _side-nav_ `div`, the 100% is calculated on the parents _**set**_ height, not the height its content sized it to, and since the `article` doesn't have one set, explicit using `height: x`, it use the default `auto`, hence itself resolves to _auto_ and won't fill the parent's height. Hope this make sense. – Asons Oct 04 '18 at 05:31
  • @LGSon ah, thanks, so this is what I did not know: "the 100% is calculated on the parents set height, not the height its content sized it to". – iaquobe Oct 04 '18 at 17:38
0

Please set body{height: 100%}, will set the height of both blue and red to 100%, as shown in the below working snippet, hope it helps :)

html, body {
  height: 100%;
}

article {
  background-color: red;
  height: 100%;
}

#side-nav {
  background-color: blue;
  float: left;
  min-width: 10%;
  height: 100%;
  padding: auto;
  margin: 0;
}

#main-content {
  margin-left: 10%;
  width: 90%;
}
<!DOCTYPE html>
<html>
  <head>
    <title>some title</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <nav id="top-nav">
      <div id="main-nav-bar">
        <a class="nav-bar-opt">opt1</a>
        <a class="nav-bar-opt">opt2</a>
        <a class="nav-bar-opt">opt3</a>
      </div>
    </nav>
    <article id="article">
      <div id="side-nav">
        <ul>
          <li><a class="art-link">bullet</a></li>
          <li><a class="art-link">point</a></li>
          <li><a class="art-link">list</a></li>
        </ul>
      </div>
      <div id="main-content">
        <h1>
          title
        </h1>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris condimentum sodales nulla a imperdiet. Ut interdum rhoncus luctus. Fusce porttitor eu nulla eu consectetur. Vivamus et pretium dolor, quis lobortis mauris. Quisque dignissim auctor nisl placerat placerat. Vivamus ultrices leo nec tincidunt ornare. Nulla accumsan euismod metus nec congue. 
        </p>
        <ul>
          <li>another</li>
          <li>bullet</li>
          <li>point</li>
          <li>list</li>
        </ul>
      </div>
    </article>
  </body>
</html>
Girisha C
  • 1,922
  • 1
  • 12
  • 20
  • if you set both html and body to 100%, body ends up with a scroll bar on it. Only body needs to be 100% – Yvonne Aburrow Oct 03 '18 at 18:33
  • @YvonneAburrow Yes, and therefore a `margin: 0` is needed on the `body`, still, the `body` (and `html`) needs a height for it all to work – Asons Oct 03 '18 at 18:38
  • 1
    @YvonneAburrow, true it will have a scrollbar only in case when body tags margin is not set to zero, try `body{margin: 0}` scrollbar will not be shown. – Girisha C Oct 03 '18 at 18:39
  • sorry, yes you are right, both `html` and `body` need a height of 100% – Yvonne Aburrow Oct 03 '18 at 18:47
  • Ok, so this is where the next problem comes in. If my page ends up being bigger then my screen, the text will overflow but the background color stops as soon as I scroll. I know there is `min-height` but for some reason it doesn't seem to work when the page is smaller than the screen. So now my page is either not formatted correctly if it is bigger than my screen or if it is smaller. Is there a way to make it properly formatted no matter the size? – iaquobe Oct 03 '18 at 19:29
  • you could set a container `div` with `height: 100%` and `overflow: hidden`, and within that, a scrolling container with `overflow: auto` – Yvonne Aburrow Oct 04 '18 at 15:59
0

Instead of floating the side-nav element to the left, you need to use flex.

Then you don't need to specify height on every element, as requested.

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
}

main {
  height: 98%;
  display: flex;
  flex-direction: row;
  flex: 1 1 auto; /* grow shrink amount */
}

article {
  background-color: #ffeeee;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 0.5em;
}

#side-nav {
  background-color: #eeeeff;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 11%;
  padding: auto;
  margin: 0;
}

#side-nav ul {
  list-style-type: none;
  margin-left: -2.5em;
}
  
#side-nav li a {
  display: block;
  white-space: nowrap;
  padding: 0.25em;
}
  
#side-nav li a:hover {
  display: block;
  background-color: #0000ff;
  color: #fff;
  cursor: pointer;
}
<!DOCTYPE html>
<html>
  <head>
    <title>some title</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <nav id="top-nav">
      <div id="main-nav-bar">
        <a class="nav-bar-opt">opt1</a>
        <a class="nav-bar-opt">opt2</a>
        <a class="nav-bar-opt">opt3</a>
      </div>
    </nav>
    <main>
      <div id="side-nav">
        <ul>
          <li><a class="art-link">nav</a></li>
          <li><a class="art-link">list</a></li>
          <li><a class="art-link">and</a></li>
          <li><a class="art-link">some</a></li>
          <li><a class="art-link">more</a></li>
          <li><a class="art-link">items</a></li>
        </ul>
      </div>
      <article id="article">
        <h1>
          title
        </h1>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris condimentum sodales nulla a imperdiet. Ut interdum rhoncus luctus. Fusce porttitor eu nulla eu consectetur. Vivamus et pretium dolor, quis lobortis mauris. Quisque dignissim auctor nisl placerat placerat. Vivamus ultrices leo nec tincidunt ornare. Nulla accumsan euismod metus nec congue. 
        </p>
        <h3>
          title
        </h3>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris condimentum sodales nulla a imperdiet. Ut interdum rhoncus luctus. Fusce porttitor eu nulla eu consectetur. Vivamus et pretium dolor, quis lobortis mauris. Quisque dignissim auctor nisl placerat placerat. Vivamus ultrices leo nec tincidunt ornare. Nulla accumsan euismod metus nec congue.
        </p>
        <ul>
          <li>another</li>
          <li>bullet</li>
          <li>point</li>
          <li>list</li>
        </ul>
      </article>
    </main>
  </body>
</html>
Girisha C
  • 1,922
  • 1
  • 12
  • 20
Yvonne Aburrow
  • 2,602
  • 1
  • 17
  • 47