Bruce Lawson's personal site

Why is viewport in a meta tag?

Adam Bradley asked

Marcos Caceres replied

HTML never required an <html>, <head> or <body> element (only XHTML validators did). So if you open test 1 in any browser and view source you’ll see those three elements aren’t in the source. But if you inspect the DOM with any inspection tool, you’ll the browser has inserted those elements.

How does the browser know where to close the <head> and open the <body>? Test 2 shows a page that contains a <vomitingotter> element. This isn’t offcially part of HTML yet (hurry up Hixie!). There is no <body> element in the source, but the browser knew to leave the <title> and <meta charset> in the head and add the <vomitingotter> element into the <body> (which is why you can actually see its contents; by default, no text in the <head> makes its way into the visible page.)

Simply, the first element that isn’t known to be part of the <head> makes the browser close the <head> and open the <body>. So if it’s not recognised as metadata content (<base>, <link>, <meta>, <noscript>, <script>, <style>, <template>, <title>) it goes in the body. Any subsequent “head” elements remain in the <body>; they aren’t restored into the head (see the DOM of test 3), even if you explicitly wrap them in <html>, <head> and <body> elements in the original source – see test 4.

This doesn’t investigate the bigger question of why Apple – who invented the viewport meta tag – decided to add it to HTML at all. After all, HTML is about content and the viewport information is about styling, and would therefore be more appropriately be declared in CSS. I don’t know the answer to that, except that Apple knows best about everything.

There’s a CSS specification called CSS Device Adaptation that is basically “viewport in CSS”, with an @viewport rule (tutorial by Andreas Bovens). This generalises the viewport directive, and gives you more power, too; because it’s in CSS you can combine it with Media Queries. It’s supported in Opera, Chrome and Internet Explorer.

Buy "Calling For The Moon", my debut album of songs I wrote while living in Thailand, India, Turkey. (Only £2, on Bandcamp.)

13 Responses to “ Why is viewport in a meta tag? ”

Comment by Yoav Weiss

One note regarding @viewport:
@viewport is not something people should use in external CSS.

When used there it can cause both performance issues (for resources which rely on viewport dimensions, mostly responsive images and external style sheets for now, but we may have more in the future), as well as possible infinite loops (when combined with the media attribute and external stylesheets).

So, while I understand the argument that viewport information should not be <meta>, when @viewport is used, it should be used inline.

Comment by ppk

I always assumed that the meta viewport is in the HTML in order to make sure that the layout viewport width is set and available at the moment the engine starts parsing the CSS. If the information comes later, the engine would have to backtrack and do extra work.

Yoav’s comment points at something similar with @viewport, so I guess I’m not far from the truth here.

In addition, when Apple created this whole system mobile phones were MUCH less powerful than they are today, so performance back then required a solution like this. (This can also be said of many other Safari oddities such as not switching the layout viewport to landscape mode onorientationchange -> saves battery life because a page reflow is unneceesary.)

I guess that nowadays all this is less necessary from a performance perspective, but meanwhile the old solutions have become set in stone.

So there you go. It won’t ever change.

Comment by Gunnar Bittersmann

A little nitpicking: HTML has always required html, head and body elements (at least since version 4—I don’t bother to look further back). HMTL does not require opening or closing tags for these elements. That’s the reason that you’ll find these elements in the DOM even if you don’t have the tags in the HTML source code.

Comment by Charlie

@yoav – it still shouldn’t be in the HTML as it tells us nothing about structure or metadata. Media queries are the way to solve the issue but that would probably have required more work and cooperation with others.

It probably got in there along with other elements because Apple initially only supported widgets. The meta tag allowed Apple to hack support into Safari. Because this worked so well they tried a similar trick with the srcset crap.

Comment by Ben Frain

The whole @viewport thing troubles me. You can’t use it ‘in the wild’ as it doesn’t cover off iOS and whilst I know they aren’t the only devices out there, they are a sizeable chunk. Desktop wise you get neither Safari or Firefox which at this point makes it a little hobbled as a solution. As Yoav stated it needs to be written in the head too where it sticks out like a sore thumb – there is no other ‘default’ code I can think off that requires some &amp;lt;style&gt; tags in the head.

The viewport &amp;lt;meta&gt; however works just about everywhere needed apart from IE10+ (inc mobile I think) so there is no option for authors seeking wide compatibility other than using both. Absurd!

As to the original question: like PPK, I’d always assumed it was in the HTML because otherwise what about any pages without CSS? With the meta in the HTML they still get a sensible layout.

I think actually think that Apple made absolutely the right choice.

Comment by Bruce


“The whole @viewport thing troubles me. You can’t use it ‘in the wild’ as it doesn’t cover off iOS and whilst I know they aren’t the only devices out there, they are a sizeable chunk. Desktop wise you get neither Safari or Firefox which at this point”

I’d use the viewport meta for iOS and backwards compat; @viewport can finesse designs – for example, you can use a different viewport for different device widths to send slightly different design to tablets and phones. (At the moment, both tablets and phones understand the viewport meta, so they’re forced into the same viewport.

As for desktop – do desktop browsers understand the viewport meta tag?

Comment by John Foliot

Hey Bruce,

Walking into the discussion with my Accessibility hat on… there is a hugely significant and potentially show-stopping problem with both the viewport meta-tag as well as the CSS Device Adaptation specification, in that by using either of those methods, developers can stop content from zooming:

&amp;lt;meta name=&quot;viewport&quot; maximum-scale=&quot;0&quot;&amp;gt;
@viewport {max-zoom: 0;}

Suffice to say this is *REALLY BAD* for some users (primarily low-vision, which can also encompass seniors – including old guys like me and you), but it can also impact users with some forms of mobility dysfunction (they may need to zoom links or buttons large enough to touch them with, say, a mouth-stick). It should go without saying that locking down the end-users ability to zoom (and reflow) content on the mobile platform isn’t smart, and hopefully we can all spread the word to *NOT* do this with either the meta-tag nor the CSS declaration.

Thanks for helping spread the word!

Comment by Adam Bradley

Thanks, that clears it up. In the end it seems the viewport meta tag was Apple’s immediate solution for backwards compat while adding in a new feature which gave hints to the user-agent in how to render the document.

So next thought, this makes me wonder if we will, and if we should, continue to go down the road of using meta when creating a new wizbang feature, whatever it may be.

Comment by Benjamin Frain

Ha, yes good point on desktop 😉 Although I do need to check what mobile Firefox likes.

Also, any idea what stock Android browser is supporting these days (4.3+)? Last time I looked caniuse didn’t even have the @viewport listed.

Ultimately, authors need to use both. Nothing seems to have changed significantly since this:

Although the fact that it’s now ‘live’ in Chrome/Opera is of note.

Comment by Nao

Hey there. Are you positive that @viewport is supported on Chrome..?

I tried it on my website with both @viewport and @-webkit-viewport rules, and none of them triggered the proper device-width on Chrome Android 35, Chrome Android Beta 38 and Opera Android (Chromium 37). Adding the meta tag fixes that, but obviously this isn’t what I wanted to do…

For me, the only mobile browser where @viewport works is Opera Classic, using the @-o-viewport rule.

Considering that it works on desktop by enabling the emulation button, it’s pretty much impossible to debug.

Comment by Charlie

Meta tags are definitely the wrong for this. HTML is extensible so a new tag such as simply viewport would have been better as it would have been more expressive and used individual attributes for clarity rather than overloading existing ones.

I guess the temptation was to use the meta tags which are like the appendix of a website: they’re there but don’t perform any useful function.

Leave a Reply

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> . To display code, manually escape it.