I have a very simple webpage with a problem. It ahs 3 divs that sit ontop of each other, the header, content then footer.
I want my footers height to expand to the bottom of the page. How can I do this?
The header has a constant height, the content will vary in height depending on the content received from an AJAX call. So I cant explicitly set it.
Heres my JSFiddle: http://jsfiddle.net/5U6ZB/2/embedded/result/
<div id="header"></div>
<div id="content">
<!-- height is dynamic sometimes it will be full of divs that makes it
longer than the screen height other times it only has 1 div -->
</div>
<div id="footer">
<!-- How do I make the footer height fill up the rest of the page height? -->
</div>
body { background-color: white; }
div { width: 100%; }
#header {
height: 400px;
background-color: RGB(200,200,200);
}
#content {
}
#footer {
background-color: RGB(112,112,112);
/*How do I make the footer height fill up the rest of the page height?*/
}
html {
background-color:#093; /*the footer color*/
}
body {
background-color: #f6f; /*the body color*/
}
Sounds like the easiest solution in your case would be to make the body background the same colour as the footer and make your content white. This would give the illusion of the footer going all the way to the bottom.
body { background-color:RGB(112,112,112); }
div { width: 100%; } /* Divs are block elements which automatically take 100% width so this is redundant. */
#header {
height: 400px;
background-color: RGB(200,200,200);
}
#content {
background-color:white;
}
#footer {
background-color: RGB(112,112,112);
}
:root {
background-color: siteBackgroundColor;
}
body {
background-color: footerColor;
}
This doesn't really expand the footer, but visually expands its background color.
A similar approach to fayerth's, this will adjust height dynamically when the browser is resized (and is based on jQuery).
Instead of resizing the footer directly, I added the additional empty element <div class="flex-footer"> and resized that instead. My thought is that it should give a less jittery effect if the footer contains a bunch of elements as well as not fussing with any children of the footer that are sized relative to the parent.
Your CSS should then apply whatever background color necessary.
Note my comment about negative margins. This was necessary in my case since the design required the use of negative margins. I've included that bit in case yours does as well.
$(function(){
$(window).load(resizeFooter);
$(window).resize(resizeFooter);
});
// Dynamically resize footer to fill page, IE8 doesn't like this.
function resizeFooter() {
var windowHeight = window.innerHeight;
var headerHeight = $("header").height();
var contentHeight = $("div.main").height();
var footerHeight = $("footer").height();
// 107 references a negative margin in header - you'll need to account for this if necessary
var flexFooter = windowHeight - (headerHeight + contentHeight + footerHeight - 107);
$(".flex-footer").css("min-height", flexFooter);
}
In pure CSS, it's not possible, but if you want to use some fancy Javascript, you can dynamically change the height of the footer to stretch the remaining height, assuming the content doesn't already do it for you.
var header = document.getElementById("header"),
content = document.getElementById("content"),
footer = document.getElementById("footer"),
height = window.screen.height - header.clientHeight - content.clientHeight;
footer.clientHeight = (height < 150) ? 150 : height; // Sets a minimum height of 150px
It's usually better to follow SynXsiS's suggestion though, as it tends to give a nicer appearance. In the end, it really depends on the way you design the look and feel of your page.
very simple, and works for me :)
footer{ position:absolute; width:100%; top: (read below); }
you can try with diferent percents values in top property, when the footer take the desired place in your screen, that percent will apply to all resolutions :)
I am tweaking a wordpress theme - and have the same problem. But - if I implement a sticky footer, it actually partially scrolls away with the content. Wordpress is a mess so I'm not sure why it's doing this - but what I need is to let the footer sit below the main content, but THEN fill the rest of the screen so it doesn't look silly on shorter pages.
Any ideas of an easy CSS fix other than the color trick? (which I may do ;)
Claudia
Related
I have bootstrap accordion in which all panels are collapsed except first one. The height of body is more than window height when the page first loads. The footer is stuck to the bottom of the page initially, and it remains at the bottom if I expand another panel from accordion.
The problem is that, when all the panels are collapsed the body is of less height than the window height. In this scenario the footer is not sticking to the bottom of the window, It positions in the middle of the window where accordion ends.
I tried capturing the resize event, so if the body is of less height than the window then I would stick the footer to the bottom of the window else to bottom of the body, but resize doesn't work in case of accordion trigger.
Here is something I tried :
$(window).resize(function(){
footPosition();
});
function footPosition()
{var bodyHeight = $("body").height();
var vwptHeight = $(window).height();
if (vwptHeight > bodyHeight) {
$("footer#pageFooter").css("position","absolute").css("bottom",0).css("width","100%");
}else{
$("footer#pageFooter").css("position","static").css("bottom",0).css("width","100%");
}
}
Sorry I can't give you the accordion code, its too large.
But its a simple bootstrap accordion and I am stuck on this problem from last two days.
please help.
What you’re looking for is CSS Sticky Footer
<div id="footer">
</div>
#footer {
position: relative;
bootom: 0;
margin-top: -180px; /* negative value of footer height */
height: 180px;
clear:both;
}
Code
Demo
The basic form of HTML looks like this:
<div class="home">
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<!-- blah, blah, blah! -->
</main>
</div>
</div>
W.r.t the HTML, I am trying to make the element #main fill the entire height of the browser viewport using JavaScript/jQuery like so:
jQuery(document).ready(function($){
// get height of browser viewport
var window_h = $(window).height();
// get height of the jumbotron, i.e. element #main
var jumbotron_h = $('.home #main').outerHeight(true);
// calculate necessary padding (top/bottom) to apply on #main so that the
// element's height is equal to that of the browser's viewport,
// and its contents are centered vertically
if (window_h > (jumbotron_h + 60)) {
var jumbotron_padding = (window_h - jumbotron_h)/2
} else {
var jumbotron_padding = 30
}
// apply calculated padding on the element dynamically
$('.home #main').attr('style', 'padding-top:'+jumbotron_padding+'px;padding-bottom:'+jumbotron_padding+'px;');
});
As clearly explained in the comments in the code above, the code automatically calculates the necessary padding to be applied on #main so that its height is equal to that of the browser's viewport.
It works well, except, the calculated padding (and therefore the resultant height) is wrong in one case that I was able to identify.
Easily reproducible at least on Windows 7, Google Chrome browser (latest) when you resize the browser window to 567x724 px, which implies 551x611 px viewport size, (you can use an extension like Window Resizer), you'll notice that the element's calculated padding results in its height being larger than that of the browser's viewport.
Why is this happening? I wasn't able to reproduce the same at any other resolution. What could I possibly be missing here?
First off, Jquery's .outerheight() function includes padding, which means that when you measure the height of your #Main element after this function runs the first time, it will equal the window.height. In other words - it will look awful when you resize your browser. You can see this in action on this fiddle when you resize the browser window the old-fashioned way. You can use margins instead, but then you'll have to adjust your CSS quite a bit. Even then, resizing the window still looks awful and buggy and has inconsistent results across browsers. You can see that on this fiddle.
The specific bug you're referring to is probably due to inconsistent math when you resize your window - a combination of your use of padding (which is included in .outerheight() as mentioned above) and the viewport size not being easily divisible by 2 (it's impossible to have half a pixel and different browsers will render that half a pixel differently).
I should also point out this line of code:
if (window_h > (jumbotron_h + 60)) {
var jumbotron_padding = (window_h - jumbotron_h)/2
} else {
var jumbotron_padding = 30
}
This forces your page to always be #main.height() + 60, which can be bigger than your viewable window, depending upon your window size. #main.height() comes out to around 200.5px (there we are with another half pixel).
Assuming that your goal is to vertically center the #Main element, your best bet is to use one of the many straight CSS methods available. The table method seems most applicable here because it is completely dynamic (and thus can be responsive) - simply create a single cell CSS table, use CSS valign, and build your entire page inside that cell. For older versions of IE you'll need to use a tiny hack (display:Inline-block;) to make it work.
HTML:
<div id="parent">
<div id="child">Content here</div>
</div>
CSS:
#parent {display: table;}
#child {
display: table-cell;
vertical-align: middle;
}
IE fix:
#child {
display: inline-block;
}
Based on #Thomas's answer, I've identified two possible solutions. I am going with the #2 solution considering better browser support for it.
1. Using the unit vh (viewport height). Browser support: IE9 and above.
CSS:
.home #primary { /* Parent */
display: table;
width: 100%;
}
.home #main { /* Child */
display: table-cell;
height: 100vh; /* 100% viewport height */
vertical-align: middle;
}
2. Dynamically setting height of parent (.home #primary) equal to that of browser's viewport.
JS:
jQuery(document).ready(function($){
var window_h = $(window).height();
var jumbotron_h = $('.home #main').height();
if (window_h <= (jumbotron_h + 60)) {
var window_h = jumbotron_h + 60
}
$('.home #primary').attr('style', 'height:'+window_h+'px;');
});
CSS:
.home #primary { /* Parent */
display: table;
width: 100%;
}
.home #main { /* Child */
display: table-cell;
height: 100%; /* 100% height of parent */
vertical-align: middle;
}
body {
height:100vh;
}
.element-to-be-centered {
font-size:1em;
text-align:center;
top: 49%;
-webkit-transform: translateY(-49%);
-ms-transform: translateY(-49%);
transform: translateY(-49%);
}
I have been doing quite a bit of experimenting lately with centering content. This technique will work without having to set a height on any element.
This will work in ie9 and up.
In your CSS
html, body {
height: 100%;
}
div, #main {
height: 100%;
}
Right, so instead of using sticky footer, I've decided to create a jQuery function that will change the size of my #mainContent div so that the footer can fit in nicely.
Basically what I'm trying to do is have
#mainContent { height: 100% - 40px; }
Where
#footer { height:40px; }
I came up with
$(window).resize(function() {
var mainContent = $('#mainContent').innerHeight() - 40;
$('#mainContent').css("height", mainContent);
});
but every time I resize, it simply shortens #mainContent by 40px instead of re-working what #mainContent is supposed to be, then -40px;
$(window).resize(function() {
var mainContent = $(document).height() - 80;
$('#mainContent').css("height", mainContent);
});
I feel like I'm missing something.
Please help.
Edit: header and footer are static (i.e. 40px each), I'd like to resize mainContent without having footer flow over it (because sticky footer uses margin-top:-40px;). I still want my footer to be at the bottom of the screen.
Edit2: added the second try.
I the only elements using your screen height are the mainContent div and the footer, and you decided to control your footer through your javascript+jquery function in a responsive way, use window or document height in order to compute the content div height as so:
var mainContent = $(window).height() -40;
var mainContent = $(document).height() -40;
An example to show it working as you required.
I coded for you a simple markup but enough to show you that it should work for you as well.
Its up to you to take care of reseting/considering any possible vertical margins that can be collapsing or whatever in order to obtain the correct figure to apply in the function.
I applied a min-height declaration for the mainContent rule just for my example. of course you dont need that at all as well as those horrible colors I used :)
The positionFooter function does not need to be so extended. I wrote it that way for a didactic purpose
Here the code:
$( function () {
function positionFooter() {
var wh = $(window).height();
var wc = wh - 80;
$('#mch').text(wc);
$("#mainContent").height(wc);
}
$(window).resize(positionFooter);
positionFooter();
});
Take care of identifiers , selectors, etc when you propagate this solution to your own code.
Any way, I cant imagine why you dont want to apply a full CSS solution instead of using javascript. But Ok. Its your call. Here is the fiddle. Enjoy!
Just give height and width of your div in %.
Check if it works for you.
This should do the trick
DEMO
$(document).ready(function(){
$(window).resize(function() {
var mainContent = $(window).height() - 80;
$('#mainContent').css("height", mainContent);
});
var mainContent = $(window).height() - 80;
$('#mainContent').css("height", mainContent);
});
Let me know if this doesn't work.
It keeps shortening because you hard coded a pixel value for the size. The size will not expand/shrink because of the hard coded value.
If you want to get the full height, than you would need to remove the px value you set before reading the height.
Like RaraituL said, you can use a sticky footer. Then, if you really want to do the 100% height stuff, you can do something like:
#mainContent { height: 100%; box-sizing:border-box; padding:0 0 40px;}
Add in all the vendor prefixes and you should have the correct sizing. See here for more about box-sizing.
You can use media query to load a different css file for a specific size of browser.
#media (min-device-width: 640px) { ... }
It's like this http://mediaqueri.es/
I'm not 100% sure this is what you're looking for - it sounds like you want #mainContent to fill up the whole window except the bottom 40px. If so, this ought to work for you:
Html:
<div id="mainContent">This is the main content</div>
<div id="footer">This is the footer</div>
CSS:
#mainContent {
position:absolute;
top:0;
left:0;
right:0;
bottom:40px;
background:#F0F0F0;
overflow:auto;
}
#footer {
position:absolute;
bottom:0;
left:0;
right:0;
height:40px;
background:#FCC;
}
Working example: http://jsfiddle.net/nvNRY/1/
Edit:
If you don't want #mainContent to act like a frame (i.e. with it's own scrollbar) then simply add 40px padding to the bottom of the body tag. Don't position #mainContent absolutely and it will butt up against the padding, whereas #footer will overlap the padding.
Edit 2:
Example with header and showing overflow:scroll is action: http://jsfiddle.net/nvNRY/2/
Here's a link to what I'll be referring to.
I'm having some trouble getting the background image to work the way I'd like it to.
I want the background to auto resize based on the width of the window, which it is already doing correctly. If you make your window smaller you'll see the background shrink with it.
Here's the issue. If you make your window wide (short) then the background will resize and go too high so you can't see the top of the background anymore (since the background is bottom positioned).
I want the background to be top position when you are at the top of the page, and as you scroll down it will slowly move to be bottom positioned. Sort of like the effect of an Android phone's background when you move left and right. Of course, keep in mind that I still want the background to auto-resize when you make the window smaller.
html {
background-color: #70d4e3;
height: 100%;
}
body {
height: 100%;
}
.background {
margin-top: 45px;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: -9999;
}
.banner {
margin: 0px auto;
width: 991px;
margin-bottom: -9px;
}
.content {
background: url("http://i.imgur.com/daRJl.png") no-repeat scroll center center transparent;
height: 889px;
margin: 0 auto;
width: 869px;
}
.innerContent {
padding: 30px;
}
<img src="http://i.imgur.com/6d5Cm.jpg" alt="" class="background" />
<div class="banner">
<img src="http://i.imgur.com/JptsZ.jpg" alt="" />
</div>
<div class="content">
<div class="innerContent">
testing
</div>
</div>
Maybe some javascript or jquery would be needed to achieve this.
Well, this was fun, thanks!
I hope you don't mind me taking the liberty to use percentages to make my life a little bit easier and possibly the script slightly more robust since I can reliably use floats with percentages.
What I did is make the layout, html and css comply with the rules you need for the bg to be animated properly, they stayed largely the same from what you had.
Then it was just a question of figuring out the calculations needed with the right properties to figure out the percentage you were from the top, the *20 is actually the amount of space 'left' to fill by the background image in percentages (as the background height is 80%).
They I moved the calculations to a function so I could call that on scroll and on window resize, making sure it's initiated on any event that modifies the window somehow...
Didn't do extensive testing but it worked in Chrome and I'm tired :p
I believe this is what you are looking for:
http://jsfiddle.net/sg3s/RSqrw/15/ See edit 2
If you wanted this the other way arround just make the page background start at the top and modify that:
http://jsfiddle.net/sg3s/RSqrw/14/ See edit 2
Edit:
As a bonus, and since I had never actually written jquery script as a 'plugin', I decided to convert this into one. What I came up with should be easy to implement and use!
http://jsfiddle.net/sg3s/RSqrw/52/ See Edit 3
Functionality successfully tested in Chrome, Firefox 3.6, IE9 + compatibility mode
Edit 2:
Reading the question again checking if I did it right I noticed I didn't quite do what you want, so I updated the link in the first edit which gives you a plugin in which you can have several options for the scrolling background. It retains my 'old' interpetation while also doing what you want... Read comments in code for some extra descriptions.
Edit 3:
As I went to work today I was bothered with the fact that my plugin 'try' was a little bloated. And as you mentioned in the comment it didn't quite fit the requirements.
So I rewrote it to only do what you want and not much more, tested in Chrome Firefox, IE9 +compat etc etc.. This script is a lot cleaner.
http://jsfiddle.net/sg3s/vZxHW/
You can chose to make the background stick to the top or bottom if the height fits in the window. Nothing else, but that is already more than enough to do some pretty cool stuff :p
An exact solution: Fiddle: http://jsfiddle.net/srGHE/2/show/
View source
Thanks for the challenge. See below for the solution, which is complying with all requirements, including recommended yet optional (with steps on how to remove these) features. I only show the changed parts of your page, with an explanation after each section (CSS, HTML and JavaScript):
CSS (changes):
html,body{
margin: 0;
height: 100%;
padding: 0;
}
body{
background-color: #70d4e3;
}
#background { /*Previously: .background*/
/*Removed: margin-top: 45px;
No other changes*/
}
#banner /*Previously: .banner; no other changes */
#content /*Previously: .content; no other changes */
#innerContent /*Previously: .innerContent; no other changes */
Explanation of CSS revisions:
margin-top:45px at the background is unnecessary, since you're absolutely positioning the element.
All of the elements which are unlikely to appear more than once should be selected via the id (#) selector. This selector is more specific than the class selector.
HTML (changes):
All of the class attributes have been replaced by id. No other changes have been made. Don't forget to include the JQuery framework, because I've implemented your wishes using JQuery.
JavaScript (new):
Note: I have added a feature which you didn't request, but seems logical. The code will automatically reserve sufficient margin at the left side of the window in order to always display the background. Remove anything between the marked comments if you don't want this feature.
$(document).ready(function(){
//"Static" variables
var background = $("#background");
var marginTop = parseFloat(background.css("margin-top")) || 0;
var bannerWidth = $("#banner").width(); /*Part of auto left-margin */
var extraContWidth = (bannerWidth - $("#content").width())/2; /*Same as above*/
function fixBG(){
var bodyWidth = $("body").width();
var body_bg_width_ratio = bodyWidth/1920;
var bgHeight = body_bg_width_ratio * 926; //Calcs the visible height of BG
var height = $(document).height();
var docHeight = $(window).height();
var difHeight = bgHeight - docHeight;
var scrollDif = $(document).scrollTop() / (height - docHeight) || 0;
/*Start of automatic left-margin*/
var arrowWidth = body_bg_width_ratio * 115; //Arrow width
if(bodyWidth - bannerWidth > arrowWidth*2){
$("body > div").css("margin-left", "auto");
} else {
$("body > #banner").css("margin-left", arrowWidth+"px");
$("body > #content").css("margin-left", (arrowWidth+extraContWidth)+"px");
}
/*End of automatic left-margin*/
if(difHeight > 0){
background.css({top:(-scrollDif*difHeight-marginTop)+"px", bottom:""});
} else {
background.css({top:"", bottom:"0"});
}
}
$(window).resize(fixBG);
$(window).scroll(fixBG);
fixBG();
});
Explanation of the JavaScript code
The size of the background is determined by calculating the ratio of the background and document width. The width property is used, because it's the most reliable method for the calculation.
Then, the height of the viewport, document body and background is calculated. If applicable, the scrolling offset is also calculated, to prepare the movement of the background, if necessary.
Optionally, the code determines whether it's necessary to adjust the left margin (to keep the background visible at a narrow window).
Finally, if the background arrow has a greater height than the document's body, the background is moved accordingly, taking the scrolling position into account. The arrow starts at the top of the document, and will move up as the user scrolls (so that the bottom side of the arrow will be the bottom of the page when the user has fully scrolled down). If it's unnecessary to move the background, because it already suits well, the background will be positioned at the bottom of the page.
When the page has finished loading, this functionality is added to the Resize and scroll events, so that the background is always at the right location.
If you've got any other questions, feel free to ask them.
well, I'm not sure if I understand you and why do you want to do that, but you can try adding 2 backgrounds (see http://www.css3.info/preview/multiple-backgrounds/ ), one with the top bg and another with the bottom bg but I think that if the page is not too long it will cause issues, so the other answer with pure CSS is as follows: first add 3 horizontal divs with 100% width. Top div will have your top bg and its height, middle div will be transparent and auto height and bottom div will have your bottom bg and its height. All divs will have a 0 z-index. Then create a higher z-index div to act as a container and you'll be set. If I understand your question right, that's the close I can think of to achieve that. This being said, I'm pretty sure you can do this with JQuery with way better results
Using jQuery I was able to give you what I think you're asking for:
$(window).scroll(function() {
var h = Math.max($(document).height(), $(window).height());
var bottom = h - $(".background").height() - $(window).height();
$(".background").css("top", (($(window).scrollTop() / h) * bottom) + "px");
});
EDIT: Forgot to account for the way scrollTop reports position.
Or maybe:
.background {
margin-top: 45px;
max-width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: -9999;
max-height: 100%;
}
I reccomend using jQuery Background Parallax
http://www.stevefenton.co.uk/Content/Jquery-Background-Parallax/
The function is as simple as
$("body").backgroundparallax();
Ask if you don't get it to work.
#abney; as i understand your question may that's you want http://jsfiddle.net/sandeep/RSqrw/60/
you need only css for this:
#background {
position: fixed;
width: 100%;
height:100%;
top: 0;
left:0;
z-index: -1;
}
The solution to your issue is a nice little lightweight plugin by Scott Robin. You can get more info, download it, and make your life easier for all of your projects by visiting his project page here.
height: 100% in CSS obviously doesn't work. So is there any other CSS or JavaScript/jQuery solutions to this problem? Please advise.
'Let's say your problem element is a <div>. If you make sure your <div>s height has something to reference to, almost all your problems will disappear:
#my_div
{
height: 100%; /* Won't work. What is 100% of an unknown/unset value? */
}
Make sure the <div>'s parents have a set height too. I usually do this (well, not exactly, but you get the idea):
#my_div, #parent_of_the_div, body, html
{
height: 100%; /* This works, but it will show scrollbars if the body
or html elements have padding or margins. */
}
So you want a div to be the height of the screen? It's kind of non-obvious, but css height is the correct approach. The trick is you need to have the html and body elements also take up the full height of the page, otherwise the div is taking up 100% of nothing. The best way I've found to do this is:
html {
height: 100%;
}
body {
height: 100%;
}
#contentDiv {
min-height: 100%;
}
No Javascript required,becouse CSS3 has some new values for sizing things relative to the current viewport size: vw, vh, and vmin
1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger
so you can write it on your style :
#contentDiv {
height: 100vh;
}
With jQuery, you could use:
$('div.class').css('height', $(window).height()+'px');
Pure css
#container {
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
}
Good Luck
Or javacript Jquery:
Ready (not innerHeight in ie8):
$(document).ready( function(){
var heightwindow = $(document).height();
$('#container').css('height', heightwindow+'px');
});
resize window :
$(window).resize(function() {
var heightwindow = $(document).height();
$('#container').css('height', heightwindow+'px');
});
There are a few options you may find useful:
vh (viewport height)
vw (viewport width)
vmin (viewport minimum length)
vmax (viewport maximum length)
#container{
height: 100vh;
background: black;
}
My answer builds on jonwayne's because there wasn't much explanation.
You cannot use css to get the value of a users monitor, but you can do it via javascript. So the trick is to add javascript to the page load event which will set the height based on the browser window height. Using jQuery, you can do this with the following snippet
// jquery shorthand for onLoad event
$(function() {
// Set the css height property of #div_to_resize to the css
// height property of the browser window
$('#div_to_resize').css('height',$(window).css('height'));
}
You can also optionally attach to the resize event of the browser to reset the height if the window is resized. Combined with the previous snippet it would be
// We extracted this to a function since we reference it more then once
function matchHeight() {
$('#div_to_resize').css('height',$(window).height);
}
// jQuery shorthand for document.onload
$(function() {
matchHeight();
//On the resize event, call matchHeight()
$(window).resize(matchHeight);
});
I don't think you can get the monitor's resolution with any web technology. What you an do is use Javascript to get the browser's height and set the height property of div in the css. This post might help for getting the height.