I'm having some issues with creating this effect with CSS:
http://i.stack.imgur.com/sMBmg.jpg
Basically, I want my content div to float on top and slightly overlap both the header and the footer elements. I've played around with some absolute positioning but I'm not sure if that's the best way to go. I want a responsive solution that works for all devices and screen sizes. Any suggestions?
Here is one way you could do it.
If this is your HTML:
<div class="header">Header</div>
<div class="content">Content</div>
<div class="footer">Footer</div>
Apply the following CSS:
.header, .footer {
height: 100px; /* not strictly needed... */
border: 1px solid blue;
}
.content {
width: 50%; /* for example... */
height: 400px;
background-color: yellow;
margin: 0 auto;
border: 1px dotted blue;
}
.header {
margin-bottom: -25px;
}
.footer {
margin-top: -25px;
}
.content {
position: relative;
z-index: 1;
}
You can see the demo at: http://jsfiddle.net/audetwebdesign/CNnay/
You set up three block level elements for the header, content and footer.
Apply negative margins to the bottom of the header and the top of the footer to
create the offset effect.
Finally, apply z-index to .content to tweak the stacking order so that the
content block is painted over the footer block.
In this layout, the content block will expand vertically as you add more content.
The results looks like:
You can try position:fixed or z-index:2000 of your div class
i have created this http://jsfiddle.net/RVnU7/1/
Related
I have a holder div that has specific dimensions, and has a single child element of varying height, and I am trying to align it to the baseline. Currently, I have a second element that is the same fixed height as the container which makes it aligned to the bottom, but if it is on its own, it sticks to the top, regardless of what rules are applied.
So, how can I vertically align an element to the bottom of a container if it is the only child element?
EDIT
While in the process of putting up the code that I am using, I came up with a solution which I have posted. The initial problem is similar to that, but without the position rules, and display:inline-block on the child elements. That is pretty much the long and short of it...
Damn it, thought of a solution after posting the question which works nicely:
Parent Element:
.parent {
height:200px;
position:relative;
width:200px;
}
Child Element:
.parent > * {
bottom:0px;
left:0px;
position:absolute;
right:0px;
}
The height of the Child element is then defined by block elements within it, but it sticks to the bottom
One way using table-cell
Assuming the bare bones markup:
<div class="wrap">
<div>Some content...</div>
</div>
the following CSS will do it:
.wrap {
border: 1px solid red;
height: 200px;
width: 200px;
display: table-cell;
vertical-align: bottom;
}
Major advantage: works with both inline and block level elements.
Disadvantage: Older browsers don't recognize display: table-cell
Demo at: http://jsfiddle.net/audetwebdesign/eXKbt/
Alternate way using inline-block
You can also do it this way by applying the following CSS:
.wrap2 {
border: 1px solid red;
height: 200px;
width: 200px;
}
.wrap2:before {
content: "";
width: 0;
height: 190px;
display: inline-block;
}
.wrap2 div {
display: inline-block;
width: 190px;
border: 1px dotted red;
vertical-align: bottom;
}
However, this approach involved using a pseudo-element to define a fictitious inline block to set a baseline nearly the full height of the box and then using vertical-align on the child element. There were some issues related to the width but it can be made to work.
See earlier fiddle for demo.
Not much detail to go off of, but maybe something like this
.container {
position: relative;
}
.child-element {
position: absolute;
bottom: 0;
}
Whenever I resize the browser, the 2nd div in .container positions below the first one.
<div class = "container">
<div class = "one"></div>
<div class = "two"></div>
</div>
The divs are really blank.
CSS
.container{
overflow: hidden;
width: 810px;
min-width: 810px;
}
.one,.two{
width: 300px;
height: 450px;
}
.one{float:left}
I just realized that, you are not floating the other element, this is causing it to shift down, you should use float: left; or right as it's a div so it will take up entire horizontal space, and hence it is pushed down.
Demo
.one, .two{
width: 300px;
height: 450px;
float:left; /* Float both elements */
background: #f00;
}
Alternative
You should use display: inline-block; and white-space: nowrap; to prevent the wrapping of the elements
Demo
This will gave you the same effect, the only thing is 4px white space, you can simply use
.two {
margin-left: -4px;
}
the above will fix the white space issue for you
Demo 2
Add this CSS. Demo.
.two {
margin-left: 300px;
}
PS: When works with float, you should clearfix.
Give your body a minimum width:
body {
min-width: 1110px;
}
Then, when the viewport gets smaller than 1110px the scrollbar will appear.
Note: if you add margin, padding or border to the divs, add it to the min-width of the body (or take some extra space).
I have a page with only a couple of lines of content. I want the footer to be pushed to the bottom.
<div id="footer"></div>
I don't want to use
#footer
{
position:fixed;
bottom:0;
}
AKA Sticky Footer
Is this possible without jQuery?
any suggestions?
This Flexbox solution is neater and far easier to implement:
HTML
<body>
<div class="content">
content
</div>
<footer class="footer"></footer>
</body>
CSS
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.content {
flex: 1 0 auto;
}
.footer {
flex-shrink: 0;
}
Just ensure you wrap the necessary divs inside the body.
Update 2021 - CSS GRID
Here is a solution using CSS Grid, this is by far the best way to do it on 2021.
html, body {
margin: 0;
height: 100%;
}
body {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr;
grid-template-areas: "main" "footer";
grid-template-rows: 1fr 80px;
}
main {
background-color: #F8BBD0;
grid-area: main;
}
footer {
background-color: #7E57C2;
grid-area: footer;
}
<body>
<main>The content</main>
<footer>Footer</footer>
</body>
Old Answer
There is another sticky footer by Ryan Fait that doesn't use position fixed:
* {
margin: 0;
}
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important; /* This line and the next line are not necessary unless you need IE6 support */
height: 100%;
margin: 0 auto -155px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
height: 155px; /* .push must be the same height as .footer */
}
Here is a solution that does not require that the footer be placed outside of the main wrapper element, which is how most people structure their pages.
html,
body {
margin: 0;
height: 100%;
}
.wrapper {
box-sizing: border-box;
position: relative;
padding-bottom: 1em; /* Height of footer */
min-height: 100%;
}
header {
background-color: #cff;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
color: #fff;
background-color: #000;
}
<div class="wrapper">
<header>I am the header.</header>
<article>I am content that doesn't fill the page. The footer will appear at the bottom of the browser window. However, when I do fill the page, you will need to scroll down to see the footer.</article>
<footer>I am the footer.</footer>
</div>
Explanation
The wrapper element will fill 100% of the viewport height. (You could also use 100vh for the wrapper if you don't want to set the height of the html and body elements.) The wrapper also has a bottom padding to create a placeholder for the footer to sit.
The footer is absolutely positioned to the bottom of the wrapper and sits in the placeholder created by the wrapper's bottom padding.
This means that when the page does not have scrollbars, the footer will be positioned at the very bottom. However, when there is enough content for scrollbars to appear, the footer will be pushed down below the content.
(The color and background-color CSS properties in the example are for decoration only, obviously. They are included so that when you run the code, you can clearly see the separated sections.)
Try Sticky Footer Solution by Steve Hatcher
/*
Sticky Footer Solution
by Steve Hatcher
http://stever.ca
http://www.cssstickyfooter.com
*/
* {
margin: 0;
padding: 0;
}
/* must declare 0 margins on everything, also for main layout components use padding, not
vertical margins (top and bottom) to add spacing, else those margins get added to the total height
and your footer gets pushed down a bit more, creating vertical scroll bars in the browser */
html, body {
height: 100%;
}
#wrap {
min-height: 100%;
}
#main {
overflow: auto;
padding-bottom: 180px;
}
/* must be same height as the footer */
#footer {
position: relative;
margin-top: -180px; /* negative value of footer height */
height: 180px;
clear: both;
}
/*Opera Fix*/
body:before {
/* thanks to Maleika (Kohoutec)*/
content: "";
height: 100%;
float: left;
width: 0;
margin-top: -32767px; /* thank you Erik J - negate effect of float*/
}
/* IMPORTANT
You also need to include this conditional style in the <head> of your HTML file to feed this style to IE 6 and lower and 8 and higher.
<!--[if !IE 7]>
<style type="text/css">
#wrap {display:table;height:100%}
</style>
<![endif]-->
*/
Another way to do this if you don't know the footer size is to use javascript and css
html, body{
height:100%;
height:100%;
}
#footer{
background-color: #292c2f !important;
position:absolute;bottom:0px;
}
and Javascript part
$(document).ready(function(){
if ($(document).height() > $(window).height()) {
$('#footer').css('position', 'relative');
}
});
You can do this with another approach just easily by setting min-height on the tag before your footer tag.
.the-tag-before-footer{
min-height:30%;
}
I tried a lot of approaches, but results were different when page was totally fill or not. The simplest and efficient solution is to use flex.
html, body {height: 100%;}
body {display: flex; flex-direction: column;}
.content {flex: 1 0 auto; padding: 20px;}
.footer {flex-shrink: 0; padding: 20px;}
<div class="content">
<h1>The GOAT Footer with Flexbox</h1>
<p>You can add content to test with a full page</p>
</div>
<footer class="footer">
The GOAT Footer
</footer>
Credits to CSS Trick
First wrap all of your main content in a div element and give it a class of “wrapper” (or call it whatever you want).
HTML:
<body>
<div class="wrapper">
<h1>Main Content</h1>
</div>
<footer>
<p>Footer Content</p>
</footer>
</body>
Now, make sure you give your footer a height.
Then use the calc() function to set the height of your wrapper equal to the height of the viewport (display), minus the height of the footer.
.wrapper {
min-height: calc(100vh - 50px);
}
footer {
height: 50px;
}
Now, if you have extra margins on your wrapper content you will have to increase the amount of pixels you subtract from the viewport height to reflect that. Other than that, this is a super easy and quick fix. No javascript needed, and only two CSS rules.
The problem is simple to solve for anyone using Bootstrap 4 or higher, just include this snippet on your website:
<script>
$(document).ready(function(){
if ($('body').height() < $(window).height()) {
$('footer').addClass('position-absolute bottom-0');
} else {
$('footer').addClass('position-static');
}
});
</script>
Here we check if the height of the BODY tag is less than the height of the browser window, if positive we place the footer at the bottom of the page and if negative we make the footer static and it will remain where it is. You don't need to change your current code, you just need to include this javascript in your page or package, remembering that to work the <body> tag must have position: relative, if you haven't changed the tag's "position" property in CSS <body>, you don't need to do anything as it is the default value.
Make sure to include the code after jquery, without jquery it won't work.
If you are not using the <footer> tag, you should change the $('footer') selector as appropriate.
Big picture: I'm trying to make a bar graph made up of discrete units. Each unit will be a div. The bar will grow from bottom to top.
Details: I have a container div that holds all of the unit divs, or blocks. The container has a vertical-align of bottom to do this.
This is what it should look like: https://jsfiddle.net/hpf4h/1/
<div id="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
#container {
height: 100px;
width: 10px;
padding: 1px;
background-color: #00f;
display: table-cell;
vertical-align: bottom;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
That works fine, but I need the container to have a height of 100%. Which makes this happen: https://jsfiddle.net/7n7ZH/1/
I'd prefer to find a way to do this with CSS, preferably not too hacky. I'm already using jQuery for the behavior in my project, so I could use that as a last resort.
Edit: Also, all parent tags also have a height of 100%, including HTML and body.
Make #container's container element display:table like this : https://jsfiddle.net/7n7ZH/2/
html, body { height: 100%; margin:0; }
body { display:table; }
#container {
height: 100%;
width: 10px;
padding: 1px;
background-color: #00f;
display: table-cell;
vertical-align: bottom;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
<div id="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
When you use display:table-cell the browser looks for ancestor elements being display:table-row, display:table-row-group and display:table. If it can't find them, it creates pseudo elements to stand in for them. That's what's happening here.
So when you say display:table-cell; height:100%, that's 100% of the created pseudo element that is display:table. But that pseudo element is only as high as its content, and there's no way in CSS to say "make the pseudo-element have height that's 100% the height of its parent instead".
But it is possible to have a real element be display:table and set its height to 100%, in which case the browser will use that and not create the display:table pseudo element.
Applying display:table-cell; and height at the same time rarely gives the results you'd expect. I see that you're trying to use vertical-align which is probably why you added the table-cell. Try css positioning instead:
Remove display:table-cell; and vertical-align from your container.
Add height:100%; to both the body and html elements so your container has room to grow.
Set the container to position:relative; which will make it the origin of all positioned children rather than the document root (body tag). This will allow you to move your container around without screwing up the child positions.
Add a wrapper around your blocks (you could use ul, li for this rather than divs).
Position the block container as position:absolute; bottom:0;
Here's the code...
#container {
height: 100%;
width: 10px;
padding: 1px;
background-color: #00f;
position:relative;
}
.blockContainer
{
position:absolute;
bottom:0px;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
body { height:100% }
html { height: 100%}#container {
height: 100%;
width: 10px;
padding: 1px;
background-color: #00f;
position:relative;
}
.blockContainer
{
position:absolute;
bottom:0px;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
body { height:100% }
html { height: 100%}
...and here's the fiddle...
https://jsfiddle.net/kPEnL/1/
I'm unable to provide assistance with doing it in the way you have started, but taking your original big picture of trying to make a vertical progressbar, here's an alternative which uses the progressbar in Twitter Bootstrap. In its existing form, it doesn't do vertical progress bars, but this modification does.
I originally suggested using stacked bars, but this doesn't work with the vertical implementation. Instead, I've got a solution which uses CSS gradients to draw the blocks in, but still uses the normal bootstrap progress bar.
.progress.discrete {
background-image: linear-gradient(0deg,
black 0%, green 5%, green 95%, black 100%);
background-size: 100% 10%;
background-repeat: repeat-y;
}
/* Bar is used to cover up the blocks, so make it look like a background */
.progress.discrete .bar {
background-image: linear-gradient(to right, #f5f5f5, #f9f9f9);
}
I assumed you wanted your blocks to be a percentage of the bar height rather than an absolute size - this means I can't apply the gradient to the bar. Instead, it can be applied to the background, and the bar used to cover it up (i.e. set width of the bar to 100-progress%). I've also included an example which uses a fixed block size applied to the bar if that's what you wanted.
http://jsfiddle.net/BHTXZ/3/
It needs a little tidying up, but does the trick.
I have a "main-section" div that is set to inherit it's height from its' parent div, which is the "wrapper" div. The wrapper div is set to inherit it's height from its' parent div, which is the body of the document. The html and body tags are set to height: 100%.
So, in order to use the CSS "sticky footer" (found at http://www.cssstickyfooter.com/), I have to set padding-bottom in the "main-section" div equal to the height of the "footer" div (which has to be outside of the wrapper div). Then, the footer div must be given a negative margin-top value equal to the height of the footer as well.
All of this is working in keeping the footer at the bottom of the page, but I am trying to extend the height of the main-section 100% to the footer so that the background-color of the main-section is visible down the entirity of the page.
I am close in doing this, except the main-section is now extending beyond the footer, and stretching the window beyond 100% height (when there is not enough content to exceed the page height), and the backgroung-color is then visible beyond the footer, beyond the height of the page (which is not desirable).
It seems that the necessary parameter of padding-bottom in the main-section div is causing this problem, even though the footer is set to clear: both and position: relative (which does keep the footer at the bottom of the page, but the main-section div is still extending below the footer quite a bit). Or maybe the min-height: 100% attribute of the wrapper could be causing a conflict?
Here is the relevant html:
<div id="wrap">
<div id="header">
...
</div> <!-- end of header -->
<div id="main-section">
...
</div> <!-- end of main section -->
</div> <!-- end of wrapper -->
<div id="footer">
...
</div> <!-- end of footer -->
...and here is the relevant CSS:
*
{
margin: 0px;
padding: 0px;
}
html, body
{
height: 100%;
}
body
{
background-color: #bbb;
}
#wrapper
{
/* wrapper 100% of screen */
min-height: 100%;
height: inherit;
width: 950px;
margin-left: auto;
margin-right: auto;
}
#header
{
background-color: #C97;
line-height: auto;
text-align: center;
font-family: "Lucida Console";
font-weight: bold;
font-size: 2.5em;
}
#main-section
{
background-color: #ddd;
height: inherit;
/* for a "sticky" footer */
padding-bottom: 50px; /* equal to the height of the footer */
}
#footer
{
clear: both;
position: relative;
height: 50px;
line-height: 50px;
margin-top: -50px; /* equal to the height of the footer, for a "sticky footer" */
width: 950px; /* equal to width of wrapper */
margin-left: auto;
margin-right: auto;
text-align: center;
background-color: #C97;
}
EDIT: It is important to mention that I am testing this in Firefox.
Here is a reference for you.
LIVE DEMO
Make change in footer
#footer
{
bottom:0px;
width:100%;
height:50px;
position:fixed; // this is the key
height: 50px;
line-height: 50px;
width: 950px;
background-color: #C97;
}
Updated Jsfiidle demo
So, a workaround, that exhibits the same behavior --
Instead of messing with the nested main-section div, I am applying the background-color to the wrapper div itself (and also not applying postion: absolute to the main-section div, but still applying position: fixed to the footer div).
This way, the main-section can contain any amount of content, and it will appear to have a 100% height background-color.