Ensuring that your site works great on Windows Phone 8 is easier than ever, thanks to extensive HTML5 support in Internet Explorer 10. You might currently use WebKit on a site specifically optimized to support iOS or Android. Now, it’s very easy to adapt a WebKit-optimized version of your site to support IE10. This means you’ll have less code to maintain and you’ll give your customers a better experience. Even better, with WebKit support for IE10, your site will be more compliant with HTML5 standards.
This guide walks through a collection of tips, best practices, and code samples to help make adapting your WebKit-optimized site for IE10 even easier. This guidance was compiled as our team worked with a number of popular sites across the web to adapt their own WebKit-optimized sites for IE10. We feel confident that this post addresses many of the updates you’ll need to make for your site as well.
Step 1: Detecting IE10 on Windows Phone 8
Step 2: Ensuring standards mode
Step 3: CSS and DOM API updates
Step 4: Updating touch and pointer events
Step 5: Handling nonstandard behaviors
Call to action
Step 1: Detecting Internet Explorer 10 on Windows Phone 8
If you’re running user-agent detection on your site, either on the client or server-side, the first step is to update that detection to treat Internet Explorer 10 the same as WebKit-based browsers. This gives you the baseline you need to start adapting the code to also support IE10. We have published some best practices about detecting IE10 using the user-agent, but for now here’s the user-agent string to expect for IE10:
Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; Touch; IEMobile/10.0;After this process is complete, if there still are differences between WebKit and IE10 that affect your site, try to adopt feature detection and other best practices for writing cross-browser code rather than user-agent detection. In particular, it’s very important to ensure that IE10 on Windows Phone 8 gets HTML5 video rather than Flash-based video.
As part of this, you should also update any third-party libraries, for example, jQuery Mobile, or other service providers to ensure that you get their latest browser support. For example, if you use Typekit, you’ll want to republish your custom font kit, or if you use Ooyala for video, you’ll need to update to their latest player.
Step 2: Ensuring standards mode
The next step is to double-check that Internet Explorer 10 will render your site in the most standards-compliant mode. Using standards mode provides the greatest support for the latest standards, such as HTML5, CSS3, SVG, and others, as opposed to some of the older modes such as “quirks mode” which are supported for backward compatibility. For most sites, this won’t require any work because standards mode is the default. The easiest way to be sure is to include the HTML5 doctype at the top of every page:
Standards mode also is the default for valid HTML 4.0+ and XHTML 1.0+ doctypes, as long as they don’t specify “Transitional”.
If you’re testing your web pages on a local network (or “localhost”), you will need to temporarily force standards mode because IE defaults into a backward-compatible mode for intranet sites. You can do this by adding the following tag to the tag of the page, or by adding the equivalent HTTP header:
After you have deployed the site to an internet domain you can remove the tag because it will no longer be needed.
Some examples of scenarios to avoid that would push your site out of standards mode are:
- Not including a doctype declaration at all. Instead, use the HTML5 doctype mentioned above.
- Specifying a “transitional” doctype. Instead, remove the Transitional keyword or adopt the HTML5 doctype.
- Forcing a specific IE mode using the x-ua-compatible header with IE=9 (or older version). Instead, specify IE=edge or remove the head completely and use the HTML5 doctype.
Step 3: CSS and DOM API updates
Now you’re ready to make some code updates. The simplest set of updates is to target any WebKit-specific CSS or JavaScript calls where there is a standards-compliant (unprefixed) or Microsoft-prefixed version that has the same behavior. Your site may already include a broad set of prefixes as a best practice. Beyond that, there may be a few other CSS updates or behavior differences that require a bit of refactoring.
Unprefixed properties
The first set of properties we’ll look at are unprefixed properties. These are CSS/DOM properties that initially shipped under the WebKit prefix (for example, with “-webkit”) but have since shipped in Internet Explorer 10 and other browsers in an unprefixed format. Fixing these up is as simple as making a copy of the line, and then removing the “-webkit” prefix on the copy. Adding these lines also will help provide support for other browsers which don’t use WebKit.
Note that this applies to CSS properties as well as the equivalent JavaScript calls. For example:
Before | After |
-webkit-border-radius: 0; | -webkit-border-radius: 0; border-radius: 0; |
a.webkitTransitionDuration = "5ms" | b.webkitTransitionDuration = b.transitionDuration = "5ms"; |
this.element.addEventListener("webkitTransitionEnd", this, false); | this.element.addEventListener("webkitTransitionEnd", this, false); this.element.addEventListener("transitionend", this, false); |
Here’s a listing of commonly used WebKit CSS properties and their standard (unprefixed) format supported in IE10. Each has an equivalent style property that can be accessed via JavaScript. For example, border-radius in CSS can also be accessed via object.style.borderRadius in JavaScript.
WebKit version | Standards-based version |
-webkit-animation | animation |
-webkit-animation-delay | animation-delay |
-webkit-animation-direction | animation-direction |
-webkit-animation-duration | animation-duration |
-webkit-animation-fill-mode | animation-fill-mode |
-webkit-animation-iteration-count | animation-iteration-count |
-webkit-animation-name | animation-name |
-webkit-animation-play-state | animation-play-state |
-webkit-animation-timing-function | animation-timing-function |
-webkit-background-clip | background-clip |
-webkit-background-size | background-size |
-webkit-border-radius | border-radius |
-webkit-border-bottom-left-radius | border-bottom-left-radius |
-webkit-border-bottom-right-radius | border-bottom-right-radius |
-webkit-border-top-left-radius | border-top-left-radius |
-webkit-border-top-right-radius | border-top-right-radius |
-webkit-box-shadow | box-shadow |
-webkit-box-sizing | box-sizing |
-webkit-background-clip | background-clip |
@-webkit-keyframes | keyframes |
-webkit-transform | transform |
-webkit-backface-visibility | backface-visibility |
-webkit-transition | transition |
-webkit-transition-property | transition-property |
-webkit-transition-duration | transition-duration |
-webkit-transition-timing-function | transition-timing-function |
webkitrequestanimationframe | requestAnimationFrame |
Other, less frequently used properties also are supported as unprefixed, such as CSS Multi-Column Layout.
Prefixed properties
The following WebKit-prefixed properties also have the same behavior in Internet Explorer 10 but require Microsoft vendor-prefixing (for example, with the prefix “-ms”) because the corresponding standards have not progressed far enough at the W3C to be unprefixed. You can read more about the Microsoft approach to this process here.
WebKit version | IE10 version |
-webkit-text-size-adjust | -ms-text-size-adjust |
-webkit-user-select | -ms-user-select |
-webkit-box | -ms-flexbox |
-webkit-box-align | -ms-flex-align |
-webkit-box-pack | -ms-flex-pack |
Gradients
The CSS gradients syntax has been updated during the standardization process. Specifically, the gradient type (for example, linear or radial) has moved to the property name, and there also are differences in how you specify the gradient line and colors. For the full details on the Internet Explorer 10 supported syntax for gradients, see Gradients (Windows). Recent versions of WebKit also support the same syntax, but if you targeted earlier versions of WebKit (using the “-webkit-gradient” prefix) you may need to make an update. For example:
Before | After |
background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#000000)); |
background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#000000)); background: linear-gradient(to bottom, #ffffff, #000000); |
Flexbox orientation
The syntax for setting Flexbox orientation has changed in Internet Explorer 10. For IE10 supported Flexbox syntax, see Flexible box ("Flexbox") layout (Windows). For example:
Before | After |
-webkit-box-orient: vertical; |
-webkit-box-orient: vertical; -ms-flex-direction: column; |
Borders around hyperlinked images
If an image is used as a hyperlink, by default Internet Explorer draws a blue highlight around the image to emphasize that this is a hyperlink; WebKit doesn’t do this. An easy way to turn this off is to explicitly specify no border for hyperlinked images using the following CSS:
a img {
border: none;
}
Border-image
Internet Explorer 10 doesn’t include support for CSS border-image. To preserve the layout of your page, a best practice is to specify a solid border-style fallback so border widths, padding, and margin are preserved. (If IE doesn’t find a supported border type, it will discard those values.) For example:
Before | After |
padding: 8px 0 8px; -webkit-border-image: url(border.png) 5 5 5 5 repeat repeat; border-width: 5px; |
border-style: solid; border-color: #fff; padding: 8px 0 8px; -webkit-border-image: url(border.png) 5 5 5 5 repeat repeat; border-width: 5px; |
Step 4: Updating touch and pointer events
WebKit and Internet Explorer 10 handle touch event handling differently. WebKit supports a touch interface that is separate from mouse handling; IE10 groups touch, mouse, and stylus into a single interface (pointer). The pointer event model also has been submitted to the W3C for standardization under the Pointer Events Working Group. Although they are different, the models are generally similar, so support for pointer events can generally be added with minimal code changes.
Adding pointer event listeners
The pointer API uses a standard “down, move, up” event model. Therefore, it’s simple to hook up listeners for existing event handlers to pointer events.
Before |
this.element.addEventListener("touchstart", eventHandlerName, false); this.element.addEventListener("touchmove", eventHandlerName, false); this.element.addEventListener("touchend", eventHandlerName, false); |
After |
if (window.navigator.msPointerEnabled) { |
Handling the pointer events
If all of the events are being handled by a single listener, for example, by the “eventHandlerName” value in the preceding example, you’ll need to separate them out into individual handlers based on the event type. These are easily mapped to existing handlers:
Before |
switch (event.type) { case "touchstart": this.onTouchStart(a); break; case "touchmove": this.onTouchMove(a); break; case "touchend": this.onTouchEnd(a); break; } |
After |
switch (event.type) { case "touchstart": case "MSPointerDown": this.onTouchStart(a); break; case "touchmove": case "MSPointerMove": this.onTouchMove(a); break; case "touchend": case "MSPointerUp": this.onTouchEnd(a); break; } |
Detecting the primary touch point
As noted earlier, the pointer event model fires separate events for each touch point. Therefore, if you only want to handle the primary touch point (for example, for a single-touch drag scenario), you will need to filter out non-primary touches using the following line at the beginning of your “up” and “move” event handlers:
if (window.navigator.msPointerEnabled && !event.isPrimary) return;
Retrieving the coordinates
The pointer event model fires separate events for each touch point, so there is no need to retrieve a specific index from the touches collection. The coordinates are exposed directly from the “event” object using the pageX and pageY properties. This can easily be incorporated into existing code as follows:
Before |
var curX = event.targetTouches[0].pageX; |
After |
var curX = event.pageX || event.targetTouches[0].pageX; |
Handling mouse input
One advantage of the Internet Explorer 10 model is that mouse input is handled with the same events! Because of this, IE10 fires “move” events when the mouse is hovering over the area. In scenarios such as single-touch drag, you would want that event only if the mouse button is held down while the user is moving the mouse. You can detect that at the beginning of your move event handler by using the pointerType property as follows:
if (window.navigator.msPointerEnabled && ((event.pointerType == evt.MSPOINTER_TYPE_TOUCH && event.buttons != 1) || !a.isPrimary)) return;
Turning off default touch behavior
The pointer event model in Internet Explorer 10 requires you to explicitly indicate which areas of the page will have custom gesture handling (using the code you just added), and which will use default gesture handling (pan the page). You can do this by adding markup on elements that should opt out of default gesture handling using the -ms-touch-action property. For example:Before |
After |
In addition to none, IE10 on Windows Phone 8 also supports the pan-x and pan-y properties, which specify that the browser should handle horizontal or vertical gestures, and custom JavaScript handlers should handle everything else.
Step 5: Handling nonstandard behaviors
A final category of updates is related to scenarios that don’t have an associated W3C standard; WebKit and Internet Explorer 10 approaches are different. In all of these cases, the WebKit and IE10 solutions can coexist on a site without any problems.
Disabling link highlighting
Some mobile browsers, including Safari on iOS and Internet Explorer on Windows Phone, display a translucent highlight when elements with hyperlinks are tapped, to provide additional feedback to the user. However, many sites want to disable this default behavior to have greater control over the look and feel of their site.
WebKit solution | IE10 solution |
a { -webkit-tap-highlight-color: rgba(0,0,0,0); } |
Note that the msapplication-tap-highlight tag only needs to be applied once in the of the page and applies to the entire page. The tag is specific to Internet Explorer 10 on Windows Phone, and does not apply to Internet Explorer 10 on Windows.
Disabling native styling for drop-down lists
The “-webkit-appearance” CSS property defines WebKit-specific behaviors to change the appearance of controls to resemble native controls. In many cases, this is the default behavior in Internet Explorer 10 and therefore isn’t required.
However, one specific, commonly used scenario for “-webkit-appearance” is to disable the drop-down arrow that appears on elements so it can be styled with a custom look such as a background image. When the arrow is removed, the text-indent value usually is set to ensure that the text of the drop-down list items doesn’t show up on the page. (However, it will show up in the control that pops up when it is tapped). Here’s how to achieve the same effect in IE10:
WebKit solution | IE10 solution |
CSS: select { -webkit-appearance: none; text-indent: -5000px; } | CSS: select::-ms-expand { display: none; } HTML (empty top option to remove text): |
Call to action
This guide covers the most common changes required to make your WebKit-optimized site work great on Internet Explorer 10 and other standards-compliant browsers. If you have other tips that aren’t covered, please share them in the comments!
In many cases, the actual code changes to your site will be minimal, depending on the features being used on your site, and on existing best practices used in your code. So go ahead and make the best your site has to offer available to Windows Phone 8 users!