Is there any way, bearing in mind the way the jQuery Mobile framework operates, to fix the page so that the footer always aligns with the bottom of the page - no matter the height.
As it stands the height of a jQuery page will change, especially as devices are rotated portrait to landscape, so the solution would have to take this into account.
Just to clarify - I don't need the footer to be at the bottom of viewport, just working so that the default page height doesn't drop below the viewport height.
Thanks.
You can add this in your css file:
[data-role=page]{height: 100% !important; position:relative !important;}
[data-role=footer]{bottom:0; position:absolute !important; top: auto !important; width:100%;}
So the page data-role now have 100% height, and footer is in absolute position.
Also Yappo have wrote an excellent plugin that you can find here:
jQuery Mobile in a iScroll plugin
http://yappo.github.com/projects/jquery.mobile.iscroll/livedemo.html
hope you found the answer!
An answer update
You can now use the data-position="fixed" attribute to keep your footer element on the bottom.
Docs and demos: http://view.jquerymobile.com/master/demos/toolbar-fixed/
Since this issue is kind of old a lot of things have changed.
You can now get this behavior by adding this to the footer div
data-position="fixed"
More info here:
http://jquerymobile.com/test/docs/toolbars/bars-fixed.html
Also beware, if you use the previously mentioned CSS together with the new JQM solution you will NOT get the appropriate behavior!
In my case, I needed to use something like this to keep the footer pinned down at the bottom if there is not much content, but not floating on top of everything constantly like data-position="fixed" seems to do...
.ui-content
{
margin-bottom:75px; /* Set this to whatever your footer size is... */
}
.ui-footer {
position: absolute !important;
bottom: 0;
width: 100%;
}
Fixed basics
To enable this behavior on a header or footer, add the
data-position="fixed" attribute to a jQuery Mobile header or footer
element.
<div data-role="footer" data-position="fixed">
<h1>Fixed Footer!</h1>
</div>
jQm offers:
http://jquerymobile.com/demos/1.0b1/#/demos/1.0b1/docs/toolbars/docs-footers.html
http://jquerymobile.com/demos/1.0b1/#/demos/1.0b1/docs/toolbars/bars-fixed.html
http://jquerymobile.com/demos/1.0b1/#/demos/1.0b1/docs/toolbars/bars-fullscreen.html
http://jquerymobile.com/demos/1.0b1/#/demos/1.0b1/docs/toolbars/footer-persist-a.html
None of these work?
The following lines work just fine...
var headerHeight = $( '#header' ).height();
var footerHeight = $( '#footer' ).height();
var footerTop = $( '#footer' ).offset().top;
var height = ( footerTop - ( headerHeight + footerHeight ) );
$( '#content' ).height( height );
I thought I'd share my CSS only solution here. This way you can avoid the extra overhead of using JS for this.
This isn't a fixed position footer. The footer will be offscreen if the page content is taller than the screen. I think it looks better this way.
The body and .ui-page min-height and height are necessary to prevent the footer from jumping up and down during transitions.
Works with the latest JQM version as of now, 1.4.0
body,
.ui-page {
min-height:100% !important;
height:auto !important;
}
.ui-content {
margin-bottom:42px; /* HEIGHT OF YOUR FOOTER */
}
.ui-footer {
position:absolute !important;
width:100%;
bottom:0;
}
This script seemed to work for me...
$(function(){
checkWindowHeight();
$(document).bind('orientationchange',function(event){
checkWindowHeight();
})
});
function checkWindowHeight(){
$('[data-role=content]').each(function(){
var containerHeight = parseInt($(this).css('height'));
var windowHeight = parseInt(window.innerHeight);
if(containerHeight+118 < windowHeight){
var newHeight = windowHeight-118;
$(this).css('min-height', newHeight+'px');
}
});
}
Adding the data-position="fixed" and adding the below style in the css will fix the issue z-index: 1;
http://ryanfait.com/sticky-footer/
You could possibly use this and use jQuery to update the css height of the elements to make sure it stays in place.
Related
I'm working with a div sitting above another div. When I scroll the div that sits above the other and reach the bottom, it scrolls the entire body. This is hard to explain so I made a fiddle to demonstrate the effect: http://jsfiddle.net/2Ydr4/
HTML:
<div class="body">
<div class="above">
<!-- Content in here that is longer than the height -->
</div>
</div>
CSS:
.above {
width: 300px;
height: 200px;
overflow-y: scroll;
background: red;
z-index: 10;
position: fixed;
}
My question is: how do I prevent the body scrolling when the floating div is scrolled to the bottom or top? I'm sure it's something really obvious that I'm missing. Thanks!
EDIT: I should probably have mentioned that the target device for this was an iPad. I've tried adding body {overflow: hidden} conditionally as suggested below, and while this solves the problem on a desktop browser, it still seems to persist on a touch-based browser.
Desktop
That's how scrolling works. What you will need to do is remove the body's scroll property temporarily or by the users action.
For example you could disable the body's scroll when the user hovers over the floating div by using...
body{overflow:hidden}
and then re-enable it when you hover off the floating div by using..
body{overflow:auto}
Mobile
On mobile devices you will need to use touch events. I haven't tried this but in theory this should work.
var $body = document.querySelector('.body'),
$above = document.querySelector('.above');
$above.addEventListener('ontouchstart', onAboveStart, false);
$body.addEventListener('ontouchstart', onBodyStart, false);
function onAboveStart()
{
$body.addEventListener('ontouchmove', function(e) {e.preventDefault()}, false);
}
function onBodyStart()
{
$body.removeEventListener('ontouchmove', function(e) {e.preventDefault()});
}
I have a website like this one: >> website <<. It is built from 2 frames - main and a footer. I was trying to get it working without frames (don't work on mobile phones). Is there any simple CSS or jQuery method to stick the footer on the bottom to be visible always? so the effect is like on the website above? I was trying to use css, but the footer appears only when I scroll down to it. I want the footer to cover the actual content, so it's always for example 50pixels high and is always visible on the bottom of the screen. even if the page is 10000px high. I believe it's something simple, but I got lost somewhere there. Thank you for your help in advance
Yes. It's the position: fixed property.
.footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 50px;
}
Demo: http://jsfiddle.net/ZsnuZ/
(function() {
$('.footer').css('position', $(document).height() > $(window).height() ? "inherit" : "fixed");
})();
Continuing on from Sam Jones:
Basically this checks to see if the height of the document will fill the window, if it is less than the window, it will attach to the bottom of the window, if the document is larger than the window size it will attach to the bottom of the document (so it is only visible when you scroll to the bottom).
If you resize the window it will recalculate and everything should work properly!
CSS
#footer {
bottom: 0px;
}
HTML
<div id="footer">
Footer content
</div>
<script>
var footerResize = function() {
$('#footer').css('position', $("body").height() + $("#footer").innerHeight() > $(window).height() ? "inherit" : "fixed");
};
$(window).resize(footerResize).ready(footerResize);
</script>
We can even compare the heights and set the footer at the bottom using below code.
$(document).ready(function(){
if($("body").height() < $(window).innerHeight()) {
$('#footer').css('position','fixed');
$('#footer').css('bottom',0);
}
});
For me this works better, because body height includes the footer when position is static or inherit:
var footerResize = function() {
if ($('#footer').css('position') == "fixed")
$('#footer').css('position', $("body").height() + $("#footer").height() > $(window).innerHeight() ? "inherit" : "fixed");
else
$('#footer').css('position', $("body").height() > $(window).innerHeight() ? "inherit" : "fixed");
};
It stays on the bottom when growing the window now.
I want a footer in Jquery Mobile, that is not fixed, but is always at the bottom of the page.
Like this: http://ryanfait.com/sticky-footer/ (but in JQuery Mobile), not like like the standard JQuery Mobile Fixed footers.
So the footer should appear at the end of the content, or the bottom of the screen, whichever is lower.
Any ideas on how to approach this?
Edit:
The basic problem, is that I seem unable to get the div with data-role=content to actually take up the full height of the screen.
I solved this using mostly CSS. The advantages of this over the accepted answer is it will handle cases where the page size changes after the page is shown (such as browser resize, orientation change, or even more simple cases like collapsible/accordian sections). It also has much less Javascript code, and no layout math.
CSS:
html, body {
margin: 0;
padding: 0;
height: 100%;
}
[data-role=page] {
min-height: 100%;
position: relative;
}
[data-role=content] {
padding-bottom: 40px; /* based on how tall your footer is and how much gap you want */
}
[data-role=footer] {
position: absolute;
bottom: 0;
width: 100%;
height: 40px /* this can be configurable, or omitted, as long as the above padding-bottom is at least as much as the height of the footer is */
}
The absolute footer caused jQuery Mobile page transitions to show a flickering footer (particularly the "slide" transitions), so I added this small amount of Javascript:
$(document).live( 'pagebeforechange', function() {
// hide footer
$('[data-role=footer]').hide();
});
$(document).live( 'pagechange', function() {
// show footer
$('[data-role=footer]').show();
});
Basically you just need to check the height of each data-role="content" elements to make sure that with the header/footer/content-area that the vertical space in the view-port is used.
For example:
$(document).on("pageshow", ".ui-page", function () {
var $page = $(this),
vSpace = $page.children('.ui-header').outerHeight() + $page.children('.ui-footer').outerHeight() + $page.children('.ui-content').height();
if (vSpace < $(window).height()) {
var vDiff = $(window).height() - $page.children('.ui-header').outerHeight() - $page.children('.ui-footer').outerHeight() - 30;//minus thirty for margin
$page.children('.ui-content').height(vDiff);
}
});
This code will run each time a page is navigated-to.
Here is a demo: http://jsfiddle.net/aBVtJ/1/
Check out this SO:
jQuery Mobile has a native footer that supports a fixed, or 'sticky', position. An example and documentation can be found at http://view.jquerymobile.com/1.3.1/dist/demos/widgets/fixed-toolbars/
I've followed Ryan Fait's sticky footer example and for some reason my footer, while sticky, is clipping through the rest of the divs when you reduce the height of the browser. Anyone know why this is, I'm obviously missing something, I haven't ran into this problem before.
Link: http://lithbeauty.com/test/
You need to clear your floats. Just add clear:both to your .push class. Also, you should remove the top margin and padding on your wrapper because it's forcing the height beyond 100% and creating an unnecessary scroll.
#wrapper{
position:relative;
height:auto;
min-height:100%;
}
#footer{
position:absolute;
bottom:0;
left:0;
width:100%;
}
I've found that the CSS sticky-footer approach is deceptively simple, a nightmare really. #Yusef's solution above is much more straightforward. I made a variation on this that also implements this Javascript code:
function setFooter()
{
var footer = document.getElementById("footer");
var innerWidth = window.innerWidth;
var offsetWidth = document.body.offsetWidth;
var scroll = innerWidth - offsetWidth;
if(scroll != 0)
{
footer.style.position = "relative";
}
else
{
footer.style.bottom = 25 + "px";
}
}
As long as Yusef's CSS for the footer also contains clear: both;, when there is no scrollbar in the window the footer div will automatically align below the main-content div (and also set onload = "setFooter();" in the html body tag).If there is a scrollbar in the window, the difference calculated by the scroll variable will be the integer amount that overflows (see my question for more info: Why are scrollTop, pageYOffset, and height all not working?).Watch these videos for implementing wrapper, main-content, and footer divs: http://www.youtube.com/watch?v=JnhoQ-aLfvE&src_vid=UpZbLIfHSMw&annotation_id=annotation_777473&feature=iv
I am working on a WordPress theme using the WordPress Boilerplate as a base (HTML5 Boilerplate + another WordPress base theme). Can be seen here:
JaredSartin.com (Theme is in progress, don't mind some of the other mess :P)
It looks just fine in Chrome, but the top image gets messed up in all other browsers. I am layering 2 images to overlap so I can have a responsive design, removing the back image and leaving just the title when the browser gets to a certain width.
The images are absolutely positioned with a percentage margin-top and margin-left on the top one to properly position it. they are both set to scale with the page via
height:auto;
width:100%;
OR
width:85%;
in the top image's case. Now, I was working in Chrome to produce the current look, the left-margin is fine in all browsers I have tested (FF and IE7/IE8 on Windows) but the top is off. In FF's inspector, I see that the adjusted top-margin needs to be 7.5% (makes more sense than the one I set in chrome - 24.5%).
Any ideas to a cross browser fix? I don't want to have to use specific browser detection (like Chrome vs Other). I already have some reset styles in place.
EDIT
I have a fix/hack, but if you have a better one (not so hacky, but just plain Cross Browser CSS), let me know...
header img#titleimgfront{
width: 85%;
margin-top: 7.5%; /* For non-webkit browsers */
margin-left: 8.5%;
}
/* unfortunate hack since Webkit has an issue with Margin-top */
#media screen and (-webkit-min-device-pixel-ratio:0) {
header img#titleimgfront{
margin-top: 24.6%;
}
}
There's nothing wrong with what you're doing -- this is a bug in Webkit, that it calculates a percentage margin-top from the height of an absolutely-positioned element, where other browsers (and the spec) calculate it from the width. (see: https://lists.webkit.org/pipermail/webkit-unassigned/2011-February/293573.html)
It does seem counter-intuitive to base margin-top and margin-bottom values on the element's width, but that's the way it is.
But you've found an effective workaround, so you're sorted. Don't feel that your layout is causing this problem, because it isn't, it's just Webkit.
Place this code at the top of your style.css right below the theme information and it should solve the majority of cross browser issues:
/*------------------------------------------------*/
/*-----------------[RESET]------------------------*/
/*------------------------------------------------*/
/* http://meyerweb.com/eric/tools/css/reset/ */
/* v1.0 | 20080212 */
html,body,div,ul,ol,li,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,fieldset,input,hr {margin:0; padding:0;}
h1,h2,h3,h4,h5,h6,pre,code,address,caption,cite,code,em,strong,th {font-size:1em; font-weight:normal; font-style:normal;}
ul,ol {list-style:none;}
fieldset,img,hr {border:none;}
caption,th {text-align:left;}
table {border-collapse:collapse; border-spacing:0;}
td {vertical-align:top;}
Your using absolute positioning lose the margins and use top, right, bottom or left.
header img#titleimgfront{
top: 25%;
}
While this is not the answer to your question just advice.
Your overly complicating a simple header image. I don't get the point of overlapping and lining up 3 images.
Just use 1 transparent png and in your WordPress header.php
<header>
<img src="http://path_to_image.png" width="800" height="240" class="logo" />
</header>
css:
.logo {
margin: 20% auto;
}
If your going to use HTML 5 drop all the extra divs and stuff. You don't need body or the extra wrapper.
Just use <section <?php body_class(); ?>> instead.
add top_margin class to fix top margin problem
$('.top_margin').each(function () {
var $item = $(this),
marginTop = 0,
newMarginTop = 0,
pageWidth = $item.parent().innerWidth();
//hide to obtain percentage value instead of calculated px value
$item.hide();
marginTop = parseFloat($item.css('margin-top')) / 100;
newMarginTop = Math.round(self.pageWidth * marginTop) + 'px';
$item.css('margin-top', newMarginTop);
console.log('old: ' + marginTop + ', new: ' + newMarginTop);
$item.show();
});