woojoo666
woojoo666

Reputation: 7921

Extend div to bottom of page (only HTML and CSS)

Its a very simple problem but I can't seem to find a suitable solution online. I want to have a list of elements in natural flow with the last element extended to the bottom of the page. So if I have

<div id="top" style="height:50px;"></div>
<div id="bottom" style="background:lightgrey;"></div>

I need element bottom to extend from the bottom of top to the bottom of the page. Any solution that uses only html and css is welcome, and you can add container divs or anything, as long as I can get dynamic resizing of the bottom div

EDIT: I don't want to hard-code any values for bottom, because I want bottom to adjust if top is resized

here's a fiddle for all your fiddling needs: http://jsfiddle.net/8QnLA/

Upvotes: 36

Views: 65057

Answers (3)

Martin Gressler
Martin Gressler

Reputation: 31

Solution for react or vanilla JS.

const useExpandToPageBottom = () => {
    const ref = useRef<HTMLDivElement | null>(null);
    useEffect(() => {
      if (!ref.current) return;
      const { y } = ref.current.getBoundingClientRect();
      ref.current.style.height = `${window.innerHeight - y}px`;
    });

    return { ref };
};

Use hook like so:

const { ref } = useExpandToBottom()

<div ref={ref}>Div to expand</div>

Upvotes: 0

Danield
Danield

Reputation: 125651

Solution: #1: css tables:

html, body {
  height: 100%;
  width: 100%;
}
body {
  display: table;
  margin: 0;
}
#top, #bottom {
  width: 100%;
  background: yellow;
  display: table-row;
}
#top {
  height: 50px;
}
#bottom {
  background: lightgrey;
  height: 100%;
}

html, body {
  height: 100%;
  width: 100%;
}
body {
  display: table;
  margin: 0;
}
#top, #bottom {
  width: 100%;
  background: yellow;
  display: table-row;
}
#top {
  height: 50px;
}
#bottom {
  background: lightgrey;
  height: 100%;
}
<div id="top" style="height:50px;"><span>A header</span></div>
<div id="bottom" style="background:lightgrey;"><span>The content area - extends to the bottom of the page</span></div>

Codepen #1 (little content)

Codepen #2 (lots of content)

Solution #2: Using calc and viewport units

#top {
  height: 50px;
  background: yellow;
}
#bottom {
  background: lightgrey;
  min-height: calc(100vh - 50px);
}

body {
  margin: 0;
}
#top {
  height: 50px;
  background: yellow;
}
#bottom {
  background: lightgrey;
  min-height: calc(100vh - 50px);
}

Where `min-height: calc(100vh - 50px);` means:

'Let the height of the content div be **at least** 100% of the viewport height minus the 50px height of the header.'
<div id="top" style="height:50px;"><span>A header</span></div>
<div id="bottom" style="background:lightgrey;"><span>The content area - extends to the bottom of the page</span></div>

Codepen #1 (little content)

Codepen #2 (lots of content)

Solution #3 - Flexbox

body {
  margin: 0;
  min-height: 100vh;
}
body {
  display: flex;
  flex-direction: column;
}
#top {
  height: 50px;
  background: yellow;
}
#bottom {
  background: lightgrey;
  flex: 1;
}

body {
  margin: 0;
  min-height: 100vh;
}
body {
  display: flex;
  flex-direction: column;
}
#top {
  height: 50px;
  background: yellow;
}
#bottom {
  background: lightgrey;
  flex: 1;
}
<div id="top" style="height:50px;"><span>A header</span></div>
<div id="bottom" style="background:lightgrey;"><span>The content area - extends to the bottom of the page</span></div>

Codepen #1 - little content

Codepen #2 - lots of content

Upvotes: 70

Explosion Pills
Explosion Pills

Reputation: 191819

Set the height of html, body to 100%. Then, you can set the last <div>'s height to 100% and it will be as tall as the window. Since you probably don't want scrolling, you can set overflow: hidden on the html, body as well.

http://jsfiddle.net/GKbzx/

Upvotes: 3

Related Questions