Skip to content

Instantly share code, notes, and snippets.

@jaggli
Last active June 30, 2016 10:19
Show Gist options
  • Save jaggli/7edf8b031c0e1043bed073849e36f2f7 to your computer and use it in GitHub Desktop.
Save jaggli/7edf8b031c0e1043bed073849e36f2f7 to your computer and use it in GitHub Desktop.
Measure viewport with JavaScirpt
/*!
Reading the user agent viewport
Author: https://github.com/jaggli
License: https://www.tldrlegal.com/l/wtfpl
*/
var getViewport = function getViewport(noCache){
var
guid = "_viewport-612ed011-5444-4166-8026-e00d76e426a3",
viewport = window[guid];
if(viewport && !noCache){ return viewport; }
var
hadViewportMeta = false,
origMetaContentAttr = "",
meta = document.querySelector("meta[name=viewport]"),
metaContentAttr = "width=device-width";
// read original content attribute
if(meta){
hadViewportMeta = true;
origMetaContentAttr = meta.getAttribute("content") || "";
}
// replace original width part of content attribute
if(origMetaContentAttr){
metaContentAttr = origMetaContentAttr
.split(/[,;]\s*/g)
.filter(function(elem){ return elem.indexOf("width=") !== 0; })
.reduce(function(a, b){ return a +", "+ b; }, metaContentAttr);
}
// add meta tag, if none was present
if(!meta){
meta = document.createElement("meta");
meta.setAttribute("name", "viewport");
document.getElementsByTagName("head")[0].appendChild(meta);
}
// set viewport meta
meta.setAttribute("content", metaContentAttr);
// read viewport
viewport = {
width: document.documentElement.clientWidth,
height: Math.round(
document.documentElement.clientWidth * document.documentElement.clientHeight /
document.documentElement.clientWidth
)
};
//restore initial state
meta.setAttribute("content", origMetaContentAttr);
if(!hadViewportMeta){
meta.parentNode.removeChild(meta);
}
window[guid] = viewport;
return viewport;
};

Reading the user agent viewport

Because all frameworks I found, fail at least at one of the following points:

  • dip values, this means device independant pixels
  • manually modifing the viewport with browser zoom level delivers the manually set values (zoom 50% = double viewport)
  • automatical device zoom is ignored (typically set on mobile browsers for large content)
  • pinch zoom on touch devices is ignored

getViewport([noCache])

noCache: boolean (default: false) set to true so skip cached values from previous measurements
Note: Measuring the viewport with this method is somehow expensive for pages without viewport meta-tag set the width to device-width

var viewport = getViewport();

Returns an object with two int values

{
  width: <int>,
  height: <int>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment