6

i'm building a layout that has dynamic height (as most people do). i've been searching for a while but have not found similar case with mine. so here it is, my simplified code:

html:

<div id="body"><div id="content">
content
</div>
</div>
<div id="footer">
    abc
</div>

css:

#footer{
    position: absolute;
    bottom: 0;
    width: 100%;
    background: #ddd;
}
#body{
    padding: 60px 50px 70px 50px;
    position: relative;
    min-height: calc(100% - 130px);
}
#content{
    font-family: verdana;
    margin-left: 200px;
    border-left: 5px solid #ddd;
    padding: 0 0 0 10px;
    min-height: 100%;
    min-width: 500px;
}
body{
    margin:0;
    overflow-y:scroll;
    height:100%;
    position:relative;
}
html{
    height:100%;
}

the problem is when i use that code, the content height is not calculated properly and the result look like this fiddle while what i'm trying to do is when the content is short, it should look like this and when the content is long, it should look like this.

if i change the min-height to height, when the content is short, i get what i wanted, but when the content is long, i get this annoying layout

it seems calc cannot read the height attribute when it is not specified (using min-height), but if the height is specified, then i can't get dynamic height, is there any other solution to achieve this?

PS: what i'm trying to do is to make the border of #content stretches according to its content with minimum height of a page height

note:

another strange fact is, actually my current code is working on latest chrome and IE, but have this problem on latest firefox and opera. i was trying to reproduce the problem using jsfiddle, and to my awe, all of the browsers have the same issue, i have included all the related html and css (copy the generated html and css) to jsfiddle only to find that my code is not working at all, i'm very confused

am05mhz
  • 2,727
  • 2
  • 23
  • 37

2 Answers2

5

Why not use flex boxes? It sounds like you want a sticky footer - that is, the footer is at the bottom of the viewport when the content is not very high, but it is at the bottom of the content when the content exceeds the viewport height. This is very similar to the holy grail design. Here is an HTML5+CSS3 solution that does not use JavaScript:

* {
    /* personal preference */
    margin: 0;
    padding: 0;
}
html {
    /* make sure we use up the whole viewport */
    width: 100%;
    height: 100%;
    /* for debugging, a red background lets us see any seams */
    background-color: red;
}
body {
    /* make the body a vertical flex container */
    /* https://css-tricks.com/snippets/css/a-guide-to-flexbox/ */
    display: flex;
    flex-direction: column;
    /* make sure we use the full width but allow for more height */
    width: 100%;
    min-height: 100%; /* this helps with the sticky footer */
}
main {
    /* Allow the content to grow but not shrink */
    flex-grow: 1;
    flex-shrink 0;
    /* for debugging, a blue background lets us see the content */
    background-color: skyblue;
}
footer {
    /* do not allow the footer to shrink */
    flex-shrink: 0;
    /* for debugging, a gray background lets us see the footer */
    background-color: gray;
}
<main>
    <p>This is the content. Resize the viewport vertically to see how the footer behaves.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
    <p>This is the content.</p>
</main>
<footer>
    <p>This is the footer. Resize the viewport horizontally to see how the height behaves when text wraps.</p>
    <p>This is the footer.</p>
</footer>

If you don't want to copy the code into a fiddle yourself, I've done that for you. You may need to use some vendor prefixes if you want to support older browsers - flex boxes are relatively new as of the writing of this post.

LB--
  • 2,506
  • 1
  • 38
  • 76
  • 1
    thanks for your answer, as this is an old question, i do not track it anymore, and just now i logged to my SO and find your answer, I have not test it in my project as i have changed the design, but your answer is the closest to my desired result, so i'll mark your answer as the best answer – am05mhz Jun 06 '15 at 09:34
0

Per our conv, you're after the ability to set the min-height so it fills the viewport with room for the footer, but as the content grows, the content div should too - pushing the footer down.

* { box-sizing: border-box } 
html,body { height: 100%; padding: 0; margin: 0 }
#content { min-height: 90%; outline: 1px solid blue } 
#footer { background: gray; height: 10%; }

It just takes setting the min-height using percentages. I'm using the border-box box sizing mode which is easier to work with but not required, in case you care about older IE

fiddle

helion3
  • 34,737
  • 15
  • 57
  • 100
  • what i'm trying to do is set the `#content` element as equal as browser height (minus some padding) when the content does not exceed a browser height, and when it does exceed the browser height, the `#content` element need to grow, and the `#footer` must be at the bottom of the `#content`, max-height will not do, as it will cut of long content – am05mhz Feb 01 '14 at 05:48
  • I'm still not following. min-height would allow you to set a starting height for the div, and would allow the div to grow larger when the content is too long. – helion3 Feb 01 '14 at 05:51
  • that is the point, but its not working properly, have you click the links i've provided?, thx btw. – am05mhz Feb 01 '14 at 05:54
  • There are multiple ways to fix this but it depends on what you want the footer to do. Should it be fixed to the screen bottom and the content scrolls behind it? Or should it simply be at the bottom of the content div, no matter it's length. - example: http://jsfiddle.net/964AR/14/ – helion3 Feb 01 '14 at 05:57
  • it should be at the bottom of content div only when the content div is very long, and it should be at the bottom of the viewport when the content is short, when using `min-height`, the footer works as expected, but the border on the content div is not stretched to the footer, meaning `min-height` on the content div is not working – am05mhz Feb 01 '14 at 06:02
  • thanks for your answer, but it would give another problem as the footer height is depending on the contents length – am05mhz Feb 01 '14 at 06:11
  • You meant the footer height needs to be adjustable too? Sounds like you need javascript to calculate the heights then. – helion3 Feb 01 '14 at 06:16
  • no, what i mean, is your solution would make the footer height changes as the content change, lets say total page height is 100px then 10% footer is 10px, and when total page height is 200px then footer height is 20px, so that is not what i want. – am05mhz Feb 01 '14 at 06:19
  • Then you need to use javascript. There's no stable way for an element to dynamically adjust height based on the fixed height of an element that follows in pure css. – helion3 Feb 01 '14 at 06:21
  • well, i was hoping `calc` and `min-height` can solve my problem, but as it is now, it seems pretty buggy, seems i have to apply `height` with JS when the content is short, well thank you anyway – am05mhz Feb 01 '14 at 06:29