I have a fixed header with position:fixed why it stays on top of other elements and hides them, so I have to add padding to main. Because the height of header varies by content, font-size and padding set by media queries it's not possible to use a fixed value for padding as in the snippet. Is there a solution that respects changing heights of header without using javascript?
body {
margin: 0;
padding: 0;
}
header {
background-color: grey;
position: fixed;
width: 100%;
}
main {
padding-top: 80px; /* bad, because it's fixed */
}
<header>
<h1>Example</h1>
</header>
<main>
<p>Content</p>
</main>
As others have said, you can't do it without javascript, but you can fake a fixed header using flexbox and flex-grow: 1; overflow-y: scroll; on the main content area.
* {margin:0;}
body {
display: flex;
flex-direction: column;
max-height: 100vh;
}
section {
flex-grow: 1;
overflow-y: scroll;
}
main {
background: #eee;
min-height: 500vh;
}
<header>
<h1>Example</h1>
</header>
<section>
<main>
<p>Content</p>
</main>
</section>
<footer>
<p>footer</p>
</footer>
There is no way you can achieve it without the use of Javascript if you want to keep the fixed position. I'd suggest not to use position at all but respect the html hierarchy. And make it "fixed" once scrolling gets it out of the viewport. This is the most typicall approach when you want to have the header visible at all times if height could vary.
Related
This question already has answers here:
Footer at bottom of page or content, whichever is lower
(5 answers)
Closed 9 months ago.
I tried to let the footer stay at the bottom on the "short page", which means there's not enough content to push the footer down.
this is what I want it to look like:
this is how it look right now:
this is the css code:
.footer {
clear: both;
position: static;
bottom:0;
width: 100%;
margin-top: 5vh;
padding-left:5%;
padding-right: 5%;
margin-bottom: 5vh;
color: white;
}
if I use position: fixed, it will stay at the bottom of the screen, but when it's "long page", it will also overlay the body as I scroll, like this:
position: sticky is the same kind of result.
if it's position: absolute, it will just stuck at the certain spot
I googled the entire day but still, really need some help.
Just for the record, the footer-element goes inside the body-element.
On pages where you don't have enough content to fill up the viewport, you can set the body's height to 100vh which will fill up the entire viewport of the browser. Keep in mind this limits the height to only 100vh, so you can't scroll further down the page. But seeing as there isn't enough content on your page, this shouldn't be an issue. Just make sure you don't apply this styling on other pages where you have enough content to fill up the viewport.
You can then either make wrapper/container-element for your content and apply this styling (you could also apply this directly on the body-element, minus the height: 100%). This will make the container fill up the remaining height of the viewport.
display: flex;
flex-direction: column;
height: 100%;
By then applying margin-top: auto on the footer-element, the remaining space will be converted to the maximum margin-top value possible, thus pushing the entire footer-element to the bottom of the page.
* {
box-sizing: border-box;
margin: 0;
}
body {
height: 100vh;
}
.wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
section {
background-color: tomato;
}
footer {
margin-top: auto;
background-color: limegreen;
}
<body>
<div class="wrapper">
<section>
section
</section>
<footer>
footer
</footer>
</div>
</body>
#head{
height:10vh;
background-color:red;
}
#content{
height:80vh;
}
#footer{
height:10vh;
background-color:blue;
}
body{
margin:0;
padding:0;
}
<div id = 'head'></div>
<div id = 'content'></div>
<div id = 'footer'></div>
I want my footer div to take all the horiziontal space available. Here is my code, but it doesn't work. Hope you can help me!
HTML
<div id=footer>
NewCom France Copyright © 2020
</div>
CSS
#footer {
padding: 12px;
background-color: #999999;
text-align: center;
position: fixed;
bottom: 0;
text-align: center;
margin: 0 auto;
line-height: auto;
}
Margin on a fixed-position element does nothing, and margin on body won't affect it either, as position: fixed positions an element relative to the viewport, outside of the flow of any other elements.
To ensure full width, a fixed-position element will need to have its right and left properties set.
#footer {
/* positioning */
bottom: 0;
left: 0;
position: fixed;
right: 0;
/* other styling */
background-color: #999999;
line-height: auto;
padding: 12px;
text-align: center;
}
As a side note, you have duplicate text-align: center values in your original CSS.
Ordering your CSS properties in a consistent way (for instance, I like to alphabetize my CSS properties, but in the example above also grouped them by type) will help you avoid potentially hard-to-find bugs or duplicate properties.
Is there enough content to fill up 100vh? You can just set your footer to fill that space if not, or set your body height or min-height
I recommend a flexbox layout where the footer does not expand but rather the main content but here is what you are looking for:
body {
display: flex;
flex-direction: column;
background-color: gray;
height: 100vh;
margin: 0;
padding: 0;
}
header {
background-color: red;
}
main {
background-color: blue;
}
footer {
flex: 1 auto;
background-color: green;
}
<body>
<header>
<p>Hi in the header</p>
</header>
<main>
<p>Hi in the main</p>
</main>
<footer>
<p>Hi in the footer</p>
</footer>
</body>
This question already has answers here:
How do you get the footer to stay at the bottom of a Web page?
(32 answers)
Closed 3 years ago.
I am trying to get my footer stick to the bottom of the website, I haven't seen a good answer for making the footer stick to the bottom, when the page height is less than the viewport height and when the viewport height is less than the page height.
You can achieve a sticky footer using flexbox.
Whereas your main grows using flex-grow:1 if the content is smaller than the height of the screen.
Whereas these are to important parts of the code snippet:
html,body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex-grow: 1;
}
header, footer {
height: 50px;
}
header {
background-color: green;
}
.content {
background-color: grey;
overflow: hidden;
}
footer {
background-color: red;
}
html,body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex-grow: 1;
}
<header>header</header>
<main>
<div class="content">
content
</div>
</main>
<footer>footer</footer>
p.s.
This works mainly because of the set min-height and the setting flex-grow: 1 on the flex-child in the middle of the flex-container.
Assuming you have 3 elements in the flex-container with a set height.
The element with flex-grow: 1 will fill the remaining space to reach the parents height. While the other 2 elements just have their height depending on their content.
So as soon your content reaches a size where the content elements min-height is reached, there is no space to fill anymore and it will behave normally like an element with height: auto
If you want a sticky footer, you can use position: fixed;. For example;
footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
}
Is there a way for the footer to be positioned at the bottom no matter how much content is on the page and the content does not overlap with the footer?
Thank You for all your help
Flexbox might be a solution which is pretty flexible. The footer will always be at the bottom of the page unless there is too much content, then it will just be at the end of the page (thus no "overlapping").
document.getElementById("expand").addEventListener("click", function() { document.getElementById("long").style.display = "block"; });
* {
box-sizing: border-box;
}
#container {
display: flex;
flex-direction: column;
align-content: stretch;
height: 100vh;
}
header, footer {
flex-basis: auto;
flex-grow: 0;
padding: 20px;
background: #ccc;
}
div#content {
flex-grow: 1;
padding: 20px;
}
div#long {
display: none;
}
<div id="container">
<header>This is the header with auto-height.</header>
<div id="content">Short Content. <span id="expand"><strong><u>Click here more content!</u></strong></span>
<div id="long"><img src="http://placehold.it/350x1000"></div></div>
<footer>This is the footer, and always at the bottom of the window unless there's too much content.</footer>
</div>
A better idea can be utilizing a css framework like twitter-bootstrap. but if you want to achieve that with css only, something like this in your css file will give you what you need:
footer {
width: 100%;
bottom: 0;
position: fixed;
}
In order to make sure, any content and footer will not overlap you can either set a padding-bottom in your body:
body {
padding-bottom: 60px;
}
or have a content div which you set its 'margin-bottom':
.content {
margin-bottom: 60px;
}
jsfiddle
I have a page that has a header, content, and footer. The header and footer are of fixed height, and I'd like the content to adjust its height so that it fits dynamically between the header and footer. I am planning to put a background-image in my content, so it is critical that it actually fills the rest of the unoccupied vertical space.
I used the Sticky Footer approach to ensure that the footer remains on the bottom of the page. This however does not make the content span the entire height of the remaining space.
I have tried several solutions which involved me adding height:100%, height:auto; position:relative but it did not work.
html,
body {
height: 100%;
background-color: yellow;
}
header {
width: 100%;
height: 150px;
background-color: blue;
}
header nav ul li {
display: inline;
padding: 0 30px 0 0;
float: left;
}
#wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 0 -30px 0;
/* the bottom margin is the negative value of the footer's height */
position: relative;
}
#wrapper #content {
background-color: pink;
width: 400px;
height: 100%;
margin: 0 0 -30px 100px;
padding: 25px 30px 25px 30px;
}
footer {
margin: -30px 0 0 0;
width: 100%;
height: 30px;
background-color: green;
}
<div id="wrapper">
<header>
<div id="logo"></div>
<nav>
<ul>
<li>About</li>
<li>Menu</li>
<li>Specials</li>
</ul>
</nav>
</header>
<div id="content">
content
<br>goes
<br>here
</div>
</div>
<footer>footer</footer>
The trick about height:100% is that it requires all of the parent containers to be have their heights set as well. Here's an html example
<html>
<body>
<div id="container">
</div>
</body>
</html>
in order for the container div with a height set to 100% to expand dynamically to the height of the window you need to make sure that the body and html elements have their heights set to 100% as well. so...
html
{
height: 100%;
}
body
{
height: 100%;
}
#container
{
height: 100%;
}
would give you a container that expands to fit your window. then if you need to have footer or header that floats above this window you can do so with z indexing. This is the only solution I've found that fills the vertical height dynamically.
I'm providing a slightly more general solution so it is more useful for others reading this answer and wondering how to apply it to their site.
Assuming you have three divs:
<div id='header'></div>
<div id='contents'></div>
<div id='footer'></div>
where #header is fixed and may have variable height, #contents should consume all remaining vertical space and #footer is fixed and may have variable height you can do:
/* Note you could add a container div instead of using the body */
body {
display: flex;
flex-direction: column;
}
#header {
flex: none;
}
#contents {
flex: 1;
height: 100%;
overflow-y: scroll;
}
#footer {
flex: none;
}
Note that this will allow the contents to scroll vertically to show it's whole contents.
You can read more about display:flex here.
Try changing your css to this:
html,
body {
height: 100%;
background-color: yellow;
}
header {
width: 100%;
height: 150px;
background-color: blue;
}
header nav ul li {
display: inline;
padding: 0 30px 0 0;
float: left;
}
#wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 0 -30px 0;
/* the bottom margin is the negative value of the footer's height */
position: relative;
}
#content {
background-color: pink;
width: 400px;
padding: 25px 30px 25px 30px;
position: absolute;
bottom: 30px;
top: 150px;
margin-left: 100px;
}
footer {
margin: -30px 0 0 0;
width: 100%;
height: 30px;
background-color: green;
}
<div id="wrapper">
<header>
<div id="logo"></div>
<nav>
<ul>
<li>About</li>
<li>Menu</li>
<li>Specials</li>
</ul>
</nav>
</header>
<div id="content">
content
<br>goes
<br>here
</div>
</div>
<footer>footer</footer>
You probably don't want to be setting the width, padding, margins, ect. of the wrapper. Also, with absolute positioning you can pull the bottom and top of the content to where you want them.
Here's what you are after, I think.
I spend several hours trying to figure this out too and finally have a robust solution without hacks. However, it requires CSS3, which requires a modern browser to support it. So, if this constraint works for you, then I have a real solution for you that works.
http://jsfiddle.net/u9xh4z74/
Copy this code into your own file if you need proof, as the JSFiddle will not actually render the flexbox correctly as embedded code.
Basically, you need to
- set the target container to 100% height, which you seem to already know
- the parent container you set display: flex and flex-direction: vertical (you'll see in the JSFiddle I've also included the alternate styles that do the same thing but are needed for cross browser support)
- you can let the header and footer be their natural heights and dont need to specify anything in that regard
- in the container you want to fill up the remaining space, set flex: 1. You're set! You'll see it works exactly as you semantically have intended. Also in the JSFiddle, I included overflow: auto to demonstrate that if you have even more text than the screen can handle, scrolling works as you would want it to.
<div style="display:flex; flex-direction:vertical;">
...header(s)...
<div style="flex: 1; overflow: auto;">
As much content as you want.
</div>
...footer(s)...
</div>
As a side note, I pursued the option of trying to do this same thing using display: table. It works just fine as well, except that overflowed content does not work as you would expect, instead overflowed content simply expands the container to the size of the content, which I'm pretty sure is not what you want. Enjoy!
Use display:table and display:table-row
Set height:0 for normal divs and height:auto for div that should fill vertical space. Insert a div with {height:100%; overflow-y:auto} into the vertical filler to if the containers height shouldn't expand beyond its preset height.
Behold the power of display:table!
<div style="height:300px;">
<div style="display:table; height:100%; width:100%;border: 1px solid blue;">
<div style="display: table-row; height:0; padding:2px; background-color:yellow;">
Hello
</div>
<div style="display: table-row; height:auto; padding:2px; background-color:green;">
<div style="height:100%; overflow: auto;">
<div style="height: 500px"></div>
</div>
</div>
<div style="display: table-row; height:0; padding:2px; background-color:yellow;">
Gbai
</div>
</div>
</div>
There is no 100% height from 100% continer height exactly. You can't solve it this way. Likewise while using mix of height + margin + padding. This is way straight to hell. I suggest you to take a look for tutorials which are sloving this page layout.