- Viewport meta tag
- Background
- Viewport basics
- Screen density
- Viewport width and screen width
- The effect of interactive UI widgets
- Common viewport sizes for mobile and tablet devices
- Specifications
- See also
- Found a content problem with this page?
- scale()
- Try it
- Syntax
- Values
- Accessibility concerns
- Scaled/Proportional Content with CSS and JavaScript
- Full Screen website Zoom using css-transform scale and jQuery
- Some Big Feature headline
- More stuff
- Another Box
- Receive stories like this in your inbox.
Viewport meta tag
This article describes how to use the «viewport» tag to control the viewport’s size and shape.
Background
The browser’s viewport is the area of the window in which web content can be seen. This is often not the same size as the rendered page, in which case the browser provides scrollbars for the user to scroll around and access all the content.
Some mobile devices and other narrow screens render pages in a virtual window or viewport, which is usually wider than the screen, and then shrink the rendered result down so it can all be seen at once. Users can then pan and zoom to see different areas of the page. For example, if a mobile screen has a width of 640px, pages might be rendered with a virtual viewport of 980px, and then it will be shrunk down to fit into the 640px space.
This is done because not all pages are optimized for mobile and break (or at least look bad) when rendered at a small viewport width. This virtual viewport is a way to make non-mobile-optimized sites in general look better on narrow screen devices.
However, this mechanism is not so good for pages that are optimized for narrow screens using media queries — if the virtual viewport is 980px for example, media queries that kick in at 640px or 480px or less will never be used, limiting the effectiveness of such responsive design techniques. The viewport meta tag mitigates this problem of virtual viewport on narrow screen devices.
Viewport basics
A typical mobile-optimized site contains something like the following:
meta name="viewport" content="width=device-width, initial-scale=1" />
Not all devices are the same width; you should make sure that your pages work well in a large variation of screen sizes and orientations.
The basic properties of the «viewport» tag include:
Controls the size of the viewport. It can be set to a specific number of pixels like width=600 or to the special value device-width , which is 100vw, or 100% of the viewport width. Minimum: 1 . Maximum: 10000 . Negative values: ignored.
Controls the size of the viewport. It can be set to a specific number of pixels like height=400 or to the special value device-height , which is 100vh, or 100% of the viewport height. Minimum: 1 . Maximum: 10000 . Negative values: ignored.
Controls the zoom level when the page is first loaded. Minimum: 0.1 . Maximum: 10 . Default: 1 . Negative values: ignored.
Controls how much zoom out is allowed on the page. Minimum: 0.1 . Maximum: 10 . Default: 0.1 . Negative values: ignored.
Controls how much zoom in is allowed on the page. Any value less than 3 fails accessibility. Minimum: 0.1 . Maximum: 10 . Default: 10 . Negative values: ignored.
Controls whether zoom in and zoom out actions are allowed on the page. Valid values: 0 , 1 , yes , or no . Default: 1 , which is the same as yes . Setting the value to 0 , which is the same as no , is against Web Content Accessibility Guidelines (WCAG).
Specifies the effect that interactive UI widgets, such as a virtual keyboard, have on the page’s viewports. Valid values: resizes-visual , resizes-content , or overlays-content . Default: resizes-visual .
Warning: Usage of user-scalable=no can cause accessibility issues to users with visual impairments such as low vision. WCAG requires a minimum of 2× scaling; however, the best practice is to enable a 5× zoom.
Screen density
Screen resolutions have risen to the size that individual pixels are indistinguishable by the human eye. For example, smartphones often have small screens with resolutions upwards of 1920–1080 pixels (≈400dpi). Because of this, many browsers can display their pages in a smaller physical size by translating multiple hardware pixels for each CSS «pixel». Initially, this caused usability and readability problems on many touch-optimized websites.
On high dpi screens, pages with initial-scale=1 will effectively be zoomed by browsers. Their text will be smooth and crisp, but their bitmap images may not take advantage of the full screen resolution. To get sharper images on these screens, web developers may want to design images – or whole layouts – at a higher scale than their final size and then scale them down using CSS or viewport properties.
The default pixel ratio depends on the display density. On a display with density less than 200dpi, the ratio is 1.0. On displays with density between 200 and 300dpi, the ratio is 1.5. For displays with density over 300dpi, the ratio is the integer floor (density/150dpi). Note that the default ratio is true only when the viewport scale equals 1. Otherwise, the relationship between CSS pixels and device pixels depends on the current zoom level.
Viewport width and screen width
Sites can set their viewport to a specific size. For example, the definition «width=320, initial-scale=1» can be used to fit precisely onto a small phone display in portrait mode. This can cause problems when the browser renders a page at a larger size. To fix this, browsers will expand the viewport width if necessary to fill the screen at the requested scale. This is especially useful on large-screen devices.
For pages that set an initial or maximum scale, this means the width property actually translates into a minimum viewport width. For example, if your layout needs at least 500 pixels of width then you can use the following markup. When the screen is more than 500 pixels wide, the browser will expand the viewport (rather than zoom in) to fit the screen:
meta name="viewport" content="width=500, initial-scale=1" />
Other attributes that are available are minimum-scale , maximum-scale , and user-scalable . These properties affect the initial scale and width, as well as limiting changes in zoom level.
The effect of interactive UI widgets
Interactive UI widgets of the browser can influence the size of the page’s viewports. The most common such UI widget is a virtual keyboard. To control which resize behavior the browser should use, set the interactive-widget property.
The visual viewport gets resized by the interactive widget.
The viewport gets resized by the interactive widget.
Neither the viewport nor the visual viewport gets resized by the interactive widget.
When the viewport gets resized, the initial containing block also gets resized, thereby affecting the computed size of viewport units.
Common viewport sizes for mobile and tablet devices
If you want to know what mobile and tablet devices have which viewport widths, there is a comprehensive list of mobile and tablet viewport sizes here. This gives information such as viewport width on portrait and landscape orientation as well as physical screen size, operating system and the pixel density of the device.
Specifications
See also
Found a content problem with this page?
This page was last modified on Jul 5, 2023 by MDN contributors.
Your blueprint for a better internet.
scale()
The scale() CSS function defines a transformation that resizes an element on the 2D plane. Because the amount of scaling is defined by a vector, it can resize the horizontal and vertical dimensions at different scales. Its result is a data type.
Try it
This scaling transformation is characterized by a two-dimensional vector. Its coordinates define how much scaling is done in each direction. If both coordinates are equal, the scaling is uniform (isotropic) and the aspect ratio of the element is preserved (this is a homothetic transformation).
When a coordinate value is outside the [-1, 1] range, the element grows along that dimension; when inside, it shrinks. A negative value results in a point reflection in that dimension. The value 1 has no effect.
Note: The scale() function only scales in 2D. To scale in 3D, use scale3d() instead.
Syntax
The scale() function is specified with either one or two values, which represent the amount of scaling to be applied in each direction.
Values
Cartesian coordinates on ℝ^2 | Homogeneous coordinates on ℝℙ^2 | Cartesian coordinates on ℝ^3 | Homogeneous coordinates on ℝℙ^3 |
---|---|---|---|
( sx 0 0 sy ) | ( sx 0 0 0 sy 0 0 0 1 ) | ( sx 0 0 0 sy 0 0 0 1 ) | ( sx 0 0 0 0 sy 0 0 0 0 1 0 0 0 0 1 ) |
[sx 0 0 sy 0 0] |
Accessibility concerns
Scaling/zooming animations are problematic for accessibility, as they are a common trigger for certain types of migraine. If you need to include such animations on your website, you should provide a control to allow users to turn off animations, preferably site-wide.
Also, consider making use of the prefers-reduced-motion media feature — use it to write a media query that will turn off animations if the user has reduced animation specified in their system preferences.
Scaled/Proportional Content with CSS and JavaScript
The web is a fluid place. Different sized screens, yadda yadda yadda. Fortunately for us, the web is ready for it. Text wraps. CSS gives us control over how to size things. What we don’t get (easily, anyway) is a way to scale whole element (and it’s children) proportionally—retaining its exact layout as it changes size. We can do it though.
Proportional scaling of a *container* is fairly easy
This can be quite useful for things like images, containers that can independently scroll, or containers with so much spare room that it can handle dramatic changes in shape. If the content of this container was, say, an image, it works great! But things aren’t so happy if there are a bunch of HTML element children just doing what regular ol HTML elements do.
Proportional scaling of everything
Let’s say this is the kind of thing we’re after: CSS alone can’t really do this. But CSS is still the answer! transform: scale(); is what we need. It scales things perfectly proportionally. We just need to give it a number to scale it by, and that scale we can figure out with some JavaScript. The trick is:
var scale = Math.min( availableWidth / contentWidth, availableHeight / contentHeight );
Here’s one possible approach to that, using jQuery and jQuery UI Resizeable (because that’s easy and comfortable for me): See the Pen Resize with Scale by Chris Coyier (@chriscoyier) on CodePen.
SVG does this all by itself. Let’s cover this in an article really soon. I have some things to say. 😉 Also, you may be able to size everything with vw/vh units maybe, but that sounds like a pain in the butt and a whole lot of magic numbers.
It’s probably a bit rare that you’d need this
The reason I’m all into this idea is because I noticed that embeddeddable slide decks from Slides.com work like this. That’s a perfect use case. Slides.com gives you a fixed size canvas to create your slides on, which completley makes sense. Then those slides can scale up if needed, to present in a larger space. Or scale down to fit on smaller screens (like if you embed them into a blog post with a narrow content column or view on a mobile device). I think about Embedded Pens as well. Sometimes people design Pens to work in a larger area, and the design breaks down when it’s embedded. I could use this to proportionally resize the guts, but only as much as needed to fit. Maybe iframes? Probably mostly third-party or user-generated stuff, and in situations where the proportion matters, otherwise, carry on with regular RWD action.
Full Screen website Zoom using css-transform scale and jQuery
If the design calls for “zooming” in to the width of the browser, with everything scaling up proportionally, text & images included, then this bit of code is for you!
Match the body width, let’s say 1000px in this example, to the PSD design and essentially code the site like it’s 1999, as a fixed width layout. Then, with a little sprinkle of jQuery, when the browser window is increased to a size larger than 1000px, you’ll adjust the css transform scale function to “zoom” into the site.
For sizes lower than 1000px, you’ll just use regular media queries. This method should be compatible down to IE9 (but worst case, the design just maxes out to 1000px then.)
With the time you saved, go have a Gallus.
Some Big Feature headline
More stuff
Another Box
html, body < width: 100%; margin: 0; padding: 0; >body < margin: 0 auto; width: 1000px; >img < width: 100%; >header < width: 100%; background-color: pink; >div < float: left; width: 60%; background-color:green; >div+div < width: 40%; background-color: teal; >header h1, div h2 < padding: 12px; >body < background-color:lightblue; -ms-transform:scale(1); // Req for IE9 transform:scale(1); >
jQuery(document).ready(function($)< nsZoomZoom(); $( window ).resize(function() < nsZoomZoom(); >); function nsZoomZoom() < htmlWidth = $('html').innerWidth(); bodyWidth = 1000; if (htmlWidth < bodyWidth) scale = 1 else < scale = htmlWidth / bodyWidth; >// Req for IE9 $("body").css('-ms-transform', 'scale(' + scale + ')'); $("body").css('transform', 'scale(' + scale + ')'); > >);
Receive stories like this in your inbox.
About north street
We engineer the thoughtful transformation of great organizations. Our proven process helps us understand what your competitors are doing right — and wrong. Want to learn more? Let’s chat.