Vertically and Horizontally Center an Image On Load - javascript

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

Related

Scale website correctly on big monitors

I have a website that i'm working on locally, and it will be displayed through a projector for a presentation. Is there a way for me to scale it to the full size of the projection or if it were to be displayed on bigger screens without having to use all the media queries! I tried adding:
<meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0" />
But i don't think it will do the trick! Any input from you is welcomed
Edit:
Just thought i'd add that the website is in a 1000*800 container on the original size, i just want it to grow a bit whenever a screen gets bigger
if using Bootstrap then wrapping all content in a container-fluid div will use the full screen width (and therefore projection width).
<div class="container-fluid">
...// content
</div>
I'd try getting the browser window resolution and setting the width and height accordingly if the resolution goes beyond a specific one.
<script>
function setContentSize(){
var ww = window.innderWidth;
var wh = window.innderHeight;
ID.style.width = 1000 +"px";
ID.style.width = 800 +"px"; //ID must be set in HTML
if(ww > what you want ){
ID.style.width = what you want +"px";
}
}
</script>
etc. You probably can work it out
And you can load it up with window.addEventListener("resize", setContentSize);
To auto-zoom the whole page, one solution is using transform: scale(). The page needs to sit inside a container for this to work. First set the origin in css for the container:
div#page-container {
transform-origin: 0 0;
}
Then change the scale factor with javascript (in my case jQuery):
$(function() {
var ratio = $('div#page-container').width() / $(document).width();
$('div#page-container').css('transform', 'scale(' + (1.0 / ratio) + ')');
});
Here is a Fiddle.

Setting the Viewport to Scale to Fit Both Width and Height

I'm working on a website that fits within a specific width and height (an 885x610 div with a 1px border and 3px top margin). I would like the user to never have to scroll or zoom in order to see the entire div; it should always be fully visible. Since devices have a wide variety of resolutions and aspect ratios, the idea that came to mind was to set the "viewport" meta tag dynamically with JavaScript. This way, the div will always be the same dimensions, different devices will have to be zoomed differently in order to fit the entire div in their viewport. I tried out my idea and got some strange results.
The following code works on the first page load (tested in Chrome 32.0.1700.99 on Android 4.4.0), but as I refresh, the zoom level changes around. Also, if I comment out the alert, it doesn't work even on the first page load.
Fiddle
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
<script type="text/javascript">
function getViewportWidth() {
if (window.innerWidth) {
return window.innerWidth;
}
else if (document.body && document.body.offsetWidth) {
return document.body.offsetWidth;
}
else {
return 0;
}
}
function getViewportHeight() {
if (window.innerHeight) {
return window.innerHeight;
}
else if (document.body && document.body.offsetHeight) {
return document.body.offsetHeight;
}
else {
return 0;
}
}
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) {
var actual_width = getViewportWidth();
var actual_height = getViewportHeight();
var min_width = 887;
var min_height = 615;
var ratio = Math.min(actual_width / min_width, actual_height / min_height);
if (ratio < 1) {
document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scale=' + ratio + ', maximum-scale=' + ratio + ', minimum-scale=' + ratio + ', user-scalable=yes, width=' + actual_width);
}
}
alert(document.querySelector('meta[name="viewport"]').getAttribute('content'));
</script>
<title>Test</title>
<style>
body {
margin: 0;
}
div {
margin: 3px auto 0;
width: 885px;
height: 610px;
border: 1px solid #f00;
background-color: #fdd;
}
</style>
</head>
<body>
<div>
This div is 885x610 (ratio is in between 4:3 and 16:10) with a 1px border and 3px top margin, making a total of 887x615.
</div>
</body>
</html>
What can I do to have this website scale to fit both the width and the height?
It's possible to get a consistent behavior. But it's unfortunately very complex. I am working on a script that detects spoofed agents and dynamically rescale the viewport to desktop or other spoofed agents accordingly. I was also facing the zooming issue with Android/Chrome as well as the iOS emulator...
To get around it, you need to disable zooming and/or set the viewport twice. On the first pass, preferably inline in the <head> as you do now, you set your scale and disable user-scaling temporarily to prevent the zoom issue, using the same fixed value for all 3 scales like:
document.querySelector('meta[name=viewport]').setAttribute('content', 'width='+width+',minimum-scale='+scale+',maximum-scale='+scale+',initial-scale='+scale);
Then to restore zooming you set the viewport again on DOMContentLoaded, with the same scale, except that this time you set normal min/max scale values to restore user-scaling:
document.querySelector('meta[name=viewport]').setAttribute('content', 'width='+width+',minimum-scale=0,maximum-scale=10');
In your context, because the layout is fixed and larger than the viewport, initial-scale='+scale is perhaps needed for a more sound alternative for DOMContentLoaded:
document.querySelector('meta[name=viewport]').setAttribute('content', 'width='+width+',minimum-scale=0,maximum-scale=10,initial-scale='+scale);
That should get the viewport to rescale as you would like in Webkit browsers without zooming problems. I say only in webkit because sadly IE and Firefox do not support changing the viewport as per this Browser Compatibility Table for Viewports, Dimensions and Device Pixel Ratios shows: http://www.quirksmode.org/mobile/tableViewport.html
IE has its own way to change the viewport dynamically which is actually needed for IE snap modes to be responsive.
http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
So for IEMobile and IE SnapMode (IE10&11) you need to dynamically insert an inline <style> in the <head> with something like.
<script>
var s = document.createElement('style');
s.appendChild(document.createTextNode('#-ms-viewport{width:'+width+'px')+';}'));
document.head.appendChild(s);
</script>
And unfortunately, Firefox has neither: The viewport is set for once and for all as the above compatibility table shows. At the moment, for lack of other methods, using CSS Transform (as #imcg pointed out) is the only way to alter the viewport in FireFox Mobile on Android or Gecko OS. I have just tested it and it works in the context of a fixed size design. (In "Responsive Design context", the layout can be rescaled larger via CSS Transform, say at desktop size on a phone, but Firefox still read the phone size MQs. So that's something to be mindful off in RWD context. /aside from webkit)
Though, I have noticed some random Webkit crashes with CSSTransform on Android so I would recommend the viewport method for Safari/Chrome/Opera as more reliable one.
In addition, in order to get cross-browser reliability for the viewport width, you also have to face/fix the overall inconsistency between browsers for innerWidth (note that documentElement.clientWidth is much more reliable to get the accurate layout pixel width over innerWidth) and you also have to deal with devicePixelRatio discrepancies as indicated on the quirksmode.org table.
Update: Actually after some more thought into a solution for my own problem with Firefox, I just found out a way to override the viewport in Firefox Mobile, using document.write(), applied just once:
document.write('<meta name="viewport" content="width='+width+'px,initial-scale='+scale+'">');
Just tested this successfully in both Webkit and Firefox with no zooming issues. I can't test on Window Phones, so I am not sure itf document.write works for IEMobile...
I know this is two years late, but I spent a lot of time working on this problem, and would like to share my solution. I found the original question to be very helpful, so I feel that posting this answer is my way of giving back. My solution works on an iPhone6 and a 7" Galaxy Tab. I don't know how it fares on other devices, but I'm guessing it should mostly behave.
I separated the viewport logic into an external file so that it is easy to
reuse. First, here's how you would use the code:
<HTML>
<HEAD>
<SCRIPT type="text/javascript" src="AutoViewport.js"></SCRIPT>
</HEAD>
<BODY>
<SCRIPT>
AutoViewport.setDimensions(yourNeededWidth, yourNeededHeight);
</SCRIPT>
<!-- The rest of your HTML goes here -->
</BODY>
</HTML>
In actuality, I padded my desired width and height by a slight amount (15 pixels or so) so that my intended display was framed nicely. Also please note from the usage code that you do not have to specify a viewport tag in your HTML. My library will automatically create one for you if one does not already exist.
Here is AutoViewport.js:
/** Steven Yang, July 2016
Based on http://stackoverflow.com/questions/21419404/setting-the-viewport-to-scale-to-fit-both-width-and-height , this Javascript code allows you to
cause the viewport to auto-adjust based on a desired pixel width and height
that must be visible on the screen.
This code has been tested on an iPhone6 and a 7" Samsung Galaxy Tab.
In my case, I have a game with the exact dimensions of 990 x 660. This
script allows me to make the game render within the screen, regardless
of whether you are in landscape or portrait mode, and it works even
when you hit refresh or rotate your device.
Please use this code freely. Credit is appreciated, but not required!
*/
function AutoViewport() {}
AutoViewport.setDimensions = function(requiredWidth, requiredHeight) {
/* Conditionally adds a default viewport tag if it does not already exist. */
var insertViewport = function () {
// do not create if viewport tag already exists
if (document.querySelector('meta[name="viewport"]'))
return;
var viewPortTag=document.createElement('meta');
viewPortTag.id="viewport";
viewPortTag.name = "viewport";
viewPortTag.content = "width=max-device-width, height=max-device-height,initial-scale=1.0";
document.getElementsByTagName('head')[0].appendChild(viewPortTag);
};
var isPortraitOrientation = function() {
switch(window.orientation) {
case -90:
case 90:
return false;
}
return true;
};
var getDisplayWidth = function() {
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
if (isPortraitOrientation())
return screen.width;
else
return screen.height;
}
return screen.width;
}
var getDisplayHeight = function() {
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
if (isPortraitOrientation())
return screen.height;
else
return screen.width;
}
// I subtract 180 here to compensate for the address bar. This is imperfect, but seems to work for my Android tablet using Chrome.
return screen.height - 180;
}
var adjustViewport = function(requiredWidth, requiredHeight) {
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)){
var actual_height = getDisplayHeight();
var actual_width = getDisplayWidth();
var min_width = requiredWidth;
var min_height = requiredHeight;
var ratio = Math.min(actual_width / min_width, actual_height / min_height);
document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scale=' + ratio + ', maximum-scale=' + ratio + ', minimum-scale=' + ratio + ', user-scalable=yes, width=' + actual_width);
}
};
insertViewport();
adjustViewport(requiredWidth, requiredHeight);
window.addEventListener('orientationchange', function() {
adjustViewport(requiredWidth, requiredHeight);
});
};
If you compare my code closely with the original code found in the question, you will notice a few differences. For example, I never rely on the viewport width or height. Instead, I rely on the screen object. This is important because as you refresh your page or rotate your screen, the viewport width and height can change, but screen.width and screen.height never change. The next thing you will notice is that I don't do the check for (ratio<1). When refreshing or rotating the screen, that check was causing inconsistency, so I removed it. Also, I included a handler for screen rotation.
Finally, I'd just like to say thank you to the person who created this question for laying the groundwork, which saved me time!
If you can't get consistent behavior across devices by changing the viewport meta tag, it's possible to zoom without changing the dimensions using CSS3 transforms:
if (ratio < 1) {
var box = document.getElementsByTagName('div')[0];
box.style.webkitTransform = 'scale('+ratio+')';
box.style.webkitTransformOrigin = '0 0';
}
console.log(box.offsetWidth); // always original width
console.log(box.getBoundingClientRect().width); // new width with scaling applied
Note I've omitted any vendor prefixes other than webkit here in order to keep it simple.
To center the scaled div you could use the translate tranforms:
var x = (actual_width - min_width * ratio) / 2;
var y = (actual_height - min_height * ratio) / 2;
box.style.webkitTransform = 'translateX('+x+'px) translateY('+y+'px) scale('+ratio+')';
box.style.webkitTransformOrigin = '0 0';
Replace your viewport with this :
<META NAME="viewport" CONTENT="width=device-width, height=device-height, initial-scale=1, user-scalable=no"/>
The user-scalable=0 here shall do the job for you.
This shall work for you.If it still doesn't work for we will have to extend the viewport so replace your viewport and add this:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, target-densitydpi=medium-dpi, user-scalable=0" />
For your javascript error have a look at this link:
scale fit mobile web content using viewport meta tag
Set the height and width of the div's parent elements (html and body) to 100% and zero out the margin.
html, body {
margin: 0;
height: 100%;
width: 100%;
}
Next, because you want a border on the div you need to make sure that the border width is included when you specify the width / height of the element, to do this use box-sizing: border-box on the div.
Because you want a 3px top margin on the div relative positioning of the div will result in a height that is 3px too tall. To fix this use absolute positioning on the div and set top, left, and bottom to 0.
div {
position: absolute;
top: 3px;
left: 0;
bottom: 0;
box-sizing: border-box;
width: 100%;
border: 1px solid #f00;
background-color: #fdd;
}
Here's a working example.
UPDATE: I think I misunderstood the question. Here's a sample code that adjusts the "zoom" depending on the device's viewport
http://jpanagsagan.com/viewport/index2.html
Take note that I used jquery to append the meta tag as I am having issue using the vanilla append.
One thing I noticed is that if you hard-coded in the HTML and change it via JS, the document won't apply the correction (needs verification). I was able to change it via JS if there is no previous tag in the HTML, thus I used append.
You may play around with the ratio, but in the example I used width of the viewport divided by width of the div.
hope this helps.
UPDATE: I think I misunderstood the question. Here's a sample code that adjusts the "zoom" depending on the device's viewport
http://jpanagsagan.com/viewport/index2.html
Take note that I used jquery to append the meta tag as I am having issue using the vanilla append.
One thing I noticed is that if you hard-coded in the HTML and change it via JS, the document won't apply the correction (needs verification). I was able to change it via JS if there is no previous tag in the HTML, thus I used append.
You may play around with the ratio, but in the example I used width of the viewport divided by width of the div.
hope this helps.
I think Steven's should be the accepted answer.
In case it is helpful someone else, I would add the following 2 things to Steven's AutoViewport.js, in order to center the view within the viewport when the user is in landscape view:
Add "var viewport_margin = 0;" as the first line of code (as it's own line before "function AutoViewport() {}".
Add "viewport_margin = Math.abs(actual_width-(ratio*requiredWidth))/(actual_width*2)*100;" after the line that reads "document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scale=' + ratio + ', maximum-scale=' + ratio + ', minimum-scale=' + ratio + ', user-scalable=yes, width=' + actual_width);"
Thanks for all those who posted to bring this solution to light.
UPDATE: In Android, my additions only appear to work with API 24+. Not sure why they aren't working with APIs 19-23. Any ideas?

How can one find the "maximized" height of a browser window?

I am trying to make a picture take up 70% of the user's screen. However, if the screen is made smaller when the page is loaded or if the person has inspect element open, the picture becomes small and stretched. I believe the best solution would be to find the maximum height of the browser window and make the image that size. However, I am not sure how to do that?
Here is my current code for image sizing:
var topoffset = window.innerHeight * 0.77;
var profilestart = topoffset - $(".prof-header").height();
$('.splashPic').css("height", topoffset);
$('.splashPlaceholder').css("top", profilestart);
I also want to make it so that if someone is using a huge monitor (i.e. large Mac), the image size maxes out at that point? Any suggestions would be very helpful!
Edit: I don't want to make the image resize dynamically. Only load once.
Use window.screen.availHeight instead of window.innerHeight
or screen.height
var x = screen.height*0.7;
EDIT: Here's more code to show that it works for what you asked. Gets the height upon load and doesn't resize.
<img id="img2" src="http://lorempixel.com/320/240/food" />
<script>
$(document).ready(function () {
var x = screen.height*0.7;
$('#img2').css("height",x);
}
</script>
It sounds like what you want to do is something like this:
img{
display:block;
width:70%;
min-width:320px;
max-width:1200px;
}
If you want the image to take up 70% of the viewport height (and obviously retain its ratio) you could use the new css unit vh (viewport height) like this:
img
{
height: 70vh;
}
FIDDLE

Dynamically resize div based on window size

I'm trying to optimise my website for different resolutions. In the center of the website I have a DIV that currently has a fixed size. I'm trying to make its size (and contents) change according to the size of the browser window. How do I do that?
This is my website if you want to take a look at its code:
http://www.briefeditions.com
If you resize the page the div will resize with it and on load of the page.
$(window).on('load resize', function(){
$('#div').width($(this).width());
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
$(document).ready(function(){
var windowHeight = $(window).height();
$('#divID').css('min-height',windowHeight+'px');
});
UPDATE
If you want that site will resize based on browser resize then use % instead of px
CSS:
html {height:100%; overflow:hidden}
body {height: 100%;}
I guess you need screen width and height for client(users) machine.
at onload of page get screen width & height and set those values to divs using jquery/javascript
var userscreen_width,userscreen_height;
userscreen_width = screen.width;
userscreen_height = screen.height;
check this for more info
Keep in mind that in your example iframe also has fixed size. You should also resize it to the parents width. In your example this would work:
$(window).on('load resize', function(){
$('#content, #content > iframe').width($(this).width());
});
Keep in mind that you must remove all margins, as well as absolute positioning like: top, left, position:absolute from you element styles.
I checked the code from the provided link in question.
Change width to 80% in #content style.
And in .wrapper change width to 100%.
You have used mainly 920px for width, so whenever you will resize window the control will not re-size. Use equivalent % instead of 920px;
You can do like this
var width = $(window).width();
$("#divId").width(width);

How to center 'Getting Data' on mobile screen

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

Categories