On initial page load, I need the header image height to be calculated, and then push the main section below it. (The header is fixed and without this, main would display at the top of the page). In Chrome, there's no issue, everything works fine. In Safari and Firefox, main displays 20px from the top of the browser, which is the margin of main.
JS:
var headerHeight = $('#head-image').height();
function pageSetup(elementHeight) {
var main = $('main');
var headerHeightPx = elementHeight +'px';
main.css({'paddingTop': headerHeightPx});
}
$(window).on('load', function() {
pageSetup(headerHeight);
});
HTML:
<header>
...
<div class='foo'>
<img src='image.jpg' id='head-image'>
</div>
<header>
<main>
...
</main>
CSS:
#head-image {
position: fixed;
z-index: 1;
}
main {
margin: 1.5em 0;
position: relative;
z-index: 2;
}
Related
I have sticky block on my page. It sticks to the bottom of the page, when the bottom of the viewport reaches its top. And the block must stop to be sticky before footer (when the bottom of block reaches the top of footer) and stay before footer.
The problem is in inserting block before footer: nothing happens when buttons reach footer. Why does it happen?
HTML
<header>
<div class="block"></div>
</header>
<main></main>
<footer></footer>
CSS
header {
position: relative;
}
.block {
position: absolute;
bottom: 10px;
}
.block-fixed {
position: fixed;
bottom: 0;
}
JS
$(function() {
var blockPrimaryPosition = $(".block").offset().top;
function makeSticky() {
var block = $(".block");
var blockHeight = block.offset().top + 75; // coordinate of the bottom side of the block at any time
var totalHeight = $(window).scrollTop() + $(window).height(); // coordinate of the bottom of the viewport relative to the document
if (totalHeight >= blockPrimaryPosition) {
block.addClass("block-fixed");
} else if (buttonsHeight >= $("footer").offset().top) {
$("footer").before(block);
block.removeClass("block-fixed");
} else {
block.removeClass("block-fixed");
};
};
$(window).scroll(function() {
makeSticky();
});
});
(I am looking for an HTML/CSS fix but if there really is none then JS (prefereably JQuery) works for me)
I have two main divs inside my page, I have the #maincontent and the #footer.
Basically, I want the footer to always sit at the bottom on the page:
#footer{
position:fixed;
bottom:0;
}
BUT I do not want it to overflow on the #maincontent when the page is too small.
For the sake of the question the page can be thought of as simple as:
<body>
<div id="maincontent">Dynamic Content</div>
<div id="footer">StaticContent</div>
</body>
My problem is that I can do one or the other, either I fix it to the bottom of the page but when I make the viewport < (footer + maincontent) the footer sits on top of the content. I want the footer to always be at the bottom of the page but disappear off page before it overtakes the main content.
Add a class to the footer with jQuery that changes it to position: absolute when the viewport is too small.
$(document).ready(function() {
var height = $(window).height();
function windowHeight() {
height = $(window).height();
}
windowHeight();
$(window).resize(function() {
windowHeight();
});
if (height < 600) { //arbitrary height value you can set yourself
$('#footer').addClass('not-fixed');
} else {
$('#footer').removeClass('not-fixed');
}
});
If you know your footer's height whatever happens to the window height, or its content :
Just add a "padding-bottom" to your body or main content that matches the footer's height.
If you don't know your footer's height. This is trickier, as you will probably need some javascript to calculate the height of the footer, the height of the main content, compare the sum of both with the window height, and if it doesn't fit, add some adequate bottom padding to the body / main content.
EDIT :
Ok I understand, I think this jsfiddle should do the trick : http://jsfiddle.net/ah4XA/2/
The javascript would be :
$(document).ready(function () {
function updateFooter () {
var footerH = $("#main-footer").height();
var contentH = $("#main-content").height();
var windowH = $(window).height();
if ( contentH + footerH > windowH) {
$("#main-footer").removeClass("fixed");
} else {
$("#main-footer").addClass("fixed");
}
}
$(window).resize(function () {
updateFooter();
});
updateFooter();
});
If I understand what you're looking for, you want the footer to stay on the bottom of the window regardless of the page content, but also not overlap the page as the window is resized vertically.
One possible solution is to switch between position:absolute; and position: fixed; with a media query. So past a certain height it's fixed, but below that the footer position:absolute;.
EXAMPLE FIDDLE
CSS:
#media all and (max-height:300px) {
#footer {
background: red; <- added for testing
position: absolute;
}
}
The only drawback to this approach is that you need to know the height to set the switchover to. This may be tricky, but position:fixed;.
The simplest solution would be to position footer at the bottom permanently and increase the z-index of your maincontent so that it comes over the footer if window size is decreased.
NOTE: This is not the only way to do this.
JSFIDDLE DEMO
Sample CSS
#maincontent{
height : 400px;
background-color : green;
/*
position : relative is added to enable z-index.
*/
position:relative;
/*
z-index will bring it above footer,
if window size is reduced.
*/
z-index: 1;
width : 100%;
}
#footer{
height : 100px;
width : 100%;
background-color : black;
/* Below two properties will
postion footer at the bottom of the page.
*/
position : fixed;
bottom : 0;
color : white;
}
You should play with CSS position property to get this done.
EDIT:
Here is another CSS solution :
The maincontent and footer are wrapped in a bodyContainer div its position is set to relative and then footer is positioned w.r.t it.
JSFIDDLE DEMO 1 Footer is below body and not shown.
JSFIDDLE DEMO 2 Footer is shown since body height is less.
HTML
<div id="bodyContainer">
<div id="maincontent">Dynamic Content
</div>
<div id="footer">StaticContent</div>
</div>
CSS
#bodyContainer {
min-height: 100%;
position: relative;
}
#maincontent{
height : 800px;
background-color : green;
padding-bottom: 60px;
width : 100%;
}
#footer{
background-color: black;
bottom: 0;
color: #FFFFFF;
height: 48px;
position: absolute;
width: 100%;
}
I am asked to get a footer on the bottom of every page of the html web page print out (not the actual page on the browser). Do you guys know any way to do it? (It should work on IE, and just IE is fine)
I tried using fixed bottom, but contents overlaps with the footer.
I tried using javascript to calculate space and give an empty div the height: was using if bottom of the footer % page height !=0, add Required gap. But the value of the bottom of the footer and required white space seems to change with change in elements type.
var printPageHeight = 1900;
var mFooter = $("#footer-nt");
var bottomPos = mFooter.position().top + mFooter.height();
var remainingGap = (bottomPos <printPageHeight ) ? (printPageHeight -bottomPos) : printPageHeight - (bottomPos % printPageHeight );
$("#whiteSpaceToPositionFooter").css("height", remainingGap+"px");
I tried using table, works well for all the pages, except the last one.
I tried few other margin and such tweaks but they didn't work either.
I actually want the footer to be displayed only on the bottom of the last page of the print out if that's possible.
I'm answering my own question just in case if anyone else needs a solution.
After a long research and intensive tries (mainly trial and errors), I used following logic to set the footer only on the bottom of the last page: -
In css: #media print { position: fixed; top: 0; left: 0; z-index -1; } Ad IE displayed it on bottom of every page, and was sent to background by z-index.
Still, the background of text in IE was transparent in print out, so the text was on top of footer. So, used white image of 1px by 1px in absolute top left position to act as an background of the image.
Used javaScript to set the height and width of the image same as the height of the div that had content.
html:
<body>
<div id="wrapper"> <!-- not necessary -->
<img scr="./img/white.png" id="whiteBg" />
<div id="content">
<!-- content here -->
</div>
</div>
<div id="footer">
</div>
</body>
css:
#media screen {
#whiteBg {
display: none;
}
}
#media print {
#whiteBg {
display: block;
position: absolute;
top: 0;
left: 0;
z-index: -1; //to send it to the background
}
#wrapper {
padding-bottom: (the size of the footer, to make footer visible on last page).
}
#footer {
position: fixed;
bottom: 0;
}
}
jquery:
#('#whiteBg').height( $('#content')).height() );
TO GET FOOTER ON THE BOTTOM OF EVERY PAGE, I USED: (2nd Scenario)
css:
#media print {
#footer {
position: fixed;
bottom: 0;
}
body {
margin: x x y x; (y should reflect the height of the footer);
}
Maybe something like this?
<link rel="stylesheet" href="print.css" type="text/css" media="print" /> /* this css file is only for printing purposes*/
body:after {
content: "I am the footer";
}
Use the last element you have in the end of the document instead of body...
I have a specific problem on making a sticky header with jQuery. I tried the commonly used snippets around the web, but I perceived the same buggy thing everywhere.
At a specific document height (scrollable until a little more than calling of sticky-effect) the sticky header jumps between position: fixed and position: static.
HTML:
<header>
<div id="not-sticky"></div>
<div id="sticky"></div>
</header>
<div id="content"> ...
jQuery:
var $sticky = $("#sticky");
var offset = $sticky.offset();
var stickyTop = offset.top;
var windowTop = $(window).scrollTop();
$(window).scroll(function() {
windowTop = $(window).scrollTop();
if (windowTop > stickyTop) {
$sticky.css({
position: 'fixed',
top: 0
});
}
else {
$sticky.css({
position: '',
top: ''
});
}
});
CSS:
header {
width: 100%;
}
#not-sticky {
padding: 50px 0;
width: 100%;
}
#sticky {
padding: 24px 0;
position: relative;
width: 100%;
z-index: 25;
}
I also tried a margin-bottom on #not-sticky with the same height as the #sticky to keep a constant document-height, but the same jumpy-sticky-effect occurred.
Any idea to fix that thing?
Scroll fires too many times and trying to set an element style will always & inevitably create jumps (even barely noticeable but still jaggy).
The best way I've found is to
clone our element,
make that clone fixed
play with clone's visibility style.
Pure JS:
;(function(){ /* STICKY */
var sticky = document.getElementById("sticky"),
sticky2 = sticky.cloneNode(true);
sticky2.style.position = "fixed";
document.body.appendChild(sticky2);
function stickIt(){
sticky2.style.visibility = sticky.getBoundingClientRect().top<0 ? "visible" : "hidden";
}
stickIt();
window.addEventListener("scroll", stickIt, false );
}());
#sticky{
height:100px;
background:#ada;
height:50px;
position:relative;
/* needed for clone: */
top:0;
width:100%;
}
/* Just for this demo: */
*{margin:0;padding:0;}
#content{height:2000px; border:3px dashed #444;}
h1{padding:40px; background:#888;}
<h1>Logo</h1>
<div id="sticky">Sticky header</div>
<div id="content">Lorem ipsum...<br>bla bla</div>
So when you see the "header" fix, that's actually our fixed clone getting visible on-top.
I have centered (position: absolute; left: 50%; margin: -50px;) 100px width div (container).
It has absolutely positioned child div with overflow: hidden, its size is 100x2000 px (such height is for test purposes, as described below).
There is an image in child div, it is absolutely positioned.
The image is 3100x100 px, it contains frames of animation.
I am animating this image by changing its style.left from 0 to -1100px, step is 100px.
Everything is fine, but I encounter weird issue when body width is not even.
It can happen if there is scrollbar and the scrollbar has odd width (it happens for me on Chrome/Win32 for example).
In this case image visually shifts by 1 pixel horizontally as soon as animated image goes through screen edge (for 1920x1080 it happens roughly at 9-10 frame of animation).
I can't find workaround for this behavior.
Working example reproducing the problem can be found here
Child div height is set to 2000px to make sure scrollbar is visible.
If your scrollbar has even width, you can reproduce the problem by resizing your browser window to odd width.
That happens because of the browsers rounding engines. Webkit apparently has some problems with 50% on even and odd widths.
One way to overcome the issue - re-position the .outer element based on window width
document.getElementById( 'outer' ).style.left = Math.floor( window.innerWidth / 2 ) + 'px';
DEMO
You need to change .inner img position to relative and update your javascript. I made changes for you, so here is your solved code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
body {
background-color: #000000;
}
.outer {
position: absolute;
left: 50%;
margin-left: -50px;
}
.inner {
position: absolute;
width: 100px;
height: 2000px;
overflow: hidden;
}
.inner img {
position: relative;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
<img src="http://lorgame.ru/test.png" id="img">
</div>
</div>
<script language="JavaScript">
var framesCount = 30;
var framesCurrent = 0;
var framesMoveLeft = true;
var img = document.getElementById('img');
var interval = setInterval(function() {
if(framesMoveLeft == true){
framesCurrent++;
img.style.left = (img.offsetLeft - 100) + 'px';
if(framesCurrent == framesCount) framesMoveLeft = false;
} else { // Move right
framesCurrent--;
img.style.left = (img.offsetLeft + 100) + 'px';
if(framesCurrent == 0) framesMoveLeft = true;
}
}, 100);
</script>
</body>
</html>
To me this seems like a bug in Chrome. When percentages are defined in integers, they behave rather unexpectedly. Try to define the position as a decimal instead:
.outer {
position: absolute;
left: 49.99999%;
margin-left: -50px;
}
I tested this on the fiddle and it seems to do the trick.