window.outerWidth is 0 in Safari on iOS 10 beta - javascript

Using an iPad with iOS 10 installed, I entered window.outerWidth in the browser console and got a value of 0. OTOH, window.innerWidth correctly produced 1024 (landscape mode).
In iOS 9, window.outerWidth correctly produced 1024, so is this just a bug in the iOS 10 beta or is there a subtlety to this property that I'm missing?

The issue is more than just the iOS 10 Beta, but I doubt it is a priority for Apple Devs to fix as iOS devices don't really have an external frame on the sides of their browser window, so window.innerWidth is the same as window.outerWidth.
To see this working in a different context, you can pop open the inspector in your browser and emulate a smaller device. The inner width will be equal to the page width, while the outer width will be equal to the full width of the open browser.
If you still need to use outerWidth, what you can do as an alternative is either check the screen width using:
let mq = window.matchMedia( "(min-width: 1025px)" );
mq.matches will evaluate to true if you're on a desktop, and you can then use outerWidth for desktop and innerWidth for mobile. Or you could just make an alternative function to do it for you like this:
let screenWidth = () => {
const mq = window.matchMedia( "(min-width: 1025px)" );
if (mq.matches) {
return window.outerWidth;
} else {
return window.innerWidth;
}
}
Note that 1025px is 1 more pixel wide than an iPad Air 2 in landscape orientation.

If you're using jQuery in your project, you can use $(window).outerWidth() and $(window).outerHeight(). It's a workaround that works as expected in all devices.

Related

Why "screen.height" works fine when using Chrome' DevTool to simulate mobile devices, but not on real mobile devices?

The screen.height I am talking about is described in https://www.w3schools.com/jsref/prop_screen_height.asp
I used screen.height < 560 ? true : false to determine whether the screen height is smaller than a threshold, so I can hide some UI elements in this case.
It works fine in Chrome's simulator for mobile devices (the feature highlighted below).
By "works fine", I mean when simulating a mobile device, like setting device to be iPhone X as shown above and displaying in landscape mode, the UI elements are hidden correctly due to screen.height < 560 = true.
However, on real mobile devices like a real iPhone X, the UI elements don't get hidden, which I guess is because that it is always screen.height < 560 = false, even if it is in landscape mode.
I am wondering why is that... Why iPhone X in DevTool has a different height from a real iPhone X?
Is the simulation in Chrome DevTool not accurate? Or is it because screen.height doesn't return the correct value on mobile device?
Any hints would be appreciated!
That's because the simulator takes the screen size according to the dimensions that you are setting there. But in reality, screen.height takes the height size of the whole screen, including elements that are outside of the viewport in the device. You should use window.innerHeight to get an accurate height size.
If you log in your console screen.height and window.innerHeight on the simulator, you will get the same size. If you do this in the normal viewport (deactivating the simulator), you will get different values.
More info: Screen Height - Window InnerHeight
UPDATE
screen.height doesn't update on screen rotation, always has the same value corresponding to the screen height in portrait mode, while window.innerHeight takes the current height of the device window either portrait or landscape. Just make sure to fire this in the event when the rotation happens.
For this, you could use the Window.matchMedia() like so:
// Breakpoints
const breakpoint = window.matchMedia('(max-height: 560px)');
// Breakpoint checker
const breakpointMutations = () => {
if (breakpoint.matches === true) {
// Do something
}
}
// Run breakpoint checker if media changes
breakpoint.onchange = function (event) {
breakpointMutations();
}
// Run breakpoint checker on load
breakpointMutations();
It might be because you are missing the response meta tag. Try adding this to your head tag:
<meta name="viewport" content="width=device-width, initial-scale=1">

Finding the size of screen using JS on a 4k monitor

I'm working on a photo carousel. The intent is to display x pictures on one row where x is dependent on the viewport size. By viewport I mean the area inside the browser's window less scroll bars. The photos are re-sized to a width of 200 If the viewport width is 2000 I can get 10 photos (200*10=2000) (I kept the arithmetic easy)
My screen resolution is 3840x2160. I expanded the browser to take up the entire screen. When I use: $(window).width() i come up with 1707 and with screen.width I come up with 1707. Definitely not 3840.
When I resize the browser so that it's taking up about half the screen I get:
$(window).width() of 929 and with screen.width 1706.
For browsers I'm using Edge, IE11, FF and Chrome 46 and I get roughly the same problem.
My desktop monitor is also 4k and from what I've read it consists of two panels of 1920x1080 for a total of 3840x2160. If that's true, on my laptop 4k monitor I should be getting a width of 1920 using screen.width, if I take up the entire screen but I'm not.
I need to take into account that most folks viewing this website will not have 4k monitors.
Any ideas on how I can get the screen width on a 4k monitor?
Perhaps you can make use of the window.devicePixelRatio property.
It should give you 1, 2, etc. Multiply window.innerWidth and window.innerHeight by this value.
var width = window.innerWidth * window.devicePixelRatio;
var height = window.innerHeight * window.devicePixelRatio;
On my Dell laptop with a 4K UHD screen (3840 * 2160) display resolution, with Windows display settings configured to have a 250% scale and layout, I get the following results:
MDN documentation: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
To get the windows' dimensions :
var width = window.innerWidth;
var height = window.innerHeight;
To get the screen's dimensions :
var width = screen.width;
var height = screen.height;
Javascript should report me for my 4K monitor the screen resolution 3840 x 2160. In fact, I get:
screen.width=2560
screen.height=1440
document.querySelector('html').clientWidth=2526
window.innerWidth=2526
window.outerWidth=2575
document.querySelector('html').clientHeight=1301
window.innerHeight=1301
window.outerHeight=1415
screen.availWidth=2560
screen.availHeight=1400
40 pixels is the Windows 10 Taskbar at the bottom of the desktop.

Difference of $(window).width() on normal state and responsive state on inspect element

I'm wondering why there is a difference when using $(window).width() in the browser standard and device emulation mode.
When I used $(window).width() on the browser with the width of 1024px i got the value of 1007 in standard mode, but when used it on device emulation mode i got the exact 1024.
So whats the difference between the two and is there anyway to check the specific width that is exact on the normal window mode and device emulation mode?
What i'm using now is $(window).width() for the checking of the window size so is there anyway to check the actual size beside this one?
the difference is in the scrollbar of your browser. In latest version of all browsers (http://www.textfixer.com/tutorials/browser-scrollbar-width.php) the scrollbar width is 17px and if you add it to 1007 you get exactly 1024px.
The measure is correct as it refers to the area of the browser that is "available" for rendering content - returning the browser full width would be incorrect.
Try to check position like,
function checkPosition() {
if (window.matchMedia('(min-width: 1024px)').matches) {
//...
} else {
//...
}
}
Alternatively, you can use modernizr mq method like,
if (Modernizr.mq('(min-width: 1024px)')) {
//...
} else {
//...
}

JavaScript algorithm to determine orientation of tablet

We're building an HTML5/JavaScript app developed for tablets, and we want to lay out my screens differently in landscape versus portrait.
Originally, we were capturing orientation change notifications, and keeping track of the current orientation (generally reported as 0, 90, -90 or 180 degrees -- see this question). Unfortunately, different devices report different orientations as "0". That link argues that it's a bug, but there's some evidence that this is working-as-designed -- for example, this article suggests that "landscape" is the default orientation and those devices report an orientation of "0" when held in landscape mode.
We next tried to just look at the actual screen size, assuming that when width was greater than height, we were in landscape mode. But this algorithm gets confused when the on-screen keyboard is displayed -- when the keyboard is displayed, the dimensions of the visible area are returned. When the device is, strictly speaking, in portrait mode, but the portion of the screen not obscured by the keyboard is wider than it is tall.
The response to this question is quite old. Is that still the best answer? Does anyone have a good algorithm that takes the keyboard visibility into consideration?
http://jsfiddle.net/jjc39/
Try this:
<span id="orientation">orientation</span>​
$(document).ready(checkOrientation);
$(window).resize(checkOrientation);
function checkOrientation() {
var orientation = "Portrait";
var screenWidth = $(window).width();
var screenHeight = $(window).height();
if (screenWidth > screenHeight) {
orientation = "Landscape";
}
$("#orientation").html(orientation);
}​

window.screen.width and window.screen.height not working on iPad 3

I'm using the functions
window.screen.width
window.screen.height
to detect the screen resolution of the user.
They work like a charm on PCs, but they don't on iPad 3.
They output 768 and 1024 instead of 2048 and 1536.
Can somebody help me, please?
Thank you in advance
Yep. Welcome to the interesting world of Mobile devices!
The iPad 3 (and other retina devices) use window.devicePixelRatio set to 2 to show that they have different css pixels to logical pixels. An iPad 3 still reports 1024 × 768, as that is the number of CSS pixels.
As another source of confusion, some Android devices report the viewport width, and some the physical width, meaning that if you ask some Android devices, the window.screen.height will be thousands and thousands if the document is long.
In short, for your problem, use window.devicePixelRatio as a multiplier. I'd use something like
if(!window.devicePixelRatio) {
window.devicePixelRatio = 1;
}
To ensure that if it isn't set that it's declared as 1 before you start.
if(window.devicePixelRatio !== undefined) {
dpr = window.devicePixelRatio;
} else {
dpr = 1;
}
var screen_width = window.screen.width * dpr;
var screen_height = window.screen.height * dpr;
This solution works perfectly.

Categories