I've just read a nice article on viewport which left me with a couple questions regarding Visual viewport vs Layout viewport on mobile devices.
the width and the height of the layout viewport are equal to whatever
can be shown on the screen in the maximally zoomed-out mode
I did not quite understand what that means. When they say "maximally zoomed-out mode", does that mean that the layout viewport is different for different HTMLs (and not specific to different devices like iPad, Xoom, etc)?
Secondly, I've created a demo page to measure these two viewports. (Please view this on an iPhone/iPad to get the correct values.)
I understand that the layout viewport can be changed by setting the meta viewport tag, but that also changes the visual viewport--why is that? It says that the visual viewport is the part of the page that’s currently shown on-screen, so my understanding was that the visual viewport should not be affected by the meta viewport setting.
Both the layout viewport and visual viewport are measured in CSS pixels. This is an important distinction to make. As opposed to the physical pixels on the device, CSS pixels are used to keep dimensions of the content relatively constant and controlled, and the device then translates CSS pixels into device pixels.
Understanding the difference between CSS pixels and device pixels may assist in the understanding and answering of your questions.
The layout viewport's dimensions are effectively the initial dimensions of the content (in CSS pixels).
The layout viewport is used to best determine how to position and render the content initially. It is independent of the device's zoom level. By saying "...whatever can be shown on the screen in the maximally zoomed-out mode", I think he's alluding to the point that the layout viewport's dimensions are unchanging; it will always be the same size, irrespective of the current visual viewport.
The visual viewport is just the viewable area of the page -- again, in CSS pixels. If you zoom in on a page, you're increasing the size of the CSS pixels, which naturally reduces the number of CSS pixels that can fit on the device. That's why the visual viewport's dimensions shrink when you zoom.
The visual viewport cannot be any larger than the content on the page.
The content's dimensions are largely dictated by the layout viewport.
The layout viewport's dimensions are set by the meta-viewport rule.
Therefore, the visual viewport's dimensions should change in reaction to changes in the meta-viewport rule.
You have since asked (in comments):
Why is it that when there's content that's explicitly wider than the layout viewport, the visual viewport is stretching to fit all of that in? Shouldn't there be a scrollbar?
No, because you're only indicating to the browser what the initial dimensions of the layout viewport should be, not the visual viewport.
If you want the visual viewport's dimensions to not adjust to the full width of the content on page load, set the initial-scale=1 property inside the meta-viewport declaration.
There's a fantastic read over on the Mozilla Dev Centre about the viewport meta tag: https://developer.mozilla.org/en/mobile/viewport_meta_tag
Related
I have almost always used $(window).width() to check the viewport width. It normally works for both browsers and devices. But for a website on which I need to show a particular splash screen if viewport width is less than 768px, this is not working. It gives correct width upto a point but below that it keeps giving 980px howsoever narrow I make the browser. There are a few particular conditions for this site:
This site was responsive in beginning (using bootstrap) but then made non-responsive. For this we removed viewport meta tag and set following rule in css that overrides its responsive widths:
.container{ width: 1170px; }
If I resize the whole browser i.e. the window that contains all browser tabs, then it does give correct width (less than 980px also, which is the desired behaviour), but if I use development tools and use the mobile layouts from there then width is never reported to be below 980px.
It would not have mattered that it worked on resizing only the main browser window, but the issue is that it is not working in devices as well. I added an alert and on mobile devices, again width is never alerted to be less than 980px.
Can someone please suggest some solution for this or explain why it is not working as expected?
I can't seem to find any authoritative source, but there are many pages that mention smartphones assume a website is 980px wide unless told otherwise.
Apple's developer site for instance says
The majority of webpages fit nicely in the visible area with the viewport width set to 980 pixels in portrait orientation, as shown in Figure 3-4. If Safari on iOS did not set the viewport width to 980 pixels, then only the upper-left corner of the webpage, shown in gray, would be displayed. However, this default doesn’t work for all webpages, so you’ll want to use the viewport meta tag if your webpage is different. See Supported Meta Tags for more on viewport.
Figure 3-4 Comparison of 320 and 980 viewport widths
(Incidentally, it was the iPhone which first did this, but other phones soon followed.)
So the solution is either to put
<meta name="viewport" content="width=device-width">
into the head (in your case, back into the head), or, acknowledge that the site is now not-responsive, and will not perform optimally on a phone!
I noticed that the <canvas> element can have different scales. For instance, if I set the CSS width and height to 100px, but have the javascript set the element's width and height to 200px, the element is sized down so everything printed on it is 1/2 the size. (Or 2x the resolution)
I have a retina screen Macbookpro, so in development, I set the scaling to 2x so the images and objects look clear and crisp on my screen.
I have heard that other screens can have a 1.2x resolution (CSS pixels vs Actual pixels)
Is there a way to find out what the resolution/scaling is of the device's screen so I can make my canvas as crisp and as clean as possible to the user?
If it helps at all, I'm trying to make a game in javascript using canvas as my graphics output.
These properties will give your dimensions:
window.screen.availHeight
window.screen.availWidth
For pixel depth, use this property:
window.devicePixelRatio
For application in canvas, a helpful script and explanation is given here.
After searching around using different terms, I was able to find the answer that I was looking for.
The window object has a variable called window.devicePixelRatio. This lets us know the ratio of pixels to the device's screen pixels. On my retina screen, this variable gives me a 2. With this, I can set the canvas to the correct scaling so it looks clean and crisp on any screen.
Source: http://www.html5rocks.com/en/tutorials/canvas/hidpi/
What I want to is set <body> to be 100% width and height (or viewport width / height), but when the user zooms, either via pinching on mobile or numerous methods on a desktop browser, I want the viewport to scale with the zoom. So where as body used to be the size of the viewport, if you zoom in 2x, I want the viewport to be 2x bigger.
One possible solution would be to measure the viewport in javascript on load and then set body to be those dimensions, then it would scale the way I desire. I could then put more hooks into viewport resizing to get it to appear the correct size, but it'd be nicer if there was a css / html solution, even if it doesn't necessarily work on all browsers.
I have an element with position fixed (pinned to any corner) on a page (which I do not necessarily have control over the meta viewport tag - it is an embedded widget for third party sites). On Mobile Safari when the user pinch zooms the page at a certain point the viewport becomes larger than the visible area. At that point the fixed position element stays attached to the viewport and is not necessarily in the visible area.
I would like to compare two widths: the width of the visible area and the width of the viewport. I believe the size of the visible area is window.innerWidth. I am not sure how to measure the viewport.
I have been trying to see the relationships between:
document.documentElement.clientWidth
screen.width
window.innerWidth
window.outerWidth
...But have not been able to see anything obvious.
This is butt ugly but it does show some code that almost works (view on iOS to see it working. Use a desktop and click edit at top right of page to see or edit code):
https://jsbin.com/jopamu (iOS only)
The trick with the "overzoom" calculation is nasty but it does compensate somewhat for the multiple viewport zooms. It is a complex problem to solve because there are competing issues:
pinch-zoom
zoom due to input focus
the "position:fixed" zoom
potentially the OS (accessibility) zoom
The possible solutions I have found are:
Position the menu using the calculations above and position:absolute - updating the left/top in onscroll event. Has ugly juddering (can improve a little by hiding and only showing when zooming/scrolling finishes).
Position the menu using position:fixed but change the left/top to correct the menu position as zooming/scrolling occurs. Much less judder but I couldn't quite get it 100% reliable (some race condition).
Not suitable for your case (and highly unrecommended due to risk of breaking things): you can prevent pinch zooming and iOS10 double-click zooming by cancelling default on touchstart. Difficult because it needs many other workarounds so normal touch works, and needs synthetic scrolling and zooming (but has ugly side effects such as preventing scrolling working sometimes and also interferes with accessability e.g. if voice accessability turned on etc etc).
If you just want to see the widths then use the older version:https://output.jsbin.com/jopamu/6
I have a website, its uses the 960 grid system, everything is fine.
Except the header, the header is too tall!
Is it possible to reduce the entire website size when the user's screen is less than or equal to 1024x768 ?
(same way you can press CTRL+ and CTRL- in IE?)
IE does support the non-standard zoom style, which you could apply to the <body> if you detect the window size is too small.
Technically this is possible, but I would advise against using such non-conventional approaches. I would just use a short header that will look good both in <= 768 and > 768.
After the document is loaded, you could check (using JavaScript) the client height of the body and apply a style to your <body> element (or just the header) to set the font size to a certain percentage. All your other dimensions would have to defined in em or percentage units so that the base size at the main container propagates to child elements.