CSS Sticky Header/Footer and Fully Stretched Middle Area? - css

With CSS, how can i simply get a page with sticky header and footer which are appearing forever, whenever the page is scrolling or not. I found some sample online, but what i additional want is, the middle content area should be a 100% stretched area between header and footer whatever the browser size is.
I mean, most of the Samples i found, are making Header and Footer sticky correctly.., but these are just floating and actually covering the Top and Bottom parts of the 'middle' content area. That's not what i really want.

Can use absolute position for all 3 elements.
#header,#footer,#content { position:absolute; right:0;left:0}
#header{
height:100px; top:0;
}
#footer{
height:100px; bottom:0;
}
#content{
top:100px;
bottom:100px;
overflow:hidden; /* use this if don't want any window scrollbars and use an inner element for scrolling*/
}
DEMO: http://jsfiddle.net/RkX8B/

The solutions presented above work for very simple layout with no border, margin, and/or padding. Many, many solutions that you'll find on the Net will work for this.
However, almost all solutions fall completely apart if you simply add border, margin, and/or padding to any or all of your Divs.
Flex Boxes (CSS display:flex;) are incredibly powerful for this, and they work perfectly with any combination of border, margin, and/or padding.
They can portion your screen space into as many Divs as you need, using fixed size, percentage size, or "whatever's left" for each inner Div. These can be in any order, so you aren't limited to just headers and/or footers. They can also be used horizontally instead of vertically, and can next.
So you could have, say, a fixed-size header, a 20% footer, and a "whatever's left" client area between them that sizes dynamically. Inside that client area, in turn, you could have, say, a percentage-width menu bar at the left edge of the client area, a fixed-width vertical divider next to that, and a client area that takes up "whatever's left" to the right of that.
Here's a Fiddle to demonstrate all of this. The relevant CSS is remarkably simple.
CSS Flex Box (display:flex;) Demonstration with Borders/Margin/Padding
For instance, here are two CSS classes that create containers that will flow their contained Divs either horizontally or vertically, respectively:
.HorFlexContainer {
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex: 1; /* this essentially means "use all parent's inner width */
}
.VertFlexContainer {
display: flex;
flex-direction: column;
flex-wrap: wrap;
flex: 1; /* this essentially means "use all parent's inner height */
}
The Fiddle above really shows it all off, though.
For reference, see this excellent article by Chris Coyier:
Flexbox Tutorial
Hope this all helps!

You're probably looking for the "position: fixed;" property, and setting the header to top: 0; and the footer to bottom: 0; You might also consider some padding to your "content area" to account for that header and footer space...
From the top of my head you would have something like:
header { position: fixed; top: 0; height: 100px; }
footer { position: fixed; bottom: 0; height: 100px; }
#container { padding: 100px 0; }
If you're using some kind of background on your container and want to stretch it, a height: 100%; should do...
I've never found a good way to use this kind of layout though... =\

Related

Why is there no easy was to vertically center in css?

I was searching around for a way to vertically center a div in a container. I found a few different ways, but all of them seemed to be very "hacky".
My question is, why is there not just a css property, such as align-vertical that can simply be set to center to center the content? It seems like adding this to css would make so many things much easier.
I am assuming there must be a reason why something like this is not implemented, and I would like to hear if anyone has any idea why.
It's because how browsers traditionally work.
In a browser, by default, the content scrolls vertically. The viewport width is well defined (width of the device), but the viewport height can be one or two times the height of the device, or can even be infinite (as in infinite scrolling).
Traditionally blocks were meant to be horizontally oriented. You place a div and it's automatically occupying 100% of the width of the parent. But its height value is contrained to its content.
If you do
.mydiv {
background: red;
width: 100%;
height: 100%
}
Nothing changes, since divs have already 100% of width, and it can't calculate the height, since it doesn't know how far the viewport will go. You need to add:
html, body {
height: 100%;
}
to tell the browser to use the device height as the 100% value.
That's why horizontal center is easy: you know what the boundaries are, and how to center the element. But vertical center is more complicated, that's why (before flexbox), you need to resort to absolute positioning or hacks.
Flexbox allows you to render content horizontally or vertically, so it's prepared to handle centering along two axes.
If you want to read more about this, I suggest the spec:
Visual formatting model
Visual formatting model details
#outerDiv{
display:flex;
width:100%;
height:200px;
background:#ccc;
align-items:center;
}
#innerDiv {
background:#aaa;
width:80%;
margin:0 auto;
}
<div id="outerDiv"><div id="innerDiv">Hello</h1></div>
Run the script and the div remain in the center.
You can mix and match the combination like this.
Earlier you need to play with the height of the parent container and self height.
But with flex it becomes easy.
If I'm trying to center an element I do the following -
*parent-item {
margin: 0 auto;
width: 100%;
display: block;
It's important to define the width of the element you are centering.

CSS good practices for responsive Height. This is a quick fix/MacGyver or not?

I made this code that makes a responsive height, it adjusts according to the size of the viewport. (Run the snippet and resize the screen).
Whereas the html and body have a height: 100%, I set up a basic structure with 3 divs and I was handing this height: 100% between them (as you can see in the snippet). After that, I gave a position: absolute and top according to the size of each.
Well, as I assign attributes the top for each div in "hand", I got the feeling that this may be a quick fix/MacGyver on it, because as in the later, there are more divs, I have to do this calculation for top again. I think that have better ways to do this...
Thus, in what other ways I can do this? The code that I did can be considered a quick fix/MacGyver?
html, body{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.div1{
position: absolute;
width: 100%;
height: 10%;
background: red;
}
.div2{
position: absolute;
top: 10%;
width: 100%;
height: 75%;
background: green;
}
.div3{
position: absolute;
top: 85%;
width: 100%;
height: 15%;
background: yellow;
}
<div class="principal">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</div>
The answer to whether what you're doing is a good solution (which I will interpret as concise, not overly complicated, and as compatible as possibe) depends on what exactly you're trying to do. Because you don't provide much detail on that end, let me give you the rundown.
The generally best approach (by the definition above)
In most cases, you won't need any special properties and can simply set the height or min-height of your three containers to the appropriate value, since their parent (body) already has a height of 100%. Because everything is underneath each other, there is no need to use the position property in any way.
Because of the way html works by default, these containers will retain their size until their content will require more space; then they will expand to accomodate the content. This is a feature, not a bug.
If you want to prevent this, set the overflow to hidden or scroll, which will help retaining the original container size (though in case of scrolling, scrollbars might mess with your plans).
Alternative solutions
Sometimes layouters get weird ideas of what you need to put on a webpage, and weird ideas might require weird solutions. Let me try to come up with a list of options to choose from:
The approach you took works if you need to split the viewport into exact shares of fix values, disregarding the container's contents entirely. It's compatible with any relevant browser by a long shot, but it will (assuming you handle the overflow so it doesn't stretch the container) likely result in cut-off content on extreme screen sizes (if you have primarily text content) or aspect ratios (if you have primarily image content); to be honest, probably both - but if you're working on a game, for example, maintaining a relative container size can easily be more important than their contents
Flexboxes will "only" give you a benefit of stretching the content over the whole screen if you're desperately trying to avoid setting a height, but it shouldn't result in any unforeseen errors, aside from the compatibility issues. As an additional bonus, you can rearrange the containers with the order property, which none of the other methods will accomplish.
Using absolute-positioned elements, you can entirely disregard height attributes and just set both top:0 and bottom:0 (while having a relative-positioned parent) to stretch a container over the entire height, then position containers inside on the top and bottom the same way. Not many cases in which this is more useful than the above two come to mind, and you won't like fixing any problems you encounter on the way, but if you're developing for browsers thathave issues with overflow properties, you could look into it.
The vh unit, apart from suffering from compatibility issues about the same, can be used, but don't pose any actual benefit over using percentage values. They are used to size elements relative to the viewport dimensions, which your percentage solution does just the same for this specific use case.
You could use a table, though that's commonly considered bad practice for various reasons and will on top of that be the most complicated solution of all of these, so I won't go into it.
So, all in all, there are many ways to accomplish what you want (and I possibly even missed some), and without providing info about the exact nature of what you're trying to do, there can be no exact recommendations other than a quick summary of what I wrote above: If you plan on putting content in the top and bottom container and you can't use the topmost solution, flexbox will work the best for you; if you need the containers to take up precisely a certain percentage, go with your original solution; and only if both aren't suitable, expand your search to the other options.
Today flex can make this really easy:
examples to run in full page:
html, body {
height:100%;
/*
}
next can be declared only for body but won't hurt if both html/body
body {
*/
display:flex;
flex-flow:column;
}
main {flex:1;
}
/* makeup */
header, footer {
background:tomato;
padding:1em;
}
main {
background:turquoise;
margin:1em;/* it can even stand away */
}
<header> header no need to set an height </header>
<main> let's fill remaining space</main>
<footer> footer no need to set an height </footer>
or use many div
html,
body {
height: 100%;
}
body {
display: flex;
flex-flow: column;
}
div {
flex: 1;
}
/* makeup */
header,
footer {
background: tomato;
padding: 1em;
}
div {
background: turquoise;
margin: 1em;/* it can even stand away */
}
div.autoH {
flex: none;
margin: 0.25em 0em;
background: brown
}
<header>header no need to set an height</header>
<div>let's fill remaining space</div>
<div class="autoH">let's fill only my needed space</div>
<header>or use header's / footer's properties</header>
<div>let's fill remaining space</div>
<footer>footer no need to set an height</footer>

How may i set the height of div to fill the browser height?

Please visit my website at http://amrapps.ir/personal/indexbug.html
to visually see my problem.
Let me explain my problem:
In my website i have a fixed postion div which contains links and i takes and it takes 25 % of browser height.
Then it is the red div which takes 75 % of browser width.
When user clicks on -CLICK THERE TO READ MORE- in red div,it will be redirected to the next(yellow colored) div which takes 100 % of browser height.
Then you can click on go to top on the fixed div above to get back to red div.
Navigations are working well but there's a problem.
When you are at the 2nd(yellow) div,if you change browser width,the red div will be also visible! How can i fix that?
thank you for your effort.
Change your #aboutmore class to the below css:
#aboutmore {
background-color: #FFCE85;
margin-top: 5px;
top: 25%;
position: absolute;
/* height: 74%; */
width: 100%;
min-width: 1130px;
bottom: 0px;
z-index: 3;
}
Theres a couple of things going on here, and I'm not 100% of the result you want to accomplish, but we are working with CSS heights here so you need to keep some things in mind.
First of: when working with css heights, you need to make sure that all wrapping elements get the height of 100%. Including your body AND html tags. Without this, your body will just have the height of the elements inside it, and your 100% divs will do it to.
Second, you should turn of the body 'overflow: hidden' attribute, as it just obstructs correct testing.
Now, like I said, I'm not sure what you're trying to accomplish, but your header should be taken out of the wrapper as it is fixed. This will allow your wrapper to become the scrollable area. You also mentioned you wanted the second div to be 100% heigh and the first one 75%. Now, with position fixed this would mean your yellow div is only 75% visible, with 25% hidden (either by being off screen or under the header). If you want the first div and header together to take up 100%, and any subsequent div to take up 100% on their own, you should position all elements relative and not fixed.
I'm going to add some code here to help with a fixed header:
div#page-wrap {
height: 75%;
position: absolute;
top: 25%;
width: 100%;
overflow: scroll;
overflow-x: hidden;
}
about,
#aboutmore {
height: 100%;
position: relative;
top: 0%;
}
Now this will break your javascript (as you can't actually scroll the body), although I couldn't get it working in the first place anyhow. You'll find more about scrolling inside a div (as now you need to scroll in your wrapper element) in this thread: How do I scroll to an element within an overflowed Div?

HTML side by side DIV positioning

Consider this JSFiddle: http://jsfiddle.net/GFsgq/5/ (you may have to zoom out a bit).
It shows a layout that I'm trying to achieve. So far it's been going alright, but I've hit a roadblock. I want to position two divs 77px in height side by side of the centered divs. They need to retain width to always touch the edge of the screen and their center div. I'm not sure how to do this with my limited knowledge of CSS, short of adding properties at random.
Her is a picture to help you understand: http://i49.tinypic.com/2ntz34n.png
The blue strips are where I want the divs to be. How do I achieve this?
You need to add this in your CSS:
header:after {
content: "";
display: block;
background-color: blue;
width: 100%;
height: 80px;
}
jsFiddle: http://jsfiddle.net/GFsgq/32/
fullsrcreen result: http://jsfiddle.net/GFsgq/32/embedded/result/
i would add parent div spanning thw dith of the screen with position:relative; and to the two child divs use position:absolute; and position one right:0px; and the other left:0px; I am unsure about how you want to distribute width, if you have any other problems then come back.

CSS3 Flexbox full-height app and overflow

I have a app that uses a classic email like layout like the one below.
I have constructed it using the new CSS3 flexbox model and it works brilliantly until I add the ability for the user to dynamically add new items in the folders box. I would have hoped that flexbox worked in such a way that as long as there is space left in the folders box it would not begin growing into the tasks box underneath. Unfortunately this is not what I am seeing (in Chrome 17).
I have constructed a JSFiddle here that demonstrates the problem. Just click the Add Folder link and you will see the folders box growing, even though it has space enough left to accommodate the new child.
To the question. How can I construct two vertically aligned boxes using flexbox in such a way that one takes up two thirds of the available height (box-flex 2) and the other one third (box-flex 1) and that they do it in such a way that when new content is added to the first box it does not begin growing until it is out of space.
I can't say for sure if that's a browser bug or if it is in fact how the flex model is supposed to work. If that is how it should work I'd agree that's not exactly intuitive!
I found a work around by wrapping the lists in an absolutely positioned div with the overflow set to auto. This allows the flex boxes to maintain their original states and only change when the entire layout is recalculated vs. the content changing.
Here's the updated markup:
<section id="folders">
<div class="dynamicList">
<h2>Folders</h2>
<ul>
<li>Folder 1</li>
<li>Folder 2</li>
</ul>
Add Folder
</div>
</section>
And the updated CSS:
#left #tasks,
#left #folders {
position: relative;
}
.dynamicList {
bottom: 0;
left: 0;
overflow: auto;
position: absolute;
right: 0;
top: 0;
}
I forked your fiddle here to demo:
http://jsfiddle.net/MUWhy/4/
UPDATE:
If you want the headings to remain fixed and only have the contents of the folder and tasks lists scroll, then I would consider putting the headings and the add buttons in their own fixed-height boxes within the #left div. It's a bit more mark up but still pretty simple. I haven't tried it on JSFiddle but I think that would be the best route to go.
I have got this answer from my other question which is is the same more or less: https://stackoverflow.com/a/14964944/1604261
Instead of #LukeGT solution, that it is a workaround and not the solution to obtain the effect, you can apply a height to the element where you want to see a vertical scroll.
So the best solution if you want a min-height in the vertical scroll:
#container article {
-webkit-flex: 1 1 auto;
overflow-y: auto;
min-height: 100px;
}
If you just want full vertical scroll in case there is not enough space to see the article:
#container article {
-webkit-flex: 1 1 auto;
overflow-y: auto;
min-height: 0px; /* or height:0px */
}
If you do not set the height (using height or min-height) the vertical scroll will not be set. In all cases, even with height: 0px; the calculated height of the element will be different to zero.
My solution with -webkit prefix: http://jsfiddle.net/ch7n6/4/
Edit:
Since Firefox now supports full flexbox specification, removing -webkit- vendor prefix it will work with all browsers.
I prefer this solution to Jim's since it's less of a hack - it will work on any flexbox on any part of the page. Jim's can only work on a box in the very top left of a page.
I solved this by wrapping the part of the flex box that I wanted to scroll inside a div.scrollbox. I made the direct children of this div have a height of 0, so that adding extra elements within it would not affect the rest of the layout. I also set its overflow-y to auto so that a scrollbar would appear if its children extend beyond its bounds.
.scrollbox {
-webkit-flex: 1 1 auto;
overflow-y: auto;
}
.scrollbox > * {
height: 0;
}
Note that this will only work if the extendible content is placed within a containing element or containing elements. In this example, li elements are contained within a containing ul element, so it works.
I also had to make some changes in order to get the 3 components of the top left flexbox to arrange themselves properly, but this was application specific.
#folders {
display: -webkit-flex;
-webkit-flex-flow: column;
}
#folders h2, #folders #add {
-webkit-flex: 0 1 auto;
}
I forked the above jsfiddle here: http://jsfiddle.net/FfZFG/.

Resources