Get webpage center coordinates on tablet devices using JavaScript - android

I'm trying to compute the viewport geometric center on a webpage, rendered with Tablet devices (iOS and Android), ie the actual CENTER of the viewport (what you see) according to current translation and current zoom level - don't want the center of the document itself, I want the center of the screen what I'm viewing.
The problem is that this calculation is does not take into account any kind of zoom (an then) translation.
On iOS, I've tried with some of these answers, on the question detecting pinch to zoom on iOS,
I was able to catch the event "OnZoom" but didn't get any value, though.
On Android, I can't even catch any event related to zoom. I'm aware of touchmove and touchstart events, but how can I distinguish then in order to get zoom (and zoom value)
I'm using jQuery 1.7.2 library.

I have made a demo page which is confirmed to work on iPhone iPad, Samsung Galaxy Tab 10. I have only attached the click event on a huge div, so tap on the screen after zooming to update the display.
The calculation is very simple, use screen.width/window.innerWidth to get the zoom level. screen.width will always be in device pixels and window.innerWidth is always in css pixels, which also take the zoom into account.
Further calculation is simple math:
// round the result down to avoid "half pixels" for odd zoom levels
Math.floor(window.scrollY + window.innerHeight/2);
Math.floor(window.scrollX + window.innerWidth/2);
To check whether the user is zooming, attach the listener to window.resize and window.scroll which will fire after orientationchange hiding the address bar and zooming.
Here's my demo JavaScript:
var dot = document.getElementById("dot");
document.getElementById("main").addEventListener("click", function(e) {
var zoom = screen.width / window.innerWidth;
alert("zoom: " + zoom + "\n" + "ScrollY: " + window.scrollY);
dot.style.top = Math.floor(window.scrollY + window.innerHeight/2 - 5) + "px";
dot.style.left = Math.floor(window.scrollX + window.innerWidth/2 - 5) + "px";
}, false);

Setting up a simple HTML page, I can get pretty close to center.
With the code below, I'm just checking the width and height of a fixed div, and then combining that with the document offset and some simple maths to figure out the center, and place a single black dot there. I can get it pretty close, but it varies on my iPhone 4S.
Haven't tried on Android devices.
I don't think this would work on iOS <= 4, as they don't support fixed-positioning.
<style>
#fixed{
position: fixed;
left: 0; right: 0; top: 0; bottom: 0;
background: orange; opacity: 0.25;
}
.black{
position: absolute;
top:0;left:0;
width: 1px; height: 1px;
background: black;
}
</style>
<body>
<div id="fixed"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script>
jQuery(function($){
setInterval(function(){
var top = ($("#fixed").height()/2) + $("#fixed").offset().top;
var left = ($("#fixed").width()/2) + $("#fixed").offset().left;
$("body").append('<div class="black" style="top: '+top+'px; left: '+left+'px;" />');
}, 1500)
});
</script>
</body>

I had a client request a page zoom detection method in javascript a couple years ago.
In my case, he wanted it to work on a facebook app. Through the iframe canvas/viewport.
I used Max and Min functions
function getDocHeight() {
var D = document;
return Math.max(
Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
Math.max(D.body.clientHeight, D.documentElement.clientHeight)
);
}
function getDocWidth() {
var D = document;
return Math.max(
Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),
Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),
Math.max(D.body.clientWidth, D.documentElement.clientWidth)
);
}
function getMinHeight(h) {
return Math.min(viewport.currentHeight, getDocHeight(), h);
}
getMinWidth was similar, but I had to apply browser-based tweaks to it.
I created an object called viewport which stored the properties of a fixed position div, specifically currentHeight and currentWidth were the offsetHeight and offsetWidth of the div element.
I ended up initializing a window.intervalTimer to run checks on the state of that div, comparedTo the stored values within the viewport object.

Related

How to detect Android device's default font size with CSS media queries?

In Android, Settings > Accessibility > Font Size the user can set font size between "Small", "Default", "Large", "Largest". Among other things, this setting affects default font size of HTML content in WebViews.
I've developed my layouts to look well with the default font size. Setting font size to "Largest" causes text to get cut off in some places, a horizontal scrollbar appear on others etc. In these cases I can use an alternative layout (for example, stack things vertically instead of horizontally), but I'm not sure how to detect which layout to use.
Ideally, I would use CSS media queries. Something like:
#foo {
display: flex;
}
#media (min-width: 360px) {
#foo {
/* If at least 360px available, use a horizontal layout */
flex-direction: row;
}
}
Problem is, the 360px breakpoint isn't affected by the Font Size setting on the device (which makes sense). I've also tried other measurement units: rem, ch, cm – but none of them seemed to take into account device's font size.
I've thought about doing something like this on page load:
display a line of constant text (say, "0000000000") on the screen
measure it in JS
if the measured width / device width ratio is above some set constant, switch to the alternative layout
But this approach would add complexity, delay and repaints and flicker on page load.
Is there a way to take device font size in account in CSS (media queries or otherwise)?
Short Answer
No, you cannot do this just using CSS. However you can minimise impact using a method similar to the one you mentioned in your question (measuring font size and adjusting layout accordingly).
Long Answer
You cannot do this with just CSS, however it is possible to have a performant website without repaints and fall-back to your default styles for no JS.
There is one downside to this method, you do end up injecting a style sheet into the page which will affect first contentful paint times. However bear in mind that this is essentially the same as having a matching media query (so in reality, there is no difference between this and a media query other than it relies on JavaScript).
You can mitigate this by inlining the relevant styles but obviously that carries a page weight cost. You will have to decide which is the greater sin!
The solution is quite simple.
(1) Work out the user's font size using the method similar to the one you described.
(2) Load in conditional CSS that overrides the key layout options as you desire.
(2a) Alternatively add a class to the body and change the layout based on that from styles within existing style sheets or inlined in the document if above the fold.
1. Work out the user's font size
You can do this in vanilla JS right within the header of the page as an inline script so it does not delay anything (other than parsing the script) and it will still be performant.
Try the below example with you font size set to "medium" first, then set your font-size to "extra large" and run the script again. Your font size should show as 16px and 24px respectively.
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
console.log(style)
<div id="foo">a</div>
We now have a font size that is relative to the user's scaling.
We can further improve this by simply dividing the resultant font size by 16 (default size) to get a %age scale.
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
console.log(style, fontSizePercentage + "%");
<div id="foo">a</div>
2. Load in conditional CSS
Now that we know if the font size has been scaled by the user we simply conditionally load CSS.
To do this we need a simple JavaScript check
//set to whatever criteria you need, if your site still works on "large" font size and only needs adjustment at "extra large" then use 124 etc.
if(fontSizePercentage > 100){
//add the CSS
}
In the below example I have 3 columns that turn into 3 rows to demonstrate how font size dictates which styles to apply.
Please note to simulate a dynamically added CSS file I added some inline CSS code that gets written to a style sheet, you would obviously just add a style sheet (I have included a function to do this and just commented out where that function is called).
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
el.remove();
console.log(fontSizePercentage);
//this is just to simulate adding CSS, you would obviously import a style sheet properly here. I have put the proper function further down.
var normal = `
.col3{
float: left;
width: 32%;
margin-right: 1%;
}
`
var bigger = `
.col3{
float: left;
width: 100%;
}
`
var styleSheet = document.createElement("style");
styleSheet.type = "text/css";
if(fontSizePercentage > 100){
styleSheet.innerText = bigger;
}else{
styleSheet.innerText = normal;
}
document.head.appendChild(styleSheet);
////actual style sheet code/////
function addCss(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
if(fontSizePercentage > 100){
//addCss('url-to-large-font-size-layout');
}else{
//addCss('url-to-normal-font-size-layout');
}
<div id="foo">a</div>
<div class="col3">column</div>
<div class="col3">column</div>
<div class="col3">column</div>
You will see from the example we add the stylesheet dynamically, choosing between two style sheets in the example. In reality you would probably only need to do the check for the requirement to use the large fonts stylesheet as your standard font size will be covered by your main CSS.
pros
This method effectively is the same as a 'font size media query' and carries a tiny JavaScript overhead.
cons
If you are bothered by repaints then performance is obviously important to you, this method adds an additional request and can delay First Contentful Paint / Initial page rendering for "above the fold content".
Because of this I offer a second suggestion:
2a. Add a class to the body.
Use exactly the same method as above but instead of inserting a style sheet simply use the check for font size to add a class to the body on page load.
The simply include the styles within your current style sheets but with the additional body class as a qualifier.
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
el.remove();
var bod = document.getElementById('simulated-body');
if(fontSizePercentage > 100){
bod.classList.add('large-font-layout');
}
console.log(fontSizePercentage);
.col3{
float: left;
width: 32%;
margin-right: 1%;
}
.large-font-layout .col3{
float: left;
width: 100%;
}
<div id="simulated-body">
<div id="foo">a</div>
<div class="col3">column</div>
<div class="col3">column</div>
<div class="col3">column</div>
</div>
pros this doesn't add any extra requests, should not affect your page paint. Generally this option will be preferable to the first option as you should only need to override a handful of CSS classes so the added weight is negligible.
cons - adds extra weight to your CSS.
Conclusion
Somebody should add a "user font size" media query :-P
Seriously though I would go with the (2a) option I gave you and inline your critical CSS. If you are changing more than 100 classes in your CSS (and so CSS weight becomes a problem) then something is wrong with your design so the speed difference will be negligible. Couple that with the fact that the JS is less than 1kb and it will not affect your paints and it is a simple but effective solution to your problem.
Bonus info for option 2
As an additional thought you can combine option 2 with checking the screen width to really minimise the amount of data sent down the wire. However this then starts adding considerable complexity which is something you said you wanted to avoid. I have included it here for completeness.
function getFontSizePercentage(){
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
el.remove();
return fontSizePercentage;
}
function getPageWidth(){
return Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
}
function addCSS(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
var fontSizePercentage = getFontSizePercentage();
var pageWidth = getPageWidth();
var cssSize = "1920";
switch(true) {
case (pageWidth < 1366):
cssSize = "1366";
break;
case (pageWidth < 728):
var cssSize = "728";
break;
default:
cssSize = "1920";
}
var cssPath = "styles/screen-width-" + cssSize + "-font-size-adjust";
if(fontSizePercentage > 100){
console.log("adding CSS for width: " + cssSize, cssPath);
addCSS(cssPath);
}else{
console.log("not adding CSS", cssPath);
}
<div id="foo">a</div>
you can use the VH (viewport height) or VW(viewport width) font-size measures and the font will resize based on % of device viewport for example:
1vh = 1% of viewport heigth
2vw = 2% of viewport width etc
If you are doing media selector you could as well use rem or px as font-size.
You will still have to add #media selector for different devices, keep in mind viewport is the actual size of a device screen, like 10inch screens will have a #media selector up to 1280px or bellow.
/* please use caniuse.com for browser compatibility table*/
h1 {
font-size: 2.5vw;
}
h2 {
font-size: 2vw;
}
p {
font-size: 12px;
}
#media only screen and (max-width:768px) {
h1 {
font-size: 5vw;
}
h2 {
font-size: 4vw;
}
p {
font-size: 18px;
}
}
<h1>text</h1>
<h2>text</h2>
<p>some normal font controled by media query</p>
Is there a way to take device font size in account in CSS (media queries or otherwise)?
Media queries are used to set font size based on device width, not the contrary.
The unit you might use will always be based on the device width, not on the font size (as this can't be already defined at this point).
What you can do is, instead of defining the width of your columns based on percentage or using px units, you can set them on the base font size.
For instance, instead of
.flex-col {
flex: 0 1 30%;
}
you may use
.flex-col {
flex: 0 1 20rem;
}
The real problem are not your media queries but the fact that your containers are not defined in a responsive way (with both fix width and height for instance) causing cut off and scrollbars.

How to get rid of white space or improper loading in jquery mobile in android?

I am getting a white space between which is caused in jquery mobile in between at end of content and start of footer. I have this issue in android 4.0.3 and how can get rid of this issue.Kindly help me in solving this issue.I have added screenshot to show how I get it in emulator.Thank you.
Please next time try goggling this problem, it is most commonly asked problem here.
As you can see data-role="content" will not cover available free space. So you will need to do this using CSS or javascript.
CSS solution:
.ui-content {
padding: 0;
position: absolute !important;
top : 40px !important;
right : 0;
bottom : 40px !important;
left : 0 !important;
}
JavaScript solution:
function getRealContentHeight() {
var header = $.mobile.activePage.find("div[data-role='header']:visible");
var footer = $.mobile.activePage.find("div[data-role='footer']:visible");
var content = $.mobile.activePage.find("div[data-role='content']:visible:visible");
var viewport_height = $(window).height();
var content_height = viewport_height - header.outerHeight() - footer.outerHeight();
if((content.outerHeight() - header.outerHeight() - footer.outerHeight()) <= viewport_height) {
content_height -= (content.outerHeight() - content.height());
}
return content_height;
}
Read more about it here, with working examples.

Android WebView getContentHeight() doesnt return the correct value

I have a requirement where I display a WebView with a checkbox beneath it. The checkbox is initially in disabled state. Only when the user scrolls down to the bottom of the webview , the checkbox is enabled. I do this by extending Webview class and writing my onScrollChanged listener as below:
#Override
protected void onScrollChanged(int left, int top, int oldLeft, int oldTop) {
if ( (getContentHeight() - (top + getHeight())) <= mMinDistance )
{
Log.i("MYACT","content height: "+getContentHeight()+" top: "+top+" Height: "+getHeight()+" minDistance: "+mMinDistance);
Log.i("MYACT", "Reached bottom");
mOnBottomReachedListener.onBottomReached(this);
}
else{
Log.i("MYACT","content height: "+getContentHeight()+" top: "+top+" Height: "+getHeight()+" minDistance: "+mMinDistance);
Log.i("MYACT", "Not at bottom");
mOnBottomReachedListener.onNotAtBottom(this);
}
super.onScrollChanged(left, top, oldLeft, oldTop);
}
The problem is the condition
(getContentHeight() - (top + getHeight())) <= mMinDistance) //mMinDistance is 0 in my case
is satisfied even before i scroll down to the bottom of the page. As you can see, I tried printing the values of each in log and found that the parameter "top" sometimes exceeds the value "getContentHeight".
Sample log values:
08-14 11:28:19.401: I/MYACT(1075): content height: 3020 top: 3861
Height: 416 minDistance: 0
How can i make avoid this scenario in this case? Should i use a different way of checking whether i have scrolled down to the bottom of the page?
Thanks
I found the issue with this after some research. Webview usually scales the web page based on the screen size and then renders it. It usually zooms the page so that it doesn't look too small in the phone. You can get this scale factor by using the method getScale()
So, in my case, i would use the following condition to check whether end of page has been reached
(getContentHeight()*getScale() - (top + getHeight())) <= mMinDistance)
//mMinDistance is 0 in my case
If memory serves values returned by getContentHeight() may depend on implementation of a WebView and its rendering mode (software/hardware). But I'm not sure. Perhaps this talk at Google IO will help you more in this question.
But generally speaking it's always hard and tricky to mix WebView with other views, especially when it comes to scrolling.
So my advice would be to put your checkbox into HTML displayed by the WebView. You have pretty much options of doing that like injecting some additional HTML code before passing it to loadData() method or invoking JavaScript with loadUrl("javascript:whatever();"), which can modify the initial DOM structure.
As a rule I do not put other views to Activity window when I have to deal with a WebView there.

set window.innerWidth and window.innerHeight in mobile browsers

i can get the window.innerWidth or window.innerHeight on mobile platforms
such as android of iphone.
var w = window.innerWidth;
but i want to set it back to its old value, i mean when the user zooms by pinch, the innerWidth and innerHeight values are changed. i can get the new values, but i want that
the screen size is back to its old position, but i could never change the size by
window.innerWidth = foo;
window.innerWidth = 'foopx';
window.resizeTo(foo,bar);
None of them worked in android or in iphone, ipad (safari, mobile chrome) above.
How can i remove the effect of pinch zoom? I do not want to block it or disable, user may zoom but after the zoom action i want to de-zoom to back its original position.
how can resize(change) window.innerWidth, innerHeight values?
I present to you, an ugly kludge, but so far the only way i know how to do what you want.
Let's say that in your html you've got
<meta id="myViewPort" name="viewport" content="whatever" />
Then in a script somewhere you've got this
function resetScale()
{
var viewport = document.getElementById('myViewPort')
var content = viewPort.content;
viewport.content = 'what=ever, user-scalable=no';
window.setTimeout(function()
{
viewport.content = content;
},1);
}
Yes, the timeout is required. Without it, the scale is not reset.
Also, the viewport takes a moment before it will notice that user-scalable is no longer urned off. I've had delays as long as 10 seconds before you can start zooming again, and other times where you can start zooming immediately.

Prevent portrait orientation of HTML5 game [duplicate]

Is it possible to detect on my page, for example using Javascript, when user visit it using mobile device in portrait mode, and stop orientation changing when user rotate its phone to landscape? There is game on my page, optimized for portrait display only and I don't want it in landscape.
New API's are developing (and are currently available)!
screen.orientation.lock(); // webkit only
and
screen.lockOrientation("orientation");
Where "orientation" can be any of the following:
portrait-primary -
It represents the orientation of the screen when it is in its primary portrait mode. A screen is considered in its primary portrait mode if the device is held in its normal position and that position is in portrait, or if the normal position of the device is in landscape and the device held turned by 90° clockwise. The normal position is device dependant.
portrait-secondary -
It represents the orientation of the screen when it is in its secondary portrait mode. A screen is considered in its secondary portrait mode if the device is held 180° from its normal position and that position is in portrait, or if the normal position of the device is in landscape and the device held is turned by 90° anticlockwise. The normal position is device dependant.
landscape-primary -
It represents the orientation of the screen when it is in its primary landscape mode. A screen is considered in its primary landscape mode if the device is held in its normal position and that position is in landscape, or if the normal position of the device is in portrait and the device held is turned by 90° clockwise. The normal position is device dependant.
landscape-secondary -
It represents the orientation of the screen when it is in its secondary landscape mode. A screen is considered in its secondary landscape mode if the device held is 180° from its normal position and that position is in landscape, or if the normal position of the device is in portrait and the device held is turned by 90° anticlockwise. The normal position is device dependant.
portrait -
It represents both portrait-primary and portrait-secondary.
landscape -
It represents both landscape-primary and landscape-secondary.
default -
It represents either portrait-primary and landscape-primary depends on natural orientation of devices. For example, if the panel resolution is 1280800, default will make it landscape, if the resolution is 8001280, default will make it to portrait.
Mozilla recommends adding a lockOrientationUniversal to screen to make it more cross-browser compatible.
screen.lockOrientationUniversal = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
Go here for more info (deprecated API): https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
Modern API docs in MDN is here: https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/lock
In JavaScript-enabled browsers it should be easy to determine if the screen is in landscape or portrait mode and compensate using CSS. It may be helpful to give users the option to disable this or at least warn them that device rotation will not work properly.
Edit
The easiest way to detect the orientation of the browser is to check the width of the browser versus the height of the browser. This also has the advantage that you'll know if the game is being played on a device that is naturally oriented in landscape mode (as some mobile devices like the PSP are). This makes more sense than trying to disable device rotation.
Edit 2
Daz has shown how you can detect device orientation, but detecting orientation is only half of the solution. If want to reverse the automatic orientation change, you'll need to rotate everything either 90° or 270°/-90°, e.g.
$(window).bind('orientationchange resize', function(event){
if (event.orientation) {
if (event.orientation == 'landscape') {
if (window.rotation == 90) {
rotate(this, -90);
} else {
rotate(this, 90);
}
}
}
});
function rotate(el, degs) {
iedegs = degs/90;
if (iedegs < 0) iedegs += 4;
transform = 'rotate('+degs+'deg)';
iefilter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+iedegs+')';
styles = {
transform: transform,
'-webkit-transform': transform,
'-moz-transform': transform,
'-o-transform': transform,
filter: iefilter,
'-ms-filter': iefilter
};
$(el).css(styles);
}
Note: if you want to rotate in IE by an arbitrary angle (for other purposes), you'll need to use matrix transform, e.g.
rads = degs * Math.PI / 180;
m11 = m22 = Math.cos(rads);
m21 = Math.sin(rads);
m12 = -m21;
iefilter = "progid:DXImageTransform.Microsoft.Matrix("
+ "M11 = " + m11 + ", "
+ "M12 = " + m12 + ", "
+ "M21 = " + m21 + ", "
+ "M22 = " + m22 + ", sizingMethod = 'auto expand')";
styles['filter'] = styles['-ms-filter'] = iefilter;
—or use CSS Sandpaper. Also, this applies the rotation style to the window object, which I've never actually tested and don't know if works or not. You may need to apply the style to a document element instead.
Anyway, I would still recommend simply displaying a message that asks the user to play the game in portrait mode.
seems weird that no one proposed the CSS media query solution:
#media screen and (orientation: portrait) {
...
}
and the option to use a specific style sheet:
<link rel="stylesheet" type="text/css" href="css/style_p.css" media="screen and (orientation: portrait)">
MDN:
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries#orientation
Simple Javascript code to make mobile browser display either in portrait or landscape..
(Even though you have to enter html code twice in the two DIVs (one for each mode), arguably this will load faster than using javascript to change the stylesheet...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Mobile Device</title>
<script type="text/javascript">
// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
if(window.orientation==0)
{
document.getElementById('portrait').style.display = '';
document.getElementById('landscape').style.display = 'none';
}
else if(window.orientation==90)
{
document.getElementById('portrait').style.display = 'none';
document.getElementById('landscape').style.display = '';
}
}, false);
</script>
<meta name="HandheldFriendly" content="true" />
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />
</head>
<body>
<div id="portrait" style="width:100%;height:100%;font-size:20px;">Portrait</div>
<div id="landscape" style="width:100%;height:100%;font-size:20px;">Landscape</div>
<script type="text/javascript">
if(window.orientation==0)
{
document.getElementById('portrait').style.display = '';
document.getElementById('landscape').style.display = 'none';
}
else if(window.orientation==90)
{
document.getElementById('portrait').style.display = 'none';
document.getElementById('landscape').style.display = '';
}
</script>
</body>
</html>
Tested and works on Android HTC Sense and Apple iPad.
With the new CSS3 features, you could rotate the page the opposite orientation that they rotated. Sorry, no IE7- support. :(.
var rotate = 0 - window.orientation;
setAttribute("transform:rotate("+rotate+"deg);-ms-transform:rotate("+rotate+"deg);-webkit-transform:rotate("+rotate+"deg)", "style");
This solution worked for me, which just rotates the entire page 90 degrees when it's in landscape (effectively locking the screen in portrait). I couldn't go with some of the other options here, because I needed to support Safari.
#media screen and (min-width: 320px) and (max-width: 767px) and (orientation: landscape) {
html {
transform: rotate(-90deg);
transform-origin: left top;
width: 100vh;
overflow-x: hidden;
position: absolute;
top: 100%;
left: 0;
}
}
Found it here: https://css-tricks.com/snippets/css/orientation-lock/
You could use the screenSize.width and screenSize.height properties and detect when the width > height and then handle that situation, either by letting the user know or by adjusting your screen accordingly.
But the best solution is what #Doozer1979 says... Why would you override what the user prefers?
You can detect the orientation change, but I don't think you can prevent it.
https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
http://articles.sitepoint.com/article/iphone-development-12-tips/2
#rotate-device {
width: 100%;
height: 100%;
position: fixed;
z-index: 9999;
top: 0;
left: 0;
background-color: #000;
background-image: url(/path to img/rotate.png);
background-size: 100px 100px;
background-position: center;
background-repeat: no-repeat;
display: none;
}
#media only screen and (max-device-width: 667px) and (min-device-width: 320px) and (orientation: landscape){
#rotate-device {
display: block;
}
}
<div id="rotate-device"></div>

Categories

Resources