How can I have div 'lower' fill the lower part of the screen with it's bg image?
Div 'upper' grows depending on the content.
The red line marks the viewport.
Here I have an example how I did it with a table : Splendid
But I want it tableless!!
Warning: This answer does not solve the original problem, I misunderstood his question. What the author wants to achieve is probably impossible with CSS only, because we have a combination of sticky footer, a footer-head that is always visible (like taskbar) and dynamic height of both the main content and the footer.
I'm leaving the snippet for anyone that might look for a sticky footer.
Fiddle: Dynamic Content with Sticky Footer
I used a timer to illustrate filling the 'Upper' Container with content constantly.
Basically you have the following HTML:
<div class="wrapper">
<div class="upper">
<span></span>
<div class="push">
</div>
</div>
<div class="lower">
Footer content goes there.
</div>
</div>
And of course, CSS:
.upper{
min-height: 100%;
height: auto !important;
width: 100%;
height: 100px;
background: blue;
margin: 0 auto -100px; /* The negative value of the footer height. */
color: white;
}
.lower, .push {
height: 100px; /* Footer and Push need to have equal height */
background: red;
color: white;
}
Code explanation:
This is basically the so called Sticky Footer concept on which you can do additional research. You have your main content, you have your footer and we use a little trick with the push container to literally push the footer so it doesn't overlap any of your content.
The extra CSS is just for the sake of the Demo, I hope you can clean it up and implement it the way you need it.
This is not precisely what you are asking for, but you could scrap the bottom div, and add the large background image to body. Apply background-position: center bottom; to make the image hug the bottom of the screen. This will work particularly well if the image has a clear background.
body {
background: url('largeImage.png') no-repeat center bottom;
}
Ummm just set the height of div 'lower'? Or even min-height if you want it to be content flexible.
You could use Javascript to subtract the height of the upper div from the browser's window height, and if the result is larger than 0, set the lower div at that height?
For getting the window size, I suggest using this function. I believe it's cross-platform, though I haven't tested it recently.
function getDocHeight() {
var D = document;
return Math.max(
Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
Math.max(D.body.clientHeight, D.documentElement.clientHeight)
);
}
Related
I've been looking around all over, but I can't solve this, so I'm turning here.
I want to make a layout that looks like this:
The layout consists of three fields:
A header at the top with a fixed height, dynamic width, and vertically scrollable content.
Body below header, with dynamic width and height, with vertically scrollable content.
A sidebar to the right, with a fixed width, dynamic height, and no scroll. (This should remain fixed when you scroll the body content)
Dynamic height and/or width means it will resize with the window, not that it resizes with content.
If anything is unclear or there's any questions, I'll do my best to answer.
edit: one of my (very failed) attempts here: http://jsfiddle.net/uYTht/34/
html structure:
<body>
<div id="header">
header content
</div>
<div id="content">
body content
</div>
<div id="sidebar">
sidebar content
</div>
</body>
css code:
#header {
width: 100%;
height: 100px;
margin-right: 150px;
background-color: green;
overflow-y: scroll;
}
#content {
background-color: blue;
height: 100%;
overflow-y: scroll;
}
#sidebar {
position: absolute;
top: 0;
left: 100%;
margin-left: -150px;
width: 150px;
height: 100%;
float: right;
background-color: red;
overflow: hidden;
}
edit: David below helped me find the way. Basically what I had to use to make it work as I wanted was the calc()-function.
edit edit: Jack below came up with a solution that didn't use calc(), which I must say I prefer. Thank you all very much for the help!
I created a simple fiddle, that doesn't use calc (support isn't great - http://caniuse.com/calc, and then there's the big unknown of any performance penalty you may/may not hit using it..)
It's very straight forward, using simple CSS.
http://jsfiddle.net/ruYGH/3/
You can do this by using defined heights and widths for each of the elements with the overflow property.
To make a box scrollable (if the content doesn't fit inside):
overflow:auto;
To make a box not scrollable:
overflow:hidden;
Note that if the height and width are undefined, the element will grow to fit all of the contents.
I made a (not very pretty, but functional) example here:
JSFiddle
Edit:
You can make the sidebar a fixed width and adjust the other elements accordingly with calc:
.sidebar{
width: 200px;
}
.left{
width: calc(100% - 200px);
}
The JSFiddle has been updated to reflect this.
Style the divs with "overflow" to put the scroll bars where you want them and prevent them where you don't want them. You will also use overflow to specify what you want to happen to your content if it should happen to be too big to fit in your fixed width areas.
Chris Coyer is always a knowledgeable CSS resource
As far as the layout goes, it is a walk in the park if you use a two column table with rowspan="2" on the second column of the first row and only one column in the second row.
If you don't want to use tables (there is no good reason not to, but there are thousands of people that will look down on you if you do) then look at using divs with style="display: table...."
Once again Chris Coyer has an explanation
Thanks for the fiddle, your overflow css is working it is just that your header and content divs are 100% wide (full screen) and the scroll bars are conceptually under the sidebar. I need to sell you on using that table layout so that you can "dynamically" fix your dimensions so that the browser can know when to scroll instead of expanding the content down indefinitely to fit the size of the content instead of overflowing with the scroll bar.
My problem is with the header. So I basically have 3 columns of divs. I want the middle one to have a constant width of 980px, and then I want the left of the header to extend to the end of the browser window with a blue background color. As for the right of the header, I want that to extend to the end of right side of the browser with a black background color. It kind off looks like this:
<------------------------------[blue][center header][black]---------------------------->
I've done my research and all I could find so far are two columns with a fixed left column with the right column filling up the rest of the space. I wonder how this can be applied to my problem?
Would it be like:
<div style="width:100%;">
<div style="display:table-cell; background-color:blue;"></div>
<div style="width: 980px;">my header</div>
<div style="display:table-cell; background-color:black;"></div>
</div>
Thank you!
A simple solution - basicaly using your exact stying, but putting another block in the central table-cell element, something like this span here:
<div class="wrapper">
<div class="left"></div>
<div class="center"><span>my header</span></div>
<div class="right"></div>
</div>
I moved all the inline style to a separate CSS block and used class selectors:
.wrapper {
display:table;
width:100%;
}
.left {
display:table-cell;
width:50%;
background-color:blue;
}
.right {
display:table-cell;
width:50%;
background-color:black;
}
.center {
display:table-cell;
}
.center span {
display:inline-block;
width:900px;
}
here is a jsfiddle
and here I made the center much narrower for a better illustration: jsfiddle
Hope this helps =)
Unfortunately there isn't a super smooth way of doing this that is also has wide cross compatibility support. There is a CSS spec for display called flex or flexbox which would do what you want beautifully and elegantly, but it has very limited support at the moment. Here is some resources on flexbox for your perusal...
http://css-tricks.com/old-flexbox-and-new-flexbox/
In the meantime, you can achieve the layout you want with some basic CSS jiggery-pokery that will get you what you want, but it requires absolute positioning your middle div.
Heres the JSFiddle: http://jsfiddle.net/CW5dW/
Here's the CSS:
.left {
width: 50%;
height: 300px;
float: left;
padding-right: 160px;
box-sizing: border-box;
background: red;
}
.right {
width: 50%;
height: 300px;
float: right;
padding-left: 160px;
box-sizing: border-box;
background: blue;
}
.middle {
position: absolute;
width: 300px;
height: 300px;
left: 50%;
padding: 10px;
margin-left: -150px;
box-sizing: border-box;
background: orange;
}
What is going on here you might ask?
Basically, we are taking the div with class middle and removing it from the flow of the document. This allows us to float our left div left, and our right div right, with widths of 50% in order to fluidly take up ALL space of the browser.
We then tell the middle div to take up 300px of space (in your case 980), and we tell it to go 50% of the total width of your browser from the left. This doesn't center it though, because its calculated from the left edge of your div. So we give it a negative margin space of half it's width, to sort of "move" that left edge to the center of the div.
Then, since we know the middle div has a width of 300px (in your case 980), we can then say that the left div should have some padding on its right edge greater than or equal to half the middle divs width, in my example that's 150px, and I added 10px more so text couldn't come right to the edge of the div, so 160px total. We do the same for the right div but for it's left side. This limits the content of those two divs from falling underneath our middle div.
This answer is not an "answer" as such - it's an extended comment to #Michael's post. I have, however, posted another answer - a jQuery solution.
Regarding #Michael's answer (which is a very tidy solution indeed) there is a tiny issue that if you remove your height declaration (which the OP undoubtedly will) then the backgrounds for the various columns become exposed - this method relies on the backgrounds all levelling out at their bottom edge in order to make the design coherent. If the OP's design doesn't have backgrounds behind the columns then this solution should be fine. If backgrounds are required (which they might be judging by the question wording) then it could be awkward. Two solutions to this...
a simple javascript that scans the page for column length, finds the longest, and matches all shorter ones to the maximum.
The other (and probably better) solution is to drop a background into your with the columns already on it (it only needs to be 1px high I guess) - just make sure the central white band is 980px wide and the side columns extend off a thousand or so pixels to accommodate even the largest of browsers
OK, here's my solution. This will present a "common or garden" three column fixed width layout to all users and then adjust it for users with javascript enabled (which, let's face it, is the vast majority of users). The benefits of this solution are that the layout will behave like any ordinary 3 solumn layout without the quirks you can experience from using more advanced CSS tweaks like absolute positioning and fixed heights.
Fiddle here... http://jsfiddle.net/vuary/
You should be able to see what's going on with the HTML and CSS... it's basic stuff. The jQuery is pretty straight forward too:
$(document).ready(function(){
// find the width of the browser window....
var docuWidth = $(window).width();
// find the width of the central column as set by the CSS...
// (you could hard code this as 980px if desired)
var centerWidth = $('#center').width();
// figure out how many pixels wide each side column should be...
sideColWidth = (docuWidth-centerWidth) / 2;
// then set the width of the side columns...
$('#left,#right').css({
width:sideColWidth+'px'
});
})
EDIT
Converted the jQuery to a function that is called when the document is ready, and again if the viewport is resized... just in case:
http://jsfiddle.net/aKeqf/
I'm trying to make my sidebar stretch to the bottom of the page. I've succeeded in making it stretch but now my footer it getting in the way. For some reason I don't know, my footer is appearing before the content div has ended, and cutting off the sidebar, as well as making the page messy.
As you can see, as soon as the footer appears, the sidebar (grey box) stops and the content is overlapped.
Could anyone point out the code that is doing this and a fix?
Setting min-height:100%; results in a minium height of 100%, adding an additional height:100%; is obsolte. The browser calculates the height of elements relative to the closest block-level parent element. At the top level, the height will be relative to the browser window height.
Remove the height: 100% declarations where you have also specified a min-height:100%;, and your problem will be solved: #globalDiv, #topcontentWrapper.
remove the height from this piece of css:
#topContentWrapper {
height: 100%;
min-height: 100%;
}
change to
#topContentWrapper {
min-height: 100%;
}
I have a very simple question I believe. I have a footer.php that I put on my main page and all subpages (to make it easier so I can change the footer in one location). And I am trying to make it so the footer remains at the center of the fixed-width no matter what size the browser window is. For example, I want my pages to be 950px width and the footer always be in the center, so that even when I resize the browser to as small as it goes, it simply COVERS the footer, rather then moving it with the resized window. Much like apple.coms footer.
Thank you for your help
You just need to set the width of your footer and then give it a margin:0 auto where 0 stands for the top and bottom margins and auto is for the left and right.
In your markup:
<div id="footer-container">
<div id="footer">
Footer stuff
</div>
</div>
And in your CSS:
#footer-container {
/* centering for IE */
text-align: center;
}
#footer {
width: 950px;
/* undo text-align on container */
text-align: left;
/* centering for other browsers */
margin: auto;
}
Edit: I was putting this comment on some of the other solutions, but deleted them because I didn't want to copy/paste on all of them. Just please be aware that margin: auto doesn't work in older versions of IE, so if you want to have the footer aligned in the middle, you'll need to do some nesting, like I have in this one.
Simply set the width: 950px, and margin-left:auto; margin-right:auto;.
With the left/right margins at auto, the <div> will be centered. Once the size of the browser gets down to the point where scrolling is needed, the browser will not shrink your <div>, it will just require left/right scrolling, which is needed for your content anyway.
I think you could solve it with a little bit of CSS:
html & php:
<div id="footer">
<?php include("footer.php"); ?>
</div>
CSS:
#footer {
margin: 0 auto;
text-align: center;
}
Hope this helps! :)
I have a requirement to produce a HTML layout as follows:
The page should flow to occupy the available space in the browser window
It should have a fixed height header and footer
The central area should occupy the remaining height
The central area is broken into three columns. Each of these colums should be independently scrollable should the content exceed the available area.
I've had a go at this using a table of height 100% (works eventually with a bit of tweaking) with the top and bottom cells having fixed heights. This leaves the central area to occupy the remaining space. This area contains another table with three columns. Each cell contains a div with height and width set to 100% and overflow set to auto. It seems like it should work but excess content simply causes the main table to extend its height so that the whole page becomes scrollable.
Does anyone know of any examples of this working in practice? The solution is expected to be reasonably cross browser but doesn't have to cover every corner case.
Thanks,
Phil
Update
I figured out a solution and posted it as an answer here.
Note: I'm assuming HTML5 and CSS3 here, but kept to properties that work in most browsers. The HTML5 can easily be exchanged for HTML 4.01.
To create the kind of layout you want, we start with some basic HTML:
<div id="wrapper">
<header> Header </header>
<div id="content">
<section id="left"> Left </section>
<section id="center"> Center </section>
<section id="right"> Right </section>
</div>
<footer> Footer </footer>
</div>
The difficulty is styling this according to your needs. Starting out by setting a 100% height on as much as possible, along with suitable overflow values, we can obtain something very close to what you want:
html, body { height: 100%; margin: 0; padding: 0; }
#wrapper { height: 100%; }
header, footer { height: 50px; }
#content { height: 100%; overflow: hidden; }
section { float: left; overflow: auto; height: 100%; }
#left, #right { width: 100px; }
#center { width: 300px; }
Unfortunately, this makes the layout exactly 100px (the combined height of footer and header) too tall. To remedy this, we must decrease the height of #content by the same amount, but the standard box model doesn't allow for this. Enter the box-sizing (which is supported by all major browsers except IE7), which we can use to change the box model being used. With the border-box box model, padding is included in the height and as such we can "remove" the necessary height from #content:
#content { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; padding: 50px 0; margin: -50px 0; }
See also this JSfiddle demo and the full screen result for further details.
There are several examples of this type of layout available. One of the best is Matthew Levine's "Holy Grail," complete with tutorial.
You will note that this layout does not fix the footer at the bottom of the screen. You can do this by setting body (or an all-encompassing div) height to 100% and using overflow:hidden but this introduces potential usability issues. You may find that it is best to let your page expand to correct height as needed.
I figured out a solution, it's not elegant but it does work. I created a table set to 100% height. I then added a function which executes on load and resize. This gets the height of the window and subtracts from it, the height of the header and footer, it then sets the height of a div in the central area to be that remaining height. The main difficulty was coming up with an accurate window height, through various bits of googling, I came up with the following which appears to work fine:
function getWindowHeight() {
var height = 0;
var body = window.document.body;
if (window.innerHeight) {
height = window.innerHeight;
} else if (body.parentElement.clientHeight) {
height = body.parentElement.clientHeight;
} else if (body && body.clientHeight) {
height = body.clientHeight;
}
return height;
}