While developing a site for many browsers, mobile and desktop, I've noticed that the following CSS works nicely to center a loading div.
img.loading1 {
position:absolute;
left:50%;
margin-left:-16px;
top:50%;
margin-top:-16px;
z-index:10
}
.loading2 {
color:#006BB2;
position:absolute;
left:50%;
margin-left:0px;
top:40%;
z-index:5
}
.loading3 {
position:absolute;
width:100%;
height:100%;
left:0;
top:0;
background-color:lightgrey;
opacity:0.85
}
<div id="container" style="position:relative">
...content ommitted...
<div id="loading" style="display:none">
<div class="loading3"></div>
<img class="loading1" src="images/loader-ajax.gif" width="32" height="32">
<span class="loading2" id="getting">Getting your request...</span>
</div>
...content ommitted...
The div's display gets set to 'block' and the 3 items center great.
However, on a mobile screen, while the horizontal is right on, the vertical position could be off-screen depending on the height of the 'containing' div.
Is it possible to find the center of the screen and position the image and span there with Javascript?
Edit 1: Must the height of the loading div be set to be the height of the screen for this to work?
Related info:
Every absolutely-positioned element is positioned relative to a container. The default container is the body tag.
If no dimensions are specified, an element with absolute position is shrink-wrapped to the size of its content. When calculating the size in JavaScript, the value returned is whatever the current size happens to be, based on the content it contains. The element will not have the same size as its parent unless the width or height is explicitly set to 100%.
Without using jQuery:
Get the x and y location of the container element (relative to the viewport), the width and height of the viewport, and the width and height of the element.
Set the top to half the viewport height, minus the container y position, minus half the element height.
Set the left to half the viewport width, minus the container x position, minus half the element width.
// Center an absolutely-positioned element in the viewport.
function centerElementInViewport(el, container) {
// Default parameters
if ((typeof container == 'undefined') || (container === null))
// By default, use the body tag as the relative container.
container = document.body;
// Get the container position relative to the viewport.
var pos = container.getBoundingClientRect();
// Center the element
var left = ((window.innerWidth >> 1) - pos.left) - (el.offsetWidth >> 1);
var top = ((window.innerHeight >> 1) - pos.top) - (el.offsetHeight >> 1);
el.style.left = left + 'px';
el.style.top = top + 'px';
}
Here's a jsfiddle demo. If there are problems running it in jsfiddle, try this standalone demo.
Tested it in IE7/8/9, Firefox, Chrome, Safari, and Safari Mobile (iOS). The only thing found to cause a problem so far is if the absolutely-positioned element has a margin (which this function does not support at present).
Haven't tested in a responsive design yet.
Note: Be careful not to call this function when the page first loads. If the browser was scrolled or zoomed and then reloaded, the page may not have been rescrolled or zoomed back to where it was yet, and the resulting position would be incorrect. Setting a timer of 100 msec before calling the function seemed to work (allowing the browser time to rescroll and rezoom the page).
Use position: fixed with fix width & height.
in my exeprience this is hard to do with html/css
the easiest way i have found is using Javascripts innerHeight property
code could look like:
if (window.innerHeight) {
var loadingHeight = document.getElementById('loading').offsetHeight;
document.getElementById('loading').style.top = (((window.innerHeight/2)-loadingHeight) + "px");
}
you can set the horizontal position using the same method but replacing the height, offsetHeight and window.innerHeight methods with the respective width options, they are all well documented on the web
Related
I'm trying to solve an issue with css "position:fixed" property on mobile browsers. I have a fixed div:
<div id="logo">
...other content here...
</div>
with css:
#logo{
position: fixed;
-webkit-backface-visibility: hidden;
bottom: 100px;
right: 0px;
width: 32px;
height: 32px;
}
So, usually the behaviour is exactly the desired one, with the div position always on the bottom right of the window, indipendently of the scroll position.
My issue is that on mobile browsers, when the users zoom the page, after a certain zoom level the div position is wrong (sometimes the div disappear out of the window).
I know that fixed position is not well supported on mobile browsers, but I wonder if there is some workaround. I tried with this js code onScroll event:
window.addEventListener('scroll', function(e){
drag.style['-webkit-transform'] = 'scale(' +window.innerWidth/document.documentElement.clientWidth + ')';\\I want to avoid zoom on this element
var r = logo.getBoundingClientRect();
var w = window.innerWidth;
var h = window.innerHeight;
if(r.right != w){
rOff = r.right - w;
logo.style.right = rOff;
}
if(r.top+132 != h){\
tOff = r.top + 132 - h;
logo.style.bottom = tOff;
}
});
Unfortunately, the code seems to return the wrong position.
Does anyone have any tip?
Ok, that's how I solved the issue...I hope that could help anyone to simulate fixed position on iOS devices.
I switched the position from fixed to absolute;
Attach to window a listener to get the new position when the page is scrolled or zoomed,
setting window.onscroll and window.onresize events with the following function:
function position() {
drag.style.left = window.innerWidth + window.pageXOffset - 32 + 'px';
drag.style.top = window.innerHeight + window.pageYOffset - 132 + 'px';
}
Do you want to catch if zoom is active?
There's no window.onZoom listener, but you can read this thread:
Catch browser's "zoom" event in JavaScript
and this answer: https://stackoverflow.com/a/995967/3616853
There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it.
I’ve found two ways of detecting the zoom level. One way to detect zoom level changes relies on the fact that percentage values are not zoomed. A percentage value is relative to the viewport width, and thus unaffected by page zoom. If you insert two elements, one with a position in percentages, and one with the same position in pixels, they’ll move apart when the page is zoomed. Find the ratio between the positions of both elements and you’ve got the zoom level. See test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other.
There's no way to tell if the page is zoomed if they load your page while zoomed.
Just a theory, but you may want to try setting the bottom/right positions in % rather than px.
I think what you're seeing when using pixel measurements is just the zoom effecting the pixels. Or to put it better, when you zoom-in the pixels appear larger and that throws off the position of the element, even pushing it out of the view-port on smaller screens.
Example using pixel positioning
Notice that even on a desktop as you zoom-in and out the element appears to move up and down?
Example using percent positioning
In this example the element appears to stay in the bottom right corner, because it is always positioned at 10% from the bottom of the view-port.
#logo{
position: fixed;
-webkit-backface-visibility: hidden;
bottom:10%;
right: 0;
width: 32px;
height: 32px;
}
Having two different z-index for the logo and the rest of the page could help. Allowing zooming only to the rest of the page and not to the z-index layer where logo is included. So, this might not affect the stretching on the logo.
We can
Implement a ZOOM listener
Attach it to browser
Make the zoom listener change the zoom level of the element (modify the elements position) using z-index as a factor.
I have a series of pictures that I would like to slideDown() from left to right (creating a waterfall effect). I create the waterfall effect using setInterval():
var i = 1;
var numberCount = 5;
var counter = window.setInterval(function(){
$("#instagram-pictures .instagram-picture:nth-child(" + i + ")").slideDown(1200);
if(i === numberCount){
window.clearInterval(counter);
}
else{
i = i + 1;
}
}, 400);
This works without a hitch except the slideDown part. For some reason, my pictures are not sliding down from the width of the entire top line, rather they are "expanding out" from the top left hand corner.
jsFiddle here
How do I fix this?
.slideDown() animates the height of an element, not it's position. You're allowing the width of each picture to be automatically determined based on the height. So as the height changes, it's determining new widths as well, and animating a diagonal stretch.
If you give the images a fixed width you'll get the downward animation you're after.
Source: http://api.jquery.com/slidedown/
Try ths:
Give each image a fixed width
.instagram-picture{
display: none;
width:100px;
height: 160px;
}
The width is determined based on the height and since the height is changing when the image slides down, the width changes with it. Therefore, setting a fixed width will fix your problem!
JSFiddle Demo
I would like to, once the document loads, center an image. Here's the catch. My document's width is greater than the browser's height, so I can't center it vertically in relation to the document. I can't center it vertically in relation to the browser height because if a user opens up the document in a browser that is not full screen, it will be positioned differently than being full screen.
Essentially, I need a way to center an image on the browser screen when full screen, even if the document is opened when not full screen.
Update This is what I tried
<script>
$(document).ready(function() {
var docheight = $(window).height();
var logopositionheight = docheight/2;
var docwidth = $(window).width();
var logopositionwidth = docwidth/2;
$('#welcome_logo').css({position: 'absolute'});
$('#welcome_logo').css({top:logopositionheight-150});
$('#welcome_logo').css({left:logopositionwidth-500});
});
</script>
I also changed the $(window) to $(document) but neither worked because of what I described above.
Give the image a top and left of 50% then subtract half of the image's height and width from the margin, for example if your landscape image was 200px by 100px you would write margin: -100px 0 0 -50px, this should center the image perfectly.
You may also need to change the position element depending on containers and preference to either fixed or absolute.
First option, using JS (from user3592733's answer in part):
Javascript
function initialize(imageWidth, imageHeight) {
el.style.top = ""+(( innerHeight / 2 ) - ( imageHeight / 2 ))+"px";
el.style.left = ""+(( innerWidth / 2 ) - ( imageWidth / 2 ))+"px";
}
initialize();
// will update when browser is resized
window.onresize = initialize;
Or second option, using CSS and display:table
Main Page
<style type="text/css">
.wrapperdiv {
position:absolute;
display:table;
width:100%;
height:100%;
}
.containerdiv {
display:table-cell;
text-align:center;
vertical-align:middle;
}
</style>
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="ifiedivdisplayinlineblock.css" />
<![endif]-->
</head>
<body>
<div class="wrapperdiv">
<div class="containerdiv">
content here
</div>
</div>
ifiedivdisplayinlineblock.css
.wrapperdiv {
display:inline-block;
}
It's kind of a pain in CSS but that's how I do it on my page :) pretty self explanatory I think
Like #Shakesy said, you need to get your browser's "canvas" dimensions with innerHeight and innerWidth. Once you get that you can position the image horizontally with:
(( innerWidth / 2 ) - ( imageWidth / 2 )). Also, the vertical position can be set with:(( innerHeight / 2 ) - ( imageHeight / 2 )).You can put this "after" the page has loaded.
Re-sizing the browser is handled by the operating system, so the contents inside the browser is not "controlled" by the operating system as such but rendered by the browser itself. So, in other words, when the browser is sensing that it is being re-sized by the user it can send a trigger to javascript informing it of such an event. For Mozilla you can try(1)https://developer.mozilla.org/en-US/docs/Web/API/Window.onresize
I am trying to set up a black border around a webpage. For the left and right side, just making "width: 5%;" in the CSS is fine. But then I want JS/jQuery to work out how many pixels that is, and make that the height of the top and bottom div.
Is this possible?
Thanks.
This should work for you
var val = $(".leftAndRight").width();
$(".topAndBottom").height(val);
Or with one line:
$(".topAndBottom").height($(".leftAndRight").width());
You can determine the value for the border width programmatically, assign it to all four borders, and also refresh it any time you resize:
var width,
drawBorder = function () {
var body = $('body'),
width = body.width() * 0.05;
body.css('border-width', width + 'px');
};
drawBorder();
$(window).resize(function () {
drawBorder();
});
Demo
If you set the left and right width in your stylesheet and then use JS to give the same border width to the top and bottom, unless you use a resize function your left and right borders will change every time you resize but your top and bottom borders will remain fixed.
You can use .width() to find width without the border and .outerWidth to find the width including the border. I think .outerWidth also gives you the width with the padding you may have to subtract that.
EDIT: What happens can be seen in this page when the height resolution is lower than the entire page (eg.: 1024x768): http://www.depositosalto.com.br/pagamentos.php
I trying to resize a div with the content of page with javascript to always the page fit in the whole screen when it is smaller.
I'm using the following javascript and it works in other navigators(Firefox, Opera). In Chrome it resizes the div too, but unlike the others, it don't pushs the footer div which is just below the content div.
Is there any way around it in chrome?
function defineContentHeight(height){
var screenHeight = window.innerHeight;
if (screenHeight > (height + 220)){
height = screenHeight - 220;
document.getElementById("content").style.height = height + "px";
}
else{
document.getElementById("content").style.height = height + "px";
}
}
The content inside the "conteudo" div is floating, so the height isn't calculated; you can do one of two things:
Add the "overflow:auto" style to the "conteudo" div, which is generally safe, or
Add a div with a style of "clear:both" to the very bottom of the "conteudo" div
For what it's worth, I'm not seeing your bug in Chrome 11, but my guess is that one of those might fix it.