воскресенье, 26 февраля 2012 г.

IE 9.0.5 Available via Windows Update

The February 2012 Cumulative Security Update for Internet Explorer is now available via Windows Update. This security update resolves 5 privately reported vulnerabilities in Internet Explorer. The most severe vulnerabilities could allow remote code execution if a user visits a specially crafted Web page using Internet Explorer. An attacker who successfully exploited any of these vulnerabilities could gain the same user rights as the local user.  Users whose accounts are configured to have fewer user rights on the system could be less affected than users who operate with administrative user rights.
This security update is rated Critical for Internet Explorer Windows Clients, except IE6 client, where it is rated Moderate; and Moderate for Internet Explorer on Windows servers, except IE6, where it is not rated. For more information, see the full bulletin.
Most customers have enabled automatic updating and do not need to take any action. We recommend that customers, who have not enabled automatic updating, enable it (Start Menu, type “Windows Update”). We recommend that administrators, enterprise installations, and end users who want to install this security update manually, apply the update immediately using update management software or by checking for updates using the Microsoft Update service.
—Ceri Gallacher, Program Manager, Internet Explorer

HTML5 Love is in the Air!

To help celebrate Valentine’s Day, we’re pleased to offer another new HTML5 experience that makes the most of your PC hardware and touch on Windows 8. Check out Love is in the Air and feel the warm embrace of hardware accelerated HTML5.
This experience brings together hardware-accelerated HTML5 canvas, SVG, CSS transforms & transitions, WOFF, audio, and more. On Windows Developer Preview with support for multi-touch in IE10, you can reach out and swipe to reveal a special message of love -or just use your mouse. If you think your browser can keep up, turn up the volume to 1000 floating hearts. Using another browser and not feeling the love? Try it with IE9 (or IE10) using the hardware acceleration built into the browser.
Screen shot of Love is in the Air demo. Click the image to "Feel the love."
Click the image to feel the love
Demos like this are best when shared, so we made it easy for you to experience Love is in the Air and send a special message to your friends.
From the entire IE team, we want to share the love for HTML5 and wish you a Happy Valentine’s Day.
—Rob Mauceri, Group Program Manager, Internet Explorer

Sub-pixel Rendering and the CSS Object Model

With Windows 8, you have an unprecedented choice of devices for browsing the Web, from large desktop screens to small slates. In order to accommodate this range of devices, the browser must be able to scale and layout the Web at many different screen sizes and dimensions. We've previously blogged about some of the features in IE that support these scenarios. Sub-pixel positioning (of text and layout) is one of the core platform technologies which enable Web pages to look beautiful and consistent at any scale.
In this post, we describe changes made in IE10 to better support sub-pixel positioning through the CSS-OM.
Web developers can build beautiful layouts through a variety of platform technologies. Generally, developers use CSS style sheets to describe the layout a Web site. In some scenarios, Web developers also depend on JavaScript code to measure, align, or position elements of a Web page with pixel-perfect precision. For example, some online editors carefully position an edit box exactly over the top of existing content so that it only appears as if you are directly editing the existing content. Scenarios such as this one may use the CSS object model (CSS-OM) APIs to read and/or set element position. The CSS-OM is a set of JavaScript APIs for programmatically manipulating CSS.
Measuring and aligning layout elements using the CSS-OM APIs can be problematic because of the way that those APIs round or truncate sub-pixel positioned values to whole-pixel numbers.

A Quick Note about Pixel-perfect Layouts

In general, pixel-perfect layouts on the Web tend to conflict with the goals of enabling accessible, compatible, and adaptable content, and consequently are not a best practice. The following collage illustrates some of the bugs that can occur when the Web designer attempts to create a pixel-perfect design but unexpected Web platform differences cause their designs to go awry.
Examples of pixel-perfect designs gone wrong
Examples of pixel-perfect designs gone wrong
When using the CSS-OM to dynamically generate a layout, Web developers should allow for a few pixels of potential error. Better yet, IE10 provides several new layout options that developers can use to better achieve many of these desired layouts without requiring pixel-perfect alignment using the CSS-OM.

An Illustration

To illustrate how the CSS-OM APIs may cause subtle positioning problems, consider a simple example. Sub-pixel positioning allows four boxes to be evenly distributed inside of the container, despite the container's size not being evenly divisible by four.
Consider the following HTML markup fragment:
<footer>
<div>content 1div><div>content 2div><div>content 3div><div>content 4div>
footer>
with this partial CSS markup:
footer { width: 554px; border: 1px solid black; text-align: center; }
footer div { display: inline-block; width: 25%; }
footer div:nth-child(even) { background-color: Red; }
footer div:nth-child(odd) { background-color: Orange; }
Now, let’s add a function that runs on load and reports the widths of these items:
onload = function () {
var footerBoxes = document.querySelectorAll("footer div");
var s = "";
var totalSize = 0;
for (var i = 0; i < footerBoxes.length; i++) {
// Reporting
var offsetWidth = footerBoxes[i].offsetWidth;
s += "content " + (i + 1) + " offsetWidth = " + offsetWidth + "px" + "
"
;
totalSize += offsetWidth;
}
s += "Total calculated offsetWidth = " + totalSize + "px" + "
"
;
s += "Container width = " + document.querySelector("footer").clientWidth + "px" + "
"
;
document.querySelector("#message").innerHTML = s;
}
The result of running this markup and code in IE9 is something like this:
content 1content 2content 3content 4 content 1 offsetWidth = 139
content 2 offsetWidth = 139
content 3 offsetWidth = 139
content 4 offsetWidth = 139
Total calculated offsetWidth = 556
Actual container width = 554

Note that summing the values returned by the CSS-OM API offsetWidth results in the total calculated offsetWidth differing from the actual container width by two pixels, due to rounding that occurs in the offsetWidth of the individual div elements.
The results in other browsers show a similar discrepancy, though sometimes the total is less than the actual and sometimes greater.
When the rounding/truncation leads to a sum total that overflows the container size (as illustrated), content will start to wrap or cause unwanted scroll-bars to appear. Additionally, many containers are sized according to the text and the font used to render the text, and those font metrics may be different across browsers or alternate fonts may be selected if the requested font isn't available.
The offsetWidth API, along with many other widely used CSS-OM properties (most dating back to IE4 in 1997), provide a convenient and fast way to extract integer pixel values for an element from a variety of different coordinate systems. All major browsers implement most of these APIs for compatibility and they are also part of the CSS-OM View module, a W3C draft standard.
New browser features continue to demonstrate the shortfall of limiting CSS-OM properties to whole-value pixels. For example, features like SVG and CSS 2D/ 3D Transforms allow an element's dimensions to easily fall between pixels.

Addressing the Problem

Recognizing this limitation (in part), the W3C CSS-OM View spec describes the coordinates returned via the getBoundingClientRect() API to be floats; in other words, in values that can represent sub-pixel precision. (getBoundingClientRect() is another CSS-OM API that provides an element's bounding-box position and dimension using the same origin as the offsetWidth API.)
In IE10 we've updated the getBoundingClientRect() API to return sub-pixel resolution by default in IE10 standards mode in order to be interoperable with other browsers and align with the W3C standard.
Updating our example above to report the width component of the rectangle returned by getBoundingClientRect(), IE10 now reports these fractional values:
content 1content 2content 3content 4 content 1 offsetWidth = 139, getBoundingClientRect().width = 138.5
content 2 offsetWidth = 139, getBoundingClientRect().width = 138.5
content 3 offsetWidth = 139, getBoundingClientRect().width = 138.5
content 4 offsetWidth = 139, getBoundingClientRect().width = 138.5
Total calculated offsetWidth = 556
Total calculated getBoundingClientRect().width = 554
Actual container width = 554

Taking Sub-pixel Values Everywhere

In addition to getBoundingClientRect, we also report sub-pixel position for mouse/pointer events in IE10 standards mode by default. It's only possible for the mouse/pointer to land between pixels when the zoom factor is set to a value other than 100%. Specifically, the affected mouse/pointer APIs are:
  • MouseEvent.offsetX/Y
  • MouseEvent.layerX/Y
  • MouseEvent.clientX/Y
  • MouseEvent.pageX/Y
  • MouseEvent.x/y
To continue our commitment to compatibility with legacy Web pages (pages which may not be prepared to handle sub-pixel values from the CSS-OM in general), IE10 continues to reports whole-value pixel units by default for the other CSS-OM properties. These APIs are:
  • Element.clientHeight
  • Element.clientWidth
  • Element.clientLeft
  • Element.clientTop
  • Element.scrollTop
  • Element.scrollLeft
  • Element.scrollWidth
  • Element.scrollHeight
  • HTMLElement.offsetWidth
  • HTMLElement.offsetHeight
  • HTMLElement.offsetTop
  • HTMLElement.offsetLeft
  • TextRange.offsetLeft
  • TextRange.offsetTop
However, if necessary, IE10 now allows Web developers to enable sub-pixel positioned values from the above-listed CSS-OM properties as well. Use of this special feature requires that the site run in IE10 Standards mode and opt-in by setting the following property on the document object:
document.msCSSOMElementFloatMetrics = true;
When enabled by setting document.msCSSOMElementFloatMetrics to true, all CSS-OM APIs in the previous list will begin reporting their values in sub-pixel precision that will reflect exactly the calculations used internally by the layout and rendering engine. Note that JavaScript will convert 1.00 into 1 so you may not always see a decimal point in returned values.
Going back to our example and setting document.msCSSOMElementFloatMetrics to true results in this in IE10:
content 1content 2content 3content 4 content 1 offsetWidth = 138.5, getBoundingClientRect().width = 138.5
content 2 offsetWidth = 138.5, getBoundingClientRect().width = 138.5
content 3 offsetWidth = 138.5, getBoundingClientRect().width = 138.5
content 4 offsetWidth = 138.5, getBoundingClientRect().width = 138.5
Total calculated offsetWidth = 554
Total calculated getBoundingClientRect().width = 554
Actual container width = 554

Note the fractional values returned by offsetWidth and that all totals now match.

Summary

It is sometimes helpful (and, in rare cases, necessary) to be able to use the CSS-OM properties for pixel-perfect layout calculation. When using the CSS-OM, be aware of the whole-pixel-reporting characteristics of those APIs. When designing layouts either with CSS or the CSS-OM APIs, be sure to accommodate a few pixels of tolerance in order to ensure a more robust site across multiple browsers and/or devices.
—Travis Leithead, Program Manager, Internet Explorer
Editor's note: Updated to correct a few typographic errors.

Google Bypassing User Privacy Settings

When the IE team heard that Google had bypassed user privacy settings on Safari, we asked ourselves a simple question: is Google circumventing the privacy preferences of Internet Explorer users too? We’ve discovered the answer is yes: Google is employing similar methods to get around the default privacy protections in IE and track IE users with cookies. Below we spell out in more detail what we’ve discovered, as well as recommendations to IE users on how to protect their privacy from Google with the use of IE9's Tracking Protection feature. We’ve also contacted Google and asked them to commit to honoring P3P privacy settings for users of all browsers.
We’ve found that Google bypasses the P3P Privacy Protection feature in IE. The result is similar to the recent reports of Google’s circumvention of privacy protections in Apple’s Safari Web browser, even though the actual bypass mechanism Google uses is different.
Internet Explorer 9 has an additional privacy feature called Tracking Protection which is not susceptible to this type of bypass. Microsoft recommends that customers who want to protect themselves from Google’s bypass of P3P Privacy Protection use Internet Explorer 9 and click here to add a Tracking Protection List. Customers can find additional lists and information on this page.

Background: Google Bypassing Apple’s Privacy Settings

A recent front page Wall Street Journal article described how Google “bypassed Apple browser settings for guarding privacy.” The editor and CEO of Business Insider, a business news and analysis site, summarized the situation:
Google secretly developed a way to circumvent default privacy settings established by a… competitor, Apple… [and] Google then used the workaround to drop ad-tracking cookies on the Safari users, which is exactly the sort of practice that Apple was trying to prevent.
Third-party cookies are a common mechanism used to track what people do online.  Safari protects its users from being tracked this way by a default user setting that blocks third-party cookies.  Here’s Business Insider’s summary:
What Safari does NOT allow, by default, is for third-party … cookies on users' computers without their permission. It is these ad-tracking cookies that cause lots of Internet users to freak out that their privacy is being violated, so it's understandable that Apple decided to block them by default.
But these default settings have created a problem for Google, at least with respect to its goals for its advertising business.
Google’s approach to third-party cookies seems to have the side effect of Safari believing they are first-party cookies.

What Happens in IE

By default, IE blocks third-party cookies unless the site presents a P3P Compact Policy Statement indicating how the site will use the cookie and that the site’s use does not include tracking the user. Google’s P3P policy causes Internet Explorer to accept Google’s cookies even though the policy does not state Google’s intent.
P3P, an official recommendation of the W3C Web standards body, is a Web technology that all browsers and sites can support. Sites use P3P to describe how they intend to use cookies and user information. By supporting P3P, browsers can block or allow cookies to honor user privacy preferences with respect to the site’s stated intentions.
It’s worth noting that users cannot easily access P3P policies. Web sites send these policies directly to Web browsers using HTTP headers. The only people who see P3P descriptions are technically skilled and use special tools, like the Cookie inspector in the Fiddler tool. For example, here is the P3P Compact Policy (CP) statement from Microsoft.com:
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
Each token (e.g. ALL, IND) has a specific meaning for a P3P-compliant Web browser. For example, ‘SAMo’ indicates that ‘We [the site] share information with Legal entities following our practices,’ and ‘TAI’ indicates ‘Information may be used to tailor or modify content or design of the site where the information is used only for a single visit to the site and not used for any kind of future customization.’ The details of privacy are complex, and the P3P standard is complex as well. You can read more about P3P here.
Technically, Google utilizes a nuance in the P3P specification that has the effect of bypassing user preferences about cookies. The P3P specification (in an attempt to leave room for future advances in privacy policies) states that browsers should ignore any undefined policies they encounter. Google sends a P3P policy that fails to inform the browser about Google’s use of cookies and user information. Google’s P3P policy is actually a statement that it is not a P3P policy. It’s intended for humans to read even though P3P policies are designed for browsers to “read”:
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
P3P-compliant browsers interpret Google’s policy as indicating that the cookie will not be used for any tracking purpose or any purpose at all. By sending this text, Google bypasses the cookie protection and enables its third-party cookies to be allowed rather than blocked. The P3P specification (“4.2 Compact Policy Vocabulary”) calls for IE’s implemented behavior when handling unknown tokens: “If an unrecognized token appears in a compact policy, the compact policy has the same semantics as if that token was not present.”
Similarly, it’s worth noting section “3.2 Policies” from the P3P specification:

3.2 Policies

In cases where the P3P vocabulary is not precise enough to describe a Web site's practices, sites should use the vocabulary terms that most closely match their practices and provide further explanation in the CONSEQUENCE field and/or their human-readable policy. However, policies MUST NOT make false or misleading statements.
P3P is designed to support sites that convey their privacy intentions. Google’s use of P3P does not convey those intentions in a manner consistent with the technology.
Because of the issues noted above, and the ongoing development of new mechanisms to track users that do not involve cookies, our focus is on the new Tracking Protection technology.

Next Steps

After investigating what Google sends to IE, we confirmed what we describe above. We have made a Tracking Protection List available that IE9 users can add by clicking here as a protection in the event that Google continues this practice. Customers can find additional lists and information on this page.
The premise of Tracking Protection in IE9 is that tracking servers never have the opportunity to use cookies or any other mechanism to track the user if the user never sends anything to a tracking server. This logic underlies why Tracking Protection blocks network requests entirely. This new technology approach is currently undergoing the standardization process at the W3C.
This blog post has additional information about IE’s cookie controls, and shows how you can block all cookies from a given site (e.g. *.google.com) regardless of whether they are first- or third-party. This method of blocking cookies would not be subject to the methods Google used. We recommend that users not yet running IE9 take steps described in this post.
Given this real-world behavior, we are investigating what additional changes to make to our products. The P3P specification says that browsers should ignore unknown tokens. Privacy advocates involved in the original specification have recently suggested that IE ignore the specification and block cookies with unrecognized tokens. We are actively investigating that course of action.
―Dean Hachamovitch, Corporate Vice President, Internet Explorer

Protecting Consumers’ Privacy Online

This morning in the United States, the White House announced a new “Consumer Privacy Bill of Rights” as part of the effort to improve consumers’ online privacy. As I’ve mentioned before, Microsoft is actively participating in the industry initiative for Tracking Protection at the W3C to produce Web standards for online privacy.
The Tracking Protection Working Group is chartered to work on two complementary initiatives: Tracking Preference Expression (Do Not Track) and Tracking Selection Lists (TSL). The TSL editor’s draft defines a format for interchangeable lists for blocking or allowing tracking elements from Web pages. Last month, at the W3C face-to-face meeting, the working group decided that a sub-group (or “task force”) of those interested in TSLs should work on the specification together.
Work on Do Not Track (DNT) is continuing and the W3C expects this to become a standard sometime in 2012. In the meantime, IE’s Tracking Protection feature is available to IE9 and IE10 users today. This is the only technology that can filter out unwanted cookies, beacons, and other tracking devices without requiring Web sites, advertisers, and publishers to change.
At the CPDP 2012 conference in Brussels, Simon Davies and Alexander Hanff of Privacy International launched two new tracking protection lists designed to protect consumers from Web Analytics and Behavioural Tracking. These lists are available from http://www.privacyonline.org.uk/. Check out the complete set of Tracking Protection Lists available from the IE Gallery (including the popular EasyPrivacy and Fanboy lists).
--Adrian Bateman, Program Manager, Internet Explorer

понедельник, 13 февраля 2012 г.

High performance HTML5 content in Metro-style Apps

Metro style apps in Windows 8 have all the performance benefits of IE10 when showing Web content. In Metro style apps, Web content is always JIT compiled and hardware-accelerated. Other platforms do not provide the same level of performance in apps. For example, Cocoa apps on iOS offer significantly worse JavaScript performance (via the UIWebView control) than the same content running in Safari. These Cocoa apps do not enjoy JIT compilation, and these apps cannot show and use Web content the same way the browser on the system can:
Chart showing that Web content in an Apple iOS app is over 3 times slower than the same content in Apple Safari on the same device.
Testing configuration: http://www.webkit.org/perf/sunspider/sunspider.html.
iPad: 1st Gen, iOS 5.0.1.
Windows 8: Developer Preview, Dell Optiplex 745, 64-bit OS.
Kindle Fire v1.

Why is this important?

Many applications embed HTML to provide a richer and always up to date experience for consumers. For example, the developer of a restaurant guide app might want to include a live map showing the locations of the list of restaurants the user is choosing from. If you write an app on iOS, common actions like panning and zooming the map will run twice as slow in an app compared with Safari.
Anyone writing a Metro style app for Windows 8 can easily include Web content in their app. In an HTML or XAML app, just include an

CORS for XHR in IE10

The fourth platform of IE10 simplifies building cross-site scenarios that work consistently across browsers by supporting Cross-Origin Resource Sharing (CORS) for XMLHttpRequest (XHR). CORS for XHR makes sharing data across sites simple and flexible. In the most basic scenario CORS enables creating data sources accessible from any site, and with a few small tweaks you can choose to constrain allowed sites, support data modification, and even allow authentication. Most importantly CORS keeps existing sites secure by requiring server participation.

Simple Cross-Origin XHR

Let’s look at how a cross-origin XHR request compares to a same-origin request. From script, the only difference is the URL passed to the open method. For example, say we’re working on a script that fetches a list of photo albums.

Traditional XHR

// Script running on http://photos.contoso.com
var xhr = new XMLHttpRequest();
xhr.onerror = _handleError;
xhr.onload = _handleLoad;
xhr.open("GET", "/albums", true);
xhr.send();
Now we want to access the list of albums from another origin. The other origin can be a completely different domain or a different host with the same base domain. Either way, just pointing at the full URL from another site is enough to get the browser to automatically send a CORS request.

CORS-Enabled XHR

// Script running on http://www.contoso.com
var xhr = new XMLHttpRequest();
xhr.onerror = _handleError;
xhr.onload = _handleLoad;
xhr.open("GET", "http://photos.contoso.com/albums", true);
xhr.send();
Sites can provide fallback for older browsers by wrapping this in feature detection. Checking for “withCredentials” is the best approach since it directly relates to CORS support for XHR.

CORS-Enabled XHR with Feature Detection

// Script running on http://www.contoso.com
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.onerror = _handleError;
xhr.onload = _handleLoad;
xhr.open("GET", "http://photos.contoso.com/albums", true);
xhr.send();
} else {
// Fallback behavior for browsers without CORS for XHR
}
At this point our client code makes a CORS request directly to "http://photos.contoso.com", but the request fails to return any data. The failure occurs because the server isn’t participating yet. Taking a quick look at the developer tools gives us an idea what went wrong.
Screenshot showing the F12 tools indicating no 'Access-Control-Allow-Origin' header was found.
Here we can see the server needs to send an “Access-Control-Allow-Origin” header in the response. In our scenario we’re not opening up our albums for any site to access, but want to enable access solely from “http://www.contoso.com”. Doing this requires allowing the server to identify where the request originated. Examining our outgoing request reveals a new header containing precisely this information, “Origin”.

Simple CORS Request Headers

GET http://photos.contoso.com/albums HTTP/1.1
Origin: http://www.contoso.com
...
Using this information the server can choose to limit access to any set of sites. If the server always adds an “Access-Control-Allow-Origin” header with a value of '*' then all sites will have access. For our scenario, we’ll have the server verify the origin and then set “Access-Control-Allow-Origin” to allow only “http://www.contoso.com”.

Simple CORS Response Headers

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.contoso.com
...
With the above updates in place, our “http://www.contoso.com” client can now access album lists from the server at “http://photos.contoso.com”.

Cross-Origin XHR with Preflight

The “simple” CORS requests discussed so far are great for basic, read-only scenarios, like downloading a photo album. Taking the next step by modifying data across sites requires a bit more work on the server. For example, say we’re adding code in the client to create a new album.
var xhr = new XMLHttpRequest();
xhr.onerror = _handleError;
xhr.onload = _handleLoad;
xhr.open("PUT", "http://photos.contoso.com/albums", true);
xhr.send(JSON.stringify({ name: "New Album" }));
Running this as-is doesn’t work. Examining the network traffic reveals a request is sent, but not the one we expected.
Screenshot of the F12 tools showing an OPTIONS preflight request.
What the browser actually sent is known as a preflight request. Preflight requests are sent before requests that may result in data modification on the server. Such requests are identified by the presence of non-simple properties as defined in the CORS specification. These properties range from certain HTTP methods like “PUT” to custom HTTP headers. Browsers send preflight requests to ask the server for permission to send the actual request. In our example the browser is verifying a “PUT” request is allowed.

Preflight Request

OPTIONS http://photos.contoso.com/albums HTTP/1.1
Origin: http://www.contoso.com
Access-Control-Request-Method: PUT
...
Getting the browser to send the actual request requires some changes on the server. Once again we can take a look at the developer tools for more information.
Screenshot showing the F12 tools indicating no 'Access-Control-Allow-Methods' list was found.
The first step is to make the server recognize the “OPTIONS” preflight request as distinct from other requests for the same URL. After the server verifies the preflight request by ensuring “Access-Control-Request-Method” is asking for “PUT” from an allowed origin, it sends the appropriate approval via the “Access-Control-Allow-Methods” header.

Preflight Response

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.contoso.com
Access-Control-Allow-Methods: PUT
...
Once preflight is out of the way and approved the actual request takes place.

Actual Request

PUT http://photos.contoso.com/albums HTTP/1.1
Origin: http://www.contoso.com
...
Adding the album is technically complete at this point, but our client code won’t know that unless the server responds correctly. Specifically the server must still include “Access-Control-Allow-Origin” in the response.

Actual Response

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.contoso.com
...
With that the client can add a new album cross-origin and recognize whether or not the action completed successfully.

Next Steps

Pairing CORS with other new platform features enables interesting scenarios. One example is the Cross-Site Upload Test Drive which tracks cross-origin file uploads using CORS, XHR, FileAPI, and progress events.
—Tony Ross, Program Manager, Internet Explorer

воскресенье, 5 февраля 2012 г.

CSS3 3D Transforms in IE10

CSS3 features make it easier to build rich and immersive Web experiences. A recent post described how Web developers add personality to their sites with CSS3 Transitions and Animations. CSS3 3D Transforms add another dimension (literally) for developers to enhance their sites. For example, the Windows 8 Metro style Start page uses subtle 3D transforms to highlight pressed tiles, as shown below.
Internet Explorer 10 tile shown not pressed (left) and pressed (right)
Internet Explorer 10 tile shown not pressed (left) and pressed (right)

Adding a 3rd Dimension to CSS Transforms

Like CSS3 2D Transforms, 3D Transforms provides functions and values for the CSS transform and transform-origin properties that apply geometric transformations operations to HTML elements. CSS 3D Transforms extends the transforms functions to enable 3D transforms. The rotate(), scale(), translate(), skew(), and matrix() transform functions are expanded to encompass the 3D space with a z-coordinate parameter—or in the case of matrix3d(), an extra 10 parameters—and by spawning additional transform functions, for example, rotateZ() and scaleZ().
A new perspective transform function gives transformed elements depth by making distant points appear smaller.
CSS3 3D Transforms also adds a few new CSS properties. In addition to the transform and transform-origin properties, IE10 supports vendor-prefixed perspective, perspective-origin, backface-visibility, and the flat value of transform-style.
Note: The markup examples in this post all use unprefixed properties as defined in the W3C standard. However, at this time all browsers that implement these features do so with vendor-specific prefixes. Please remember to add your browser’s prefix to the example markup when experimenting.

Perspective

The perspective transform function is important for 3D transforms. It sets the viewer’s position and maps the viewable content onto a viewing pyramid, which it subsequently projects onto a 2D viewing plane. Without specifying perspective, all points in z-space are flattened onto the same 2D plane and there is no perception of depth in the resulting transform. For some transforms, such as the translation along the Z-axis shown below, the perspective transform function is essential for visibly seeing any effect from the transform.
In the examples below  is the original, untransformed element and  is the transformed element
Example of transform: perspective(500px) translate(0px, 0px, -300px); Example of transform: translate(0px, 0px, -300px);
transform: perspective(500px) translate(0px, 0px, -300px); transform: translate(0px, 0px, -300px);
 
transform: perspective(500px) rotateY(30deg); Example of transform: rotateY(30deg);
transform: perspective(500px) rotateY(30deg); transform: rotateY(30deg);
A shortcut for adding the perspective transform to several elements is to use the perspective property on their parent element(s). The perspective property applies the perspective transform to each of its child elements:
Example of two divs transformed by the same parent perspective property.
#parent {
perspective: 500px;
}

#div1 {
position: absolute;
transform-origin: 0px 0px;
transform: rotateY(30deg);
}

#div2 {
position: absolute;
transform-origin: 0px 0px;
transform: rotateY(30deg) translate(220px);
}
The perspective-origin property can also be used in conjunction with perspective to shift the viewpoint away from the center of the element:
Illustration of the perspective-depth property.
Below, you can see that shifting the perspective origin to the left makes the content to the right of the original perspective origin appear farther away.
Example of two divs transformed by the same parent perspective-depth property.
#parent {
perspective: 500px;
perspective-origin: -300px 0px;
}

backface-visibility

The backface-visibility property is useful for hiding the backface of content. By default, the backface is visible and the transformed content can be seen even when flipped. But when backface-visibility is set to hidden, content is hidden when the element is rotated such that the front side is no longer visible. This can be useful if you want to simulate an object with multiple sides, such as the card used in the example below. By setting backface-visibility to hidden, it’s easy to ensure that only the front-facing sides are visible.
CSS markup:
.card, .card div {
position: absolute;
width: 102px;
height: 143px;
}

.card div:nth-child(1) {
background-image: url('redback.png');
}

.card div:nth-child(2) {
background-image: url('8clubs.png');
backface-visibility: hidden;
}
HTML markup for one card:
<div class="card"><div>div><div>div>div>
Creating six cards as defined above and giving each a style="transform: rotateY(ndeg)" property with a different rotation value n, results in this:
Sequence of 6 cards rotating from front to back.
rotateY(0deg); rotateY(36deg); rotateY(72deg); rotateY(108deg); rotateY(144deg); rotateY(180deg);
What’s happening in this example is that when there’s no rotation, you see the second div, the 8 of clubs—because it’s the one on top in drawing order. As we apply a rotation to the card and pass 90 degrees, the backface-visibility: hidden; property of the second div causes it to become invisible thereby exposing the first div, the card back.

3D Transforms with Animations and Transitions

Best of all, you can even use 3D transforms in conjunction with CSS transitions and animations. If you are using IE10 or another browser that supports CSS3 Animations of CSS3 3D Transforms, try this example of scrolling text, built by animating the transform property.
This is the CSS markup that achieves the effect shown in screen shots below.
#parentDiv {
perspective: 500px;
perspective-origin: 150px 500px;
}

#div1 {
transform-origin: 150px 500px;
animation: scrollText 200s linear infinite;
}

@keyframes scrollText {
0% { transform: rotateX(45deg) translateY(500px); }
100% { transform: rotateX(45deg) translateY(-8300px); }
}
Early frame from the demo that animates scrolling text with 3D transforms. Later frame from the demo that animates scrolling text with 3D transforms.

Try It Today

Try this out in IE10 on the Windows Developer Preview. The test drive demo Hands On: 3D Transforms can help visualize the possibilities that CSS 3D Transforms enables.
We’d love to see your creations!
—Jennifer Yu, Program Manager, Internet Explorer Graphics

среда, 1 февраля 2012 г.

Creating Files through BlobBuilder

As Web sites transition more and more into Web applications, working with files in meaningful ways is becoming increasingly important. Starting with Platform Preview 2, IE10 includes support for the File API, enabling developers to read and slice files on the client. Platform Preview 4 adds support for BlobBuilder, a way for developers to create new files. IE10 also has two new methods that allow the user to save blobs to their computer, enabling great end-to-end experiences when working with client-resident data.
Over on the IE Test Drive, we have a fun piano demo showing off BlobBuilder and File API capabilities. When you press notes on the piano, the site constructs two files: an mp3 music file and an SVG file of the musical score. You can see how the size of both files change each time you press a note. Press the play button to listen to your song, or download either the music file or the SVG score file by pressing the links just above the piano keys. In the rest of this blog post I’ll go through how the demo works, focusing on the capabilities of BlobBuilder and File API.
Screen shot of the BlobBuilder piano-playing Test Drive demo.

BlobBuilder Capabilities

BlobBuilder, like the name implies, is a way to build blobs on the client. The main method to do this is append. The append function accepts three data types:
  • Blob objects
  • Plain text
  • Array Buffers
The piano demo creates the mp3 file by appending blobs together, using one blob for each note. The demo creates the SVG file of the musical score by appending text that contains the SVG source.
getBlob is another method available on the BlobBuilder object which returns a blob object containing all the items previously appended. Here is a very simple example that uses BlobBuilder to create a text file:
// The BlobBuilder constructor is prefixed in all browsers.
// Use MSBlobBuilder in IE, MozBlobBuilder in Firefox, and WebKitBlobBuilder in WebKit-based browsers.
var bb = new MSBlobBuilder();

bb.append("Hello World!");
var blob1 = bb.getBlob("text/plain");
One thing to note about the getBlob method is that when you call getBlob in IE10 and Firefox, it will clear out the contents of the BlobBuilder object, so the next time you call append it will be as if you were appending into a new BlobBuilder object. WebKit does not currently clear out the contents of the BlobBuilder after calling getBlob. Consider this example:
var bb = new MSBlobBuilder();
bb.append("Hello World!");
var blob1 = bb.getBlob("text/plain");
bb.append("BlobBuilder is great");
var blob2 = bb.getBlob("text/plain");
In all browsers, blob1 will contain the text “Hello World!”. However, blob2 will be different. In IE10 and Firefox, blob2 will contain the text “BlobBuilder is great” while in WebKit-based browsers it will contain the text “Hello World!BlobBuilder is great”. This discrepancy is still under discussion in the Web Applications working group.

Getting Blobs via XHR

The File API makes it easy to access files selected by the user, something I demonstrated in the Magnetic Poetry demo. This is great when you want to incorporate the users own data into your site. However, in the piano demo, I needed the note files to be built into the demo. When you want to work with blobs but you want to supply the data, you can use XHR.
New to IE10 is the XHR responseType property. The responseType property supports four values: blob, array buffer, text, and document. In the piano demo’s initialization method - getBlobs() - you’ll see the following:
var req = new XMLHttpRequest();
var url = 'PianoNotes/AllNotes2.mp3';
req.open('GET', url, false);
req.responseType = "blob";
req.onload = function () { /* ... */ };
req.send(null);
One thing you may notice is that the demo only makes a single XHR request. It only downloads one file which contains all the notes used in the demo. However, when you press a key in the demo, only a single note plays and the site appends only a single note to the mp3 file. To make that work, after downloading the file containing all the notes, the site slices the file using the File API slice method and extracts 24 individual notes. This is a great performance savings versus having to download 24 individual files.

Creating the Music File

Once I have a blob for each note in the demo, creating the mp3 file is easy. Each time you press a key I call:
musicBlobBuilder.append(noteBlob);
In order to update the file size, I get the blob and then get the file size.
var musicBlob = musicBlobBuilder.getBlob("audio/mp3");
// display musicBlob.size
Lastly because I know that the BlobBuilder object was cleared out when I called getBlob I just append the blob back in:
musicBlobBuilder.append(musicBlob);

Creating the SVG File

Each time you press a key in the demo, you see a note added to the musical score. The musical score is drawn by a single SVG element contained within a div with an id of “scoreContainer.” Each time you press a key, script runs which adds a note to the SVG element and then the SVG file is created by appending the source:
svgBlobBuilder.append(document.getElementById("scoreContainer").innerHTML);
var svgBlob = svgBlobBuilder.getBlob("image/svg+xml");
// display svgBlob.size
In this case, I don’t refill the svgBlobBuilder because I want to start with a clean slate the next time the user presses a key.

Saving Files to Disk

The last part of the demo is saving the files to disk. When you press the “Music File” and “Musical Score File” links on top of the piano keys you will be able to save the file though an experience that feels just like downloading a file:
Notification Bar shown in IE10 in response to a call to msOpenOrSaveBlog().
Note that the notification bar is not available in the Platform Previews. Instead, a save dialog is presented.
Each link calls either saveSong() or saveSheetMusic(). Looking into each of these methods will reveal that they use the msSaveOrOpenBlob function:
window.navigator.msSaveOrOpenBlob(svgBlob, "MusicScore.svg");
msSaveOrOpenBlob and msSaveBlob are two methods available in IE10 which let sites ask the user to save a blob to their computer.
Calling msSaveOrOpenBlob will provide an option on the notification bar to open the file in addition to saving or canceling. Calling msSaveBlob only provides the option to save the file or cancel. Though these functions are not yet included in any standard, we believe they are extremely useful for writing end to end scenarios with blob data and hope that they might become a standard at some point.
Creating the Piano demo was a fun experience and I’m excited to see how you will use BlobBuilder. Let us know what you think!
—Sharon Newman, Program Manager, Internet Explorer

Web Sites and a Plug-in Free Web

The transition to a plug-in free Web is happening today. Any site that uses plug-ins needs to understand what their customers experience when browsing plug-in free. Lots of Web browsing today happens on devices that simply don’t support plug-ins. Even browsers that do support plug-ins offer many ways to run plug-in free.
Metro style IE runs plug-in free to improve battery life as well as security, reliability, and privacy for consumers. Previously, we wrote about how we use IE’s Compatibility View List to make sure sites that have a plug-in free experience for other browsers provide that same experience to IE10 users. This post describes a way for sites that continue to rely on plug-ins to provide consumers browsing with Metro style IE the best possible experience.
Developers with sites that need plug-ins can use an HTTP header or meta tag to signal Metro style Internet Explorer to prompt the user.

HTTP Header

X-UA-Compatible: requiresActiveX=true

META Tag

<meta http-equiv="X-UA-Compatible" content="requiresActiveX=true" />
Metro style IE10 detects these flags, and provides the consumer a one-touch option to switch to IE10 on the desktop:
Screen shot of a fictional video site showing a prompt that reads "The site uses add-ons that require Internet Explorer on the desktop." Three action buttons are offered: Open, Don't show again for this site, and Close.
In addition to respecting these X-UA-Compatible flags specified by the developer, the Compatibility View List can also specify a site that needs to run in the desktop.
This mechanism provides a short-term mitigation. The desktop browsing experience and most plug-ins were not designed for smaller screens, battery constraints, and no mouse. Providing an easy way to the Windows desktop is the last resort when no comparable plug-in free fallback content exists.
A plug-in free Web benefits consumers and developers and we all take part in the transition. IE10 makes it easy to provide the best possible experience while you migrate your site.
—John Hrvatin, Program Manager Lead, Internet Explorer