Return to Firewoiks

Extensions, resources & tutorials for Fireworks, Dreamweaver & HTML5 / CSS3 by UI developer, .

Responsive Design in IE10 on Windows Phone 8

Posted: January 6 2013, Updated: December 09 2014

Be sure to read the update from December 09 2014, as Microsoft have broken it again in IE11.

On October 17, 2012, 9 days before Windows 8's release, Tim Kadlec wrote an article, IE10 Snap Mode and Responsive Design, in which he told us to use CSS Device Adaptation to force IE10 in “snap mode” to display our responsive designs correctly as it ignores the meta viewport tag.

Tim suggested using:

@-ms-viewport {
	width: device-width;
}

as opposed to Microsoft's recommendation of:

@media (max-width: 400px) {
	@-ms-viewport {
		width: 320px;
	}
}

This all worked wonderfully until Microsoft released Windows Phone 8, which for some reason behaves differently to every other mobile OS by interpreting device-width as the actual resolution size (either portrait or landscape depending on how it's oriented), instead of what the manufacturer (or browser vendor) has decided is the optimal viewport width (such as the “standard” 320px in portrait).

This means that your “mobile-first” responsive designs will look anything but on Nokia's flagship Windows 8 phone, the Lumia 920, as it will render the page at its native resolution: 768 × 1280 pixels. The Lumia 820 has a lower resolution of 480 × 800 pixels, so these users will have a better experience, but still not the one we'd expect.

So what can we do? Implement Microsoft's recommended viewport CSS rule above, which works on Windows Phone 8 and in Windows 8 “snap mode”.

The downside to this is that IE10 on the desktop will not act responsively when the window is less than 401px wide, instead scaling the page from 320px to fit the window size. Your content will not reflow to fit the window, it will just get bigger or smaller as appropriate, meaning you can't test less than 320px styles on desktop IE10.

If you have a Windows Phone 8 device, I've created two test pages that demonstrate the issue when using device-width and the other displaying as expected by using width: 320px.

For everyone else, here's some screenshots:

Using device-width

Using width: 320px

Update: January 8 2013

After some conversations on Twitter, I've just tried two other methods of dealing with the viewport.

Using max-device-width in the media query

John Holt Ripley, asked whether using max-device-width in the media query would stop desktop IE10 from scaling the site. The answer, unfortunately, is no. Here's my test page.

Using <meta name="viewport" content="width=device-width" />

Adam Onishi noticed that 12 Devs of Xmas displayed fine on his Windows Phone 8. After a little debugging, it turns out that IE10 on Windows Phone 8 does acknowledge the meta viewport tag if it doesn't have an initial-scale value. Unfortunately, this doesn't work on Windows 8's “snap mode”. Here's the test page.

Similarly, using minimum-scale instead of initial-scale has the same effect.

Also, Rey Bango of Microsoft contacted me to say that he's “looking in to it”.

Update: January 15 2013

Following some discussions with Rey Bango, Microsoft have confirmed it is a bug with IE10 on Windows Phone 8 when using device-width with CSS adaption (@-ms-viewport). They are actively looking at patching the bug, but this will not happen immediately, and will be reliant on carriers to push the update to users when it becomes available.

In the meantime, Microsoft have provided a solution that relies on JavaScript and UA sniffing, which although isn't ideal, is the best way of dealing with the bug now, without harming future releases of IE10 or Windows Phone 8 devices.

Here's what you need to do:

Use @-ms-viewport in your CSS

@-ms-viewport{
	width: device-width;
}

Use the meta viewport tag

<meta name="viewport" content="width=device-width, initial-scale=1" />

And finally, in your <head>, add the following JavaScript

(function() {
	if ("-ms-user-select" in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/)) {
		var msViewportStyle = document.createElement("style");
		msViewportStyle.appendChild(
			document.createTextNode("@-ms-viewport{width:auto!important}")
		);
		document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
	}
})();

This code specifically targets version IE Mobile 10.0 – I've also added an extra condition to ensure it only happens in IE – so future, fixed versions will be untouched. It's worth noting that JavaScript cannot be disabled on Windows Phone 8, so this code will always run.

I've created a gist of the code on GitHub.

Interestingly, Rey Bango and I have discovered that due to a ”timing issue” the fix has to be called before any other scripts in the <head>, otherwise it won't work.

Tim Kadlec has also written about the fix.

Update: October 15 2013

Great news! Microsoft have fixed the viewport issue in WP8 Update 3 (GDR3).

Using device-width in a CSS @-ms-viewport rule now correctly renders pages at the device-width, instead of the resolution width.

Interestingly though, in this update IE's version number is still 10.0, despite Microsoft promising to update it so the recommended fix/workaround/hack would no longer apply. The fix doesn't have any side effects, however, so I'd recommend continuing to use it until this update is finalised and released publicly.

I'd like to thank Asbjørn for letting me know about the update.

Update: December 09 2014

Bad news! Microsoft have seemingly broken it again in IE11 on WP8.

This means that the original fix needs to be altered to remove the regex testing for 10.0.

(function() {
	if ("-ms-user-select" in document.documentElement.style && navigator.userAgent.match(/IEMobile/)) {
		var msViewportStyle = document.createElement("style");
		msViewportStyle.appendChild(
			document.createTextNode("@-ms-viewport{width:auto!important}")
		);
		document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
	}
})();