I have a fixed header at the top of the screen, and if I try to put an element after the header, said element ends up ignoring the height of the header.
HTML
<header></header>
<p>Empty text</p>
CSS
header {
display: block;
height: 100px;
width: 100%;
background: #eee;
position: fixed;
top: 0;
z-index: 100;
}
JSFIDDLE
I've searched on StackOverflow and other places for solutions to problems similar to this but with no avail (in part due to me having a hard time verbalizing the specific problem). I tried a clearfix,
<header></header>
<div style="clear:both"></div>
<p>Empty text</p>
But that still doesn't work. I also tried adding a margin-top: 100px to the p element, but I consider that bad practice in the case of me changing the height of the header in the future, and also having to do this for every single element following the header or any other element I might add a position: fixed or position: absolute. Additionally, the header will be a fluid height according to different sized screens.
Right now I'm wireframing so I'd really rather not use JavaScript, just plain CSS, if that's possible. If it's not, minimal vanilla javascript will do. This is a fundamental web design problem and I've always countered it with margin-top but I'm wondering if anyone knows of a cleaner, better way to counter it.
Also, this needs to be at least somewhat cross-browser. Again, only wireframing. My wireframes should be able to work on anything that supports basic CSS.
Sorry if this is a duplicate question, I'm sure it is, but I couldn't find anything that quite matches my situation. Any help is much appreciated!
http://jsfiddle.net/09qL0nzv/3/
var p = document.getElementsByTagName("p")[0],
header = document.getElementsByTagName("header")[0],
h = window.getComputedStyle(header).getPropertyValue("height");
p.style.marginTop=h;
This will set a margin-top to the paragraph equal to the height of fixed header. However, this does not take padding or border into account. There are two possible solutions for this.
Use box-sizing: border-box on the header. This will make sure that the height, including padding and a border, will be the height as defined in the stylesheet. (I highly recommend using border-box on all your elements, like so: *, *:before, *:after {-moz-box-sizing:border-box;box-sizing: border-box;}.)
Another solution is adding the padding and border to the computed value in JavaScript, and include that value in the margin top that you set to p. I don't like this solution, but it works.
When you fix the header, any other element you place disregards its very existence.
Only workaround I've seen is to give a padding (or margin). But, from what I understood you need a more dynamic soln. In which case your best solution would be to use client-side scripting say jquery/js to determine elements present height and then add the same as padding for elements below.
It's the position:fixed that causes the problem here. The header is no longer part of the flow content, so the flow content begins at the top of the page.
There is no ideal solution for this, but an option that might be a little better than changing the <p> margin is to add an empty <div> to the beginning of your content that matches the height of the <header>.
Here's an example JSFiddle:
For a more dynamic solution, this is what I came up with
$('p').css('margin-top', $('header').outerHeight());
$(window).resize(function() {
$('p').css('margin-top', $('header').outerHeight());
});
There might be a better way of doing this, but my reasoning was setting the initial margin of the p tag to be the outer height of the entire header, and then whenever the header might change (in this case, that would be when the window is resized), the margin is then re-evaluated on the p tag.
Related
I ran into this issue while implementing a sticky footer solution. I have the footer working well, but my body element which encompasses everything within the tag just will not auto-extend beyond a random point further down that can only be reached by scrolling down (it's a lengthy page). My intention is for the body container (does that sound morbid or what?) to auto extend past all the div elements it contains. Isn't that what it's supposed to be doing? Right now there are still div elements sitting further down from where it ends, and the footer is sitting in the middle of my page right below it. If I can't achieve this behavior, I'll have to set the body to a fixed position in css, which I don't want to do.
Using the following CSS styling doesn't work, probably because my content extends beyond a page.
html, body {min-height: 100%; height: 100%;}
Can someone articulate what the most likely issues could be? Also, feel free to make any constructive comments on my code. This is my first web project.
Here's a link to my HTML code on CodePaste: HTML Code
And here's a link to my CSS code: CSS Code
Lastly, a link to a screenshot of my webpage showing the issue. Screenshot
The green bar is the footer, and the red border is the body element styled in css so it can be viewed. You'll see it ends right after the picture.
I'm pretty sure your main problem is setting the height of the body tag. Try not giving it a height (no max-height or height tags) or giving it height: auto to make it expand as its contents.
It could also be that you are setting child elements to positon: absolute which means that the parent will collapse to the size of whatever non-absolute elements are inside it.
Also, why the <p1> tags? They should be just <p>.
Code criticism:
It was extremely difficult to figure out what the problem was and I'm not sure that I gave the correct solution because of the way you showed your code. In future, try to give your code as a JSFiddle or a Codepen.
Also, consider using a CSS framework which will reduce the amount of CSS code you write a lot. I would suggest Bootstrap or Materialize but Bootstrap is more widely used.
Don't forget to follow CSS guidelines which will make your code more readable.
You could stretch the element to the full height of the window using vh.
.container{
height: 100vh;
}
You could then position your footer to the bottom using absolute position.
footer{
position: absolute;
bottom: 0;
}
I've used this in the past for full page landing pages that aren't meant to scroll.
I don't exactly know what the question is asking, but I experimented a bit and figured that if you remove the 1 from the <p1> so you would have a normal <p> tag, it moves the text up completely. I have a very rough JS Fiddle.
Thanks to all who contributed. Based on suggestions from Sankarsh and Ori, I was able to solve the problem. Once I changed my div to just as they suggested, I noticed it began functioning as I intended and forcing the parent element down beneath it. Unfortunately, that only solved the problem for that element alone. That led to me discovering the element had a default "static" position, while most of my other elements were set to "absolute". After changing the positions of the bulk of my content to "relative" or "static", everything is working as intended!
TLDR: If you want a child element to stay within the boundaries of its parent element, you need to set the child's position to "static" or "relative". You cannot use "absolute". This way, instead of overflowing beyond the border of the parent, the child will automatically extend the parent's border to its intended position.
I'm working on a website in which sometimes the pages might not cover the entire height of the screen (due to less content), which creates empty white space below the footer. I'm trying to solve this by always keeping the footer below the viewport. I've tried many ways to do this, but all of them solve one problem and create another.
Here is a jSFiddle for what I have so far.
The only time it actually worked was when I set height:100% to the body and html, but this makes the content overflow the body in the DOM, which I'm trying to avoid. Also, because the site needs a boxed layout, I need to wrap the page-content and footer with the #page-wrapper div as used in the code.
Please let me know if there is a way to achieve this, with the given markup.
Thanks!
Edit: Here is a slightly updated jSFiddle
I think you can do this by absolutely positioning the footer and making the page-wrapper relatively positioned. The catch is that you'll have to size the page-wrapper using JS based on the height of the HTML element. Something like:
$('#page-wrapper').height($('html').height());
but you may need to tweak the position quite a bit unless you use
* { box-sizing: border-box; }
I'm wondering what's the best way to deal with this: I have two div in document flow (nav + content), positioned as relative.
In some situations, I will need to give the nav a fixed position. As this removes the nav from the flow, the content div is no longer properly located below. I could add the content some top-margin to compensate, but this would have to be computed because the nav doesn't have a set height (in my example, it's 50% of the window height).
Any suggestion?
JSFiddle: http://jsfiddle.net/6gkVS/
The best way to calculate a number and apply somewhere else, is javaScript, because you have to find that number after the DOM is loaded.
I'm going to just say that as of (this date) you shouldn't be using fixed positioning at all without testing for touch with modernizr, and only in the case that it's "no-touch" use fixed, due to the less that adequate browser support on mobile and touch enabled desktop. Try one out at a store and you'll see what I mean. Jumpy weird fixed headers everywhere.
The fact that your divs are relative doesn't really matter.
The best thing to do, is run modernizr. It will spit out a no-touch class on your html that you can use to style with.
.no-touch nav {
position: fixed;
top: 0; left: 0;
}
Then with jQuery, you can do something along these lines - if you are using box-sizing: border-box (which I suggest) than you'll want to use '.outerHeight()' to be sure to include padding and borders. You'll also only want a fixed header when the screen is big enough to accommodate it.
var windowHeight = $(window).height();
var navHeight = $('nav').outerHeight();
if ( windowHeight > 600 ) {
$('nav').addClass('fixed-nav');
$('section').css('margin-top', navHeight);
}
Here is a fiddle. I hope that helps. Sorry there is no way to do it with CSS yet. That would be cool.
I'm developing a 4 column footer in CSS, but after wrestling with this for a few hours there are two things that I cannot achieve.
1) Replicating the padding of the first column in the three subsequent columns
2) Extending the vertical border the entire 250px.
Does anyone have any ideas? Here is my code
http://jsfiddle.net/FdHAR/
The best thing to do here is to add a class, possibly footer-column, that you apply to each of the divs. Then put those four divs in a div with the class footer. Your structure would look something like this:
<div class="footer">
<div class="footer-column" id="footer_column1">...</div>
<div class="footer-column" id="footer_column2">...</div>
<div class="footer-column" id="footer_column3">...</div>
<div class="footer-column" id="footer_column4">...</div>
</div>
Obviously, we need to change the styles foor this to look right.
Padding
Let's address the padding first: all you really have to do is select the class and put some padding-left and padding-right on it. It will automatically apply the same padding to each one that way. Also, to make them appear side-by-side, we need to float them. Something like this will do:
.footer-column {
float: left; // Push the div as far up-left as it can be put
width: 25%; // Make sure to subtract the padding
padding: 10px; // We want padding on all sides to make things look nice
}
Now that that's done, let's fix the borders.
Vertical Borders
This is a bit more difficult, unless you know the overall height of the footer. Either way, we can use the CSS selector :first-child to apply the borders. This should do it:
.footer-column {
...
border-left: 1px solid black; // Whatever border you want goes here.
}
.footer-column:first-child {
border-left: none;
}
If you know the height of the footer, you can force that height, and the border will work just fine.
.footer-column {
...
height: 250px; // Force the box to be 250px tall
}
If you don't know the height of the footer, you'll have to use some other styling and possible javascript. But I'll assume you do since you stated a specific value in the question.
You want to use display: table and display: table-cell: http://jsfiddle.net/FdHAR/3/
1) Add
padding-left: 15px;
to #col2,3,4 moves the text off of the vertical white bar. You may need to play with the value to get the exact spacing you're looking for.
2) add height: 250px; to #container4 to make it the right size.
Caveats: this is after a few minutes of adjusting on safari -- your browser may vary...
Played with this a bit, I think this is closer to what you want and should work well across browsers. I'd recommend a fixed width or a min-width on the footer (<footer> is html5).
jsFiddle
Some constructive feedback:
Try to combine your styles as much as possible. No need to re-write and re-set padding, etc across similar elements.
You had div, inside div, yet were treating them like columns. A simpler approach is to use a list and think of each list item as a column. If you wanted to do divs, then don't put them inside each other.
I like to use em for setting font-size or line-height, but use px for anything else. (personal preference, makes sense since it's a screen you're usually working for)
Try to set only 1 or 2 specific strict sizes and then use percentages of that. A good thought is setting the footer font-size to 1.2em, then the h1 could be font-size 130% and smaller could be 80%. This also works well for width, etc. (each column is 25% of the parent).
a jsFiddle hint, you don't need to put the whole html doc there, just the part you want to fiddle with, same for css and jquery drop the ,.
I have been trying for 2 hours to get my footer to stay at the bottom.
I have been trying "Matthew James Taylors" technique, but no luck.
Anyone see what I am missing or doing wrong?
Here is a Live Example : http://glustik.com/essex/index.html
Any help would be GREAT!
I would attached the CSS Code with the { } but it always breaks for me.
I feel like the CSS to fix this will still be problematic, I would be tempted to rewrite the whole thing: HTML markup and CSS, otherwise I suspect there will be more trouble down the road.
Here are some things that are most likely giving you trouble:
Duplicate id values (as mentioned)
Unnecessary absolute positioning
Hard-coded height values on several divs
Unnecessary use of "clearfix" divs
Overuse of negative margins to compensate for padding on other elements (always problematic)
Minor but relevant: use of classes like floatRight, just as bad as using inline styles.
I think in general, instead of trying to control the positioning and height of everything - just let the normal content flow dictate it. Naturally, the last element in your markup (footer) should be on the bottom without all these over-thought restrictions.
Best of luck!
EDIT: Apparently I've come off as unhelpful, so I felt I should add a direct response: For a quick fix, to simply get the footer on the bottom:
Remove the height and bottom padding from #mainBody
(tested in FF4 and IE8). There will still be some padding issues within the footer, but that can be resolved in a number of ways depending on how you'd like to approach it. Once again, good luck with your project.
You have the footer positioned absolutely in #container, which is positioned relatively. therefore, its being positioned at the bottom of #container.
try moving it out of #container, or remove the relative positioning from #container
Because all of the content inside your main container (#mainBody) is floated, the container's only way to determine it's height is via the "height" property, which is set to 100px;. The footer is correctly rendering right below the 100 pixel height of the main container.
You have three options:
you can either properly clear your main container so that its height is dynamic based on its content using a clearfix like this
or you can set the height of the main container to something larger. I changed it to 700px and the footer rendered well below the main body.
or you can remove the height altogether, which will probably be the best solution in the long-run. Thanks to #Gaby aka G. Petrioli for pointing this out.
I've been doing this a long time and have never heard of this method. That doesn't make it bad, but the currently accepted version in my circles comes from Ryan Fait (http://ryanfait.com/resources/footer-stick-to-bottom-of-page/)
If you load this up in Chrome and disable the position:relative from the container it does properly glue the footer to the bottom of the page. That signals a problem to me, because it's contrary to what the tutorial says. Regardless, it accomplishes your goal.
You should take at least a look at Compass. It makes CSS so much easier. For your particular question, take a look at:
http://compass-style.org/reference/compass/layout/sticky_footer/
Make the following changes and it rendered fine in Chrome for me:
remove bottom:0; from #footer
change padding-bottom:167px; in #mainBody to the desired location (I used 455px and it looked pretty good)