The fourth IE10 platform preview includes enhanced HTML5 support by using an interoperable quirks mode based on the behavior defined in HTML5. This HTML5-based quirks mode is the default quirks mode in IE10.
Users and Web developers want sites to just work across browsers. A key part of this is making HTML, CSS, and JavaScript work in the same way across implementations. HTML5 facilitates cross-browser consistency by defining parts of the Web platform previously left unspecified. This largely involves the HTML5 parsing rules, but also includes parts about howbrowsersshouldbehave in quirks mode.
IE10’s HTML5 quirks mode is used for pages without a DOCTYPE or with a legacy DOCTYPE as defined in HTML5. Like HTML5 and other browsers, the behavior of IE10’s quirks mode is the same as standards mode with select quirks applied. This means features like
Developers can quickly identify which mode a page uses via the F12 developer tools. The latest HTML5 standards and quirks modes are now listed as Standards and Quirks. Legacy modes are still listed by the version of IE that introduced them. IE's legacy quirks mode is now referred to as Internet Explorer 5 quirks.
F12 Developer Tools’ Document Mode menu
IE10 continues to use Internet Explorer 5 quirks in Compatibility View for pages without a DOCTYPE, and for pages that opt-in via X-UA-Compatible.
<metahttp-equiv="X-UA-Compatible"content="IE=5">
Call to Action
HTML5 defines quirks mode for compatibility and interoperability, but you should continue to author new sites for standards mode by using at the top of your pages. Please help ensure IE10's HTML5 quirks mode works correctly by reporting issues via Connect.
The December 2011 Cumulative Security Update for Internet Explorer is now available via Windows Update. This security update resolves three 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 this vulnerability could run a malicious application on the affected system. 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 Important for Internet Explorer on Windows clients and Internet Explorer 9 for Windows 2008 R2; and Low for Internet Explorer on Windows servers. 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.
In the spirit of the holiday season, we offer a new HTML5 experience that makes the most of your PC hardware and the new touch capabilities in Windows 8.
Check out Let It Snow and get ready for a GPU-powered snow storm. This experience brings together hardware-accelerated HTML5 canvas, SVG, CSS, and more. On Windows Developer Preview with support for multi-touch in IE10, you can reach out and brush the snow off the sign and reveal a holiday message -or just use your mouse. If you think your browser can keep up, kick it up to 1000 snowflakes. If it's more of a flurry than a blizzard, try it with IE9 (or IE10) using the hardware acceleration built into the browser.
Click the image to Let It Snow
Earlier this year we showed the first look at IE10, which offers more and more of the site ready HTML5 developers are asking for, so they can build beautiful and interactive Web experiences. With the Windows Developer Preview, we introduced more hardware-accelerated HTML5 for building touch friendly applications on the Web. We’re delighted and amazed by what developers are building on HTML5 and excited to be part of it.
Thank you!
Your participation and feedback is an important part of how we build IE. Today we want to say thank you to everyone who browses the Web with IE9, downloads the IE10 previews, runs the test drives, and reports issues on Connect. We also want to thank the people and groups who make the standards process work, the broad community of Web developers, and enthusiastic consumers who work to move the Web forward.
From the entire IE team, we wish you a Happy Hardware-accelerated Holiday Season, and we look forward to another exciting year on the Web in 2012.
We continue to contribute to the test suites under development at the HTML5 standards bodies, submitting 118 new tests to them, to further the goal of interoperability and same markup. You can view them at the IE Test Center as well. We strongly encourage all developers to write for HTML5 standards first by always using the HTML5 doc type in your pages.
IE10 Preview 4 introduces an updated quirks mode that is more consistent and interoperable with the way quirks modes works in other browsers like Firefox, Chrome, Safari, and Opera. This updated quirks mode supports quirks for page layout, while allowing use of more up-to-date standards features like HTML5 elements for audio, video, canvas, and more.
You can find a full list of new functionality available to developers in the IE10 developer guide here. Download the Windows 8 developer preview to try this update to IE10. We look forward to continued engagement with the developer community and your feedback on Connect.
This IE10 preview supports CORS (cross origin resource sharing) to allow developers to use XMLHttpRequest to safely request, share, and move data across applications on different domains. This is a common pattern developers use to bring data and services together from different applications. In this test drive demo, you can see how CORS is used along with XMLHttpRequest, the File API, and HTML5 progress control to deliver a smooth experience for uploading multiple files to a service on another domain.
Click here to see CORS used with XMLHttpRequest to upload files across domains.
Having the ability to work with binary data and files enables developers to build new kinds of applications and experiences on the Web. This IE10 preview supports blobBuilder from File API: Writer for working with large binary objects (blobs) and JavaScript typed arrays. In this test drive demo, you can see how different file types, including file types which are not natively supported in the browser like PCX files can be read, rendered, and even have their internal contents displayed.
Click here to see how JavaScript typed arrays used with File APIs to read and view binary files.
As developers build more sophisticated applications on the Web, they have more need for precise control over how end-users select parts of the page. With CSS user select support in IE10, developers can specify which elements in their page can be selected by the consumer when using their applications. In this this test drive demo, you can see how selection control is applied in a sample blog application using the user-select property in a CSS rule.
Click here to try CSS user-select to control end-user Web page selection.
An updated platform preview of IE10 for the Windows Developer Preview is now available for download. This IE10 preview adds even more support for HTML5 technologies, enabling richer Web applications with significantly improved performance. IE10’s hardware acceleration of technologies like SVG, CSS3 transforms and animations delivers faster rendering than other browsers
With this fourth Platform Preview, developers can start working with more site-ready HTML5 technologies. You can read the full list here in the IE10 developer guide. Here are a few highlights:
Cross-Origin Resource Sharing (CORS) for safe use of XMLHttpRequest across domains.
File API Writer support for blobBuilder allowing manipulation of large binary objects in script in the browser.
Support for JavaScript typed arrays for efficient storage and manipulation of typed data.
CSS user-select property to control how end-users select elements in a Web page or application.
Support for HTML5 video text captioning, including time-code, placement, and captioning file formats.
These foundational capabilities are what developers building native applications depend on: working with binary data and files, controlling selection and hit testing in application UI, and providing accessible video content with captioning. The features in this platform preview are available to Web pages now, and will be available to Metro style applications in Windows 8.
Before we can use the Typed Arrays APIs to work with the contents of files, we need to use browser APIs to get access to the raw data. For accessing files from the server, the XMLHttpRequest API has been extended with support for various “responseType”s. The “arraybuffer” responseType provides the contents of the requested server resource to JavaScript as an ArrayBuffer object. Also supported are the “blob,” “text” and “document” response types.
function getServerFileToArrayBufffer(url, successCallback) {
// Create an XHR object
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == xhr.DONE) {
if (xhr.status == 200 && xhr.response) {
// The 'response' property returns an ArrayBuffer
successCallback(xhr.response);
} else {
alert("Failed to download:" + xhr.status + " " + xhr.statusText);
}
}
}
// Open the request for the provided url
xhr.open("GET", url, true);
// Set the responseType to 'arraybuffer' for ArrayBuffer response
xhr.responseType = "arraybuffer";
xhr.send();
}
In many cases files are provided by the user, for example as an attachment to an email in a Web mail application. The File API offers Web developers tools to read the contents of files provided via an element, drag-and-drop or any other source that provides Blobs or Files. The FileReader object is used to read the contents of a file into an ArrayBuffer and, like the XHR object, is asynchronous to ensure that reading from the disk does not prevent the user interface from responding.
function readFileToArrayBuffer(file, successCallback) {
// Create a FileReader
var reader = new FileReader();
// Register for 'load' and 'error' events
reader.onload = function () {
// The 'result' property returns an ArrayBuffer for readAsArrayBuffer
var buffer = reader.result;
successCallback(buffer);
}
reader.onerror = function (evt) {
// The error code indicates the reason for failure
if (evt.target.error.code == evt.target.error.NOT_READABLE_ERR) {
alert("Failed to read file: " + file.name);
}
}
// Begin a read of the file contents into an ArrayBuffer
reader.readAsArrayBuffer(file);
}
Conclusion
Binary data is heavily used by Web browsers. With support for Typed Arrays, XHR2 and the File API in IE10, Web applications can now work directly with binary data, to manipulate byte-level data, to render additional binary data formats, and to extract data from existing media file formats. Try out the Binary File Inspector test drive demo, and take Typed Arrays for a spin in IE10.
An important new scenario enabled by Typed Arrays is to read and render the contents of custom binary file formats that are not natively supported by the browser. As well as the various array types introduced above, Typed Arrays also provide a DataView object that can be used to read and write the contents of an ArrayBuffer in an unstructured way. This is well suited to reading new file formats, which are typically made up of heterogeneous mixes of data.
The Binary File Inspector demo uses DataView to read the PCX file format and render it using a
var buffer = getPCXFileContents();
var reader = new DataView(buffer);
// Read the header of the PCX file
var header = {}
// The first section is single bytes
header.manufacturer = reader.getUint8(0);
header.version = reader.getUint8(1);
header.encoding = reader.getUint8(2);
header.bitsPerPixel = reader.getUint8(3);
// The next section is Int16 values, each in little-endian
header.xmin = reader.getInt16(4, true);
header.ymin = reader.getInt16(6, true);
header.xmax = reader.getInt16(8, true);
header.ymax = reader.getInt16(10, true);
header.hdpi = reader.getInt16(12, true);
header.vdpi = reader.getInt16(14, true);
Code similar to the above can be used to add support for rendering a broad range of new data formats in the browser including examples like custom image formats, additional video file formats or domain-specific map data formats.
Typed Arrays provide a means to look at raw binary contents of data through a particular typed view. For example, if we want to look at our raw binary data a byte at a time, we can use a Uint8Array (Uint8 describes an 8-bit unsigned integer value, commonly known as a byte). If we want to read the raw data as an array of floating point numbers, we can use a Float32Array (Float32 describes a 32-bit IEE754 floating point value, commonly known as a floating point number). The following types are supported:
Array Type
Element size and description
Int8Array
8-bit signed integer
Uint8Array
8-bit unsigned integer
Int16Array
16-bit signed integer
Uint16Array
16-bit unsigned integer
Int23Array
32-bit signed integer
Uint32Array
32-bit unsigned integer
Float32Array
32-bit IEEE754 floating point number
Float64Array
64-bit IEEE754 floating point number
Each array type is a view over an ArrayBuffer. The ArrayBuffer is a reference to the raw binary data, but it does not provide any direct way to interact with the data. Creating a TypedArray view of the ArrayBuffer provides access to read from and write to the binary contents.
The example below creates a new ArrayBuffer from scratch and interprets its contents in a few different ways:
// Create an 8 byte buffer
var buffer = new ArrayBuffer(8);
// View as an array of Uint8s and put 0x05 in each byte
var uint8s = new Uint8Array(buffer);
for (var i = 0; i < 8; i++) {
uint8s[i] = 5; // fill each byte with 0x05
}
// Inspect the resulting array
uint8s[0] === 5; // true - each byte has value 5
uint8s.byteLength === 8; // true - there are 8 Uint8s
// View the same buffer as an array of Uint32s
var uint32s = new Uint32Array(buffer);
// The same raw bytes are now interpreted differently
In this way, Typed Arrays can be used for tasks such as creating floating point values from their byte-level components or for building data structures that require a very specific layout of data for efficiency or interoperation.
With HTML5 comes many APIs that push the envelope on user experiences involving media and real-time communications. These features often rely on binary file formats, like MP3 audio, PNG images, or MP4 video. The use of binary file formats is important to these features to reduce bandwidth requirements, deliver expected performance, and interoperate with existing file formats. But until recently, Web developers haven’t had direct access to the contents of these binary files or any other custom binary files.
This post explores how Web developers can break through the binary barrier using the JavaScript Typed Arrays API, and explore its use in the Binary File Inspector Test Drive demo.
Typed Arrays, available in IE10 Platform Preview 4, enable Web applications to use a broad range of binary file formats and directly manipulate the binary contents of files already supported by the browser. Support for Typed Arrays has been added throughout IE10: in JavaScript, in XMLHttpRequest, in the File API, and in the Stream API.
Binary File Inspector
The Binary File Inspector test drive demo highlights some of the new capabilities offered by this combination of new features. You can see the ID3 headers for music files, get a sense of the raw bytes in video files, and also see how additional file formats, like the PCX image file format, can be supported in the browser with the use of JavaScript and Canvas.
In the example above, an .mp4 video is rendered using a
Internet Explorer 4 introduced a set of visual filters and transitions to allow Web developers to apply multimedia-style effects to their Web pages. The name DX Filters comes from their underlying implementation, DirectX, and their long-form syntax, e.g., “filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50).” DX Filters are not the same as SVG Filter Effects, though both use the CSS property name filter.
The most popular of these effects have since become CSS3 Working Drafts or Candidate Recommendations including opacity, gradients, and shadows. With IE10 supporting these CSS3 specifications, there’s no need for the legacy, IE-specific filters. One additional filter, AlphaImageLoader, was once popular to work around bugs with PNG transparency in IE6 but those bugs were fixed in IE7.
The following table lists the most popular DX Filters and their standards-based alternatives.
DX Filter
Standards-based Alternative
Alpha
opacity
AlphaImageLoader
or background-image and related properties
Gradient
background-image: linear-gradient()
DropShadow
text-shadow or box-shadow
Matrix
transform, transform-origin
SVG Filter Effects in IE10 can be used to simulate some of the less common, more esoteric filters in the context of SVG. Note: Because IE9 document mode supports both DX Filters and some of the standards-based alternatives, it is wise to avoid specifying both properties on the same element. Libraries such as Modernizr make it easy to use feature detection with CSS and avoid duplicate declarations.
Make the Move to Same Markup Now
The changes described above are effective as of IE10 Platform Preview 4, available for Windows Developer Preview.
More than any version of IE before, IE10 works with the same markup and code as other popular browsers (once any CSS vendor-specific prefixes are updated to include “-ms-”). Going the other way, the removal of these two legacy features means that content developed for IE10 should also work in other browsers.
Users benefit when all browsers can work with the same standards-based content.
Users expect to visit any site on the Internet with any browser and enjoy a similar quality experience. We first discussed Internet Explorer’s commitment to achieving the goal of consistent “same markup, same results” across browsers in a post on March 16, 2010 announcing the release of the IE9’s first platform preview. IE9 moved us a long way toward that goal and IE10’s HTML5-based Standards and Quirks modes largely completes that work. The post HTML5 Parsing in IE10 listed some of the legacy features removed from IE10’s HTML5-based Standards and Quirks modes. This post expands the list of removed legacy features to include two more: Vector Markup Language (VML) and DirectX-based Filters and Transitions. Both of these features were marked deprecated in MSDN documentation as of IE9 (e.g., the first sentence of Filters and Transitions: “This topic documents a feature of Visual Filters and Transitions, which is deprecated as of Windows Internet Explorer 9”) and are now gone from IE10’s Standards and Quirks modes.
The common uses of VML and DX Filters now have standards-based alternatives implemented in IE10 and current versions of other browsers. These legacy IE features remain available in IE10 in document modes 5, 7, 8, and 9 though their performance is inferior to their hardware-accelerated, standards-based replacements. We encourage Web developers to move their sites to standards-based technologies rather than rely on legacy document modes.
Use SVG, not VML
Microsoft and others proposed VML (Vector Markup Language) to the W3C in 1998. IE5 first implemented it. The W3C merged VML with a competing proposal with the outcome being SVG. (See Vector Markup Language for a brief history.)
SVG, implemented in IE9, provides the functionality needed to replace VML in Web sites and applications that use it. The VML to SVG Migration Guide, published on the Microsoft Download Center, provides guidance for moving from VML to SVG.
The Raphaël JavaScript Library is a lightweight and easy-to-use graphics API that uses SVG when available and VML when not. Raphaël is a good choice for building vector graphics solutions that work in IE8 and newer browsers.
Last March, we released a prototype implementation of the audio portion of a working draft of the W3C Media Capture API on HTML5 Labs. This prototype publicized some proposed API enhancements described in section 6.1 of Microsoft’s HTML Speech XG Speech API Proposal. We have now updated the prototype to include the image and video capture features described in the proposal to support scenarios we’ve heard are important for Web developers, as well as incorporating your feedback on audio.
As more and more consumers use mobile devices to take still pictures, videos, and sound clips, Web developers increasingly need support to capture and upload image, video, and sound from their Web sites and applications. A usable and standardized API for media capture means Web sites and apps will be able to access these features in a common way across all browsers in the future.
During this past year, the effort to standardize media capture has intensified. The WebRTC working group was formed and combined scenarios that support basic video and audio capture with the ability to share that media in real-time communication scenarios. A broad interest in both of these scenarios from industry partners and browser vendors alike shifted focus away from the Media Capture API and brought the WebRTC draft spec to the forefront.
This past November, we took our experience with the development of this prototype and interest in media capture for the browser to the W3C's technical plenary meeting (TPAC). Travis Leithead shared some of our feedback with the Device APIs (DAP) Working Group and we continued existing discussions within the HTML Speech Incubator Group. One result of our engagement was the formation of a media capture joint task force in order to bring the best of local media capture and real-time communication scenarios together. We are actively participating in the task force and support the getUserMedia approach to capture.
With the release of this prototype, we give Web developers early access to photo, video and audio media capture APIs in the browser. We anticipate evolving the prototype to share implementation feedback and experience with the new media capture task force. The end goal remains to create the best possible standard for the benefit of the whole Web community.
Let’s also look back at our earlier proposals, explain why we believe the scenarios are still important, and why we implemented them in this new version of the prototype:
Privacy of device capabilities
The prototype allows enumeration of the capture device's capabilities (its supported modes). In the old W3C Device Capture API spec, privacy-sensitive information about the device could be leaked to an application because the navigator.device.capture.supported* properties could be accessed without user intervention. Our prototype moves these APIs to an object that is only available after the user gives permission. The W3C's current getUserMedia API does not support enumeration of device capabilities, but we believe it is valuable to Web developers and should be done in a similar privacy-sensitive manner.
Multiple Devices
The W3C's current getUserMedia API is designed to support multiple devices, either via hints to the API or through user preference. This is an improvement for a scenario that was not supported in the old W3C Device Capture API spec.
Our current prototype also supports a conceptually similar design: navigator.device.openCapture() which returns asynchronously with the capture device the user prefers (through preference or UI).
Direct Capture
In the old Media Capture API spec, the Capture.capture[Image|Video|Audio] operations launch an asynchronous UI that returns one or more captures. This means the user has to do something in the Web app to launch the UI and then initiate the capture, which makes it impossible to build capture UI directly into the Web application. Not only would this be unusable for a speech recognition application, but it is also places unnecessary user interface constraints on other media capture scenarios.
Our prototype and the current getUserMedia capture API directly capture from the device and return a Blob. Note that for privacy reasons some user agents will choose to display a notification in their surrounding chrome or hardware to make it readily apparent to the user that capture is occurring, together with the option to cancel the capture.
Streaming
For applications like speech recognition, captured audio needs to be sent directly to the recognition service. However, the current getUserMedia API design only supports capturing to Blobs, which delay the ability to process the recorded data.
Our prototypeallows starting a capture asynchronously and returning a Stream object containing the captured data. Support for Streams would also be useful in video recording scenarios. For example, using a capture stream, an app could stream a recording to a video sharing site, as it is recorded.
Preview
In the case of video capture, live preview within the application is important and something that was missing from the old Media Capture API spec.
Both our prototype and the W3C's getUserMedia API, allow a preview of the recording to be created with URL.createObjectURL(). This URL can then be used as the value for the src attribute on an
End-Pointing
For applications like speech recognition, it's important to know when the user starts and stops talking. For example, if the app starts recording but the user doesn't start talking, the app may wish to indicate that it can't hear the user. More importantly, when the user stops talking, the app will generally want to stop recording, and transition into working on the recognition results. This sort of capability may also be of some use during non-speech scenarios, to provide prompts to users who are recording videos.
Neither the old Media Capture API, nor the current getUserMedia approach support end-pointing.
In order to support key speech/voice scenarios, we recommend adding end-pointing capability. The prototype provides this feature and allows Web developers to experiment and provide feedback on these capabilities which will be useful feedback for the W3C.
Looking Forward
We are supportive of the getUserMedia API, and note that it incorporates many of the points of feedback previously submitted. To avoid confusion about the future direction of media capture at the W3C, the DAP working group has officially deprecated the old Media Capture API, which now redirects to the media capture joint task force's current deliverable.
In addition to a prototype plugin that exposes the modified APIs, we have added to this package a functional demo app that makes use of them.
Building this prototype and listening to your feedback will help Microsoft and the other browser developers build a better and more interoperable Web. We look forward to continuing this discussion in W3C and helping to finalize the specifications.
The two examples shared in this post are unlikely to be things you adopt on your site. Yet, well-designed transitions and animations are becoming an expected part of a modern Web experience. Windows 8 Metro style uses fluid and subtle animations extensively to help users better understand their interactions with the system. These literally make Windows 8 Metro style apps feel more responsive to touch.
We hope the examples here, the IE Test Drive demos, and the growing number of articles and examples elsewhere on the Web help you explore this new technology and add personality to your Web site.
CSS3 Animations are similar to CSS3 Transitions in that they smoothly animate a CSS value over time. The differences are (a) how one specifies the properties to animation, (b) how one triggers the animation and (c) the complexity of the animation possible.
You define animations using a CSS “keyframes” at-rule. A simple keyframes rule that matches the fade out behavior of the transition above would be:
@keyframes fadeOut {
from {
opacity:1;
}
to {
opacity: 0;
}
}
We apply this to our image with this CSS:
img {
animation-duration: 2s;
animation-delay: 0s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
img:hover {
animation-name: fadeOut;
}
Many of these properties are familiar from our discussion of transitions. The new ones are:
animation-fill-mode – the “forwards” value of this property means to maintain the “to” property values from the end of the animation going forward in time. The default value of this property is “none,” which causes the properties to return to their non-animated values at the end of the animation. (It’s possible to construct the CSS above without using animation-fill-mode. Simply add “opacity: 0;” to the img:hover rule to maintain the ending opacity at 0.)
animation-name – setting the animation-name property triggers the animation. When the animation-name property is set, the animation-delay time starts counting down. When animation-delay reaches zero, the animation begins and continues for the animation-duration. The animation-timing-function behaves the same as the transition-timing-function described above.
The power of CSS3 Animations lies in the ability to specify multiple keyframes with properties and intermediate values that don’t have to stay within the bounds of the start and end values. In CSS3 Transitions, intermediate values always progress from the start to the end; they will never go outside that range. Animations do not have that restriction.
This makes it possible to program a “bounce” such as shown in the markup and example below.
#bouncingImage {
width: 400px;
height: 267px;
box-shadow: 2px2px5px0pxgray;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
#bouncingImage:hover {
animation-name: zoomInBounce;
}
@keyframes zoomInBounce {
from {
transform: scale(1);
}
30% {
transform: scale(1.4);
}
40% {
transform: scale(1.15);
}
50% {
transform: scale(1.35);
}
60% {
transform: scale(1.2);
}
70% {
transform: scale(1.3);
}
80% {
transform: scale(1.225);
}
90% {
transform: scale(1.275);
}
to {
transform: scale(1.25);
}
}
Move your mouse over the image to zoom it with a bounce effect. CSS3 Animations are supported by your browser with -moz-animation.
The function of CSS3 Transitions is very straightforward: smoothly change the computed value of a CSS property from its old value to its new value. Moreover, changes in value resulting from changes in an element’s CSS class or pseudo-class also trigger transitions.
Consider the following markup:
img {
opacity: 1;
transition-property: opacity;
transition-duration: 2s;
transition-delay: 0s;
transition-timing-function: linear;
}
img:hover {
opacity: 0;
}
The effect of this is that when the user moves his or her mouse over the image, the image will fade out smoothly over 2 seconds starting immediately, as illustrated below (I’ve added a dropped shadow on a wrapping element to illustrate the endpoint).
Fading one image to nothing over 2 seconds
The transition properties that cause this to occur are:
transition-property – specifies which CSS properties are to be transitioned. The keyword “all” causes all animatable properties to transition when changed. The default value is “all.”
transition-duration – the time, in seconds or milliseconds, of the transition, starting after the transition-delay. The default value is zero, meaning that the transition is immediate.
transition-delay – the time, in seconds or milliseconds, after the value is changed before the transition starts. The time may be negative, in which case the transition starts part way through its duration. The default value is zero.
transition-timing-function – describes how the intermediate values of a transition are calculated. This allows a transition to change speed over its duration. The underlying function is a cubic Bézier curve; keywords match common functions. The default value is the keyword “ease,” a function that starts fast and slows down toward the end.
Fading one image to nothing is a simple example. Let’s say we wanted to fade one image to another, as illustrated below.
Fading from one image to another over 2 seconds
The following markup accomplishes this (except that vendor prefixes must precede all the transition properties).
HTML Fragment
Move your mouse over the image to fade it to another. CSS3 Transitions are supported by your browser with -moz-transition.
Simple transitions, such as the one above, are moderately easy to simulate in JavaScript. The benefits of CSS Transitions are their declarative definitions, making them easier than script, and they run—at least in IE10—asynchronously to the main processing thread resulting in smoother transitions and sites that are more responsive.
An interactive demo of CSS3 Transitions is available on the IE Test Drive site. The demo works in all browsers that support CSS3 Transitions, including IE10 in the Windows Developer Preview.
Advancements like high-performance compiled JavaScript and hardware-accelerated rendering of HTML5 and CSS3 in Internet Explorer 9 and 10 allow Web developers to create richer and richer experiences. Two related features, CSS3 Transitions and CSS3 Animations, give Web developers a declarative way to add personality to Web page interactions easily.
This blog post describes these two features as implemented in IE10 in the Windows Developer Preview and Windows 8 Metro style apps written in HTML.
Same Markup—Except for the Vendor Prefix
Like nearly all features new to IE9 and IE10, CSS3 Transitions and Animations are standards-based features implemented with “same markup” interoperability in mind. However, unlike features such as border-radius, box-shadow, and text-shadow, which are part of stable W3C specifications, Transitions and Animations are still at a specification stage where vendors prefix their implementations. Therefore, in this case, “same markup” must be qualified as “same markup except for the vendor prefix.”
Many other writers have written about these features, including Rich Bradshaw’s excellent article Using CSS3 Transitions, Transforms and Animation. Many articles that discuss these features use only the -webkit- prefix in their examples. Users wishing to experiment in other browsers need to copy the example and change -webkit- to -ms-, -moz-, or -o-, as appropriate. Bradshaw’s examples are an exception; they already work in IE10!
As the Web transitions from Web sites to Web apps, and as Web developers build new experiences in HTML5, we know that JavaScript will also need to make this transition without compromising its simplicity, flexibility, or performance. An approach that enables broad, incremental adoption by the Web developer community has the highest chance of success. Many of the ideas coming forward in the community support these ideas, and Microsoft will continue to work in the ECMA TC39 standards body to refine proposals for the core JavaScript runtime advancements. Most importantly, progress on the standard should be based on a dialog with Web developers on what is most needed in the Web platform.
We welcome your feedback and look forward to continuing to participate in this dialog.
For the past couple of years, TC39 has been accepting proposals for new features to add to the ECMAScript standard. As we look at the current work being pursued in the committee, we see two categories of investments:
Work on the JavaScript runtime. This work (binary data, private names, globalization, etc.) offers valuable new capabilities to the platform, and can be made available in a feature-detectable way under the existing JavaScript script tags, allowing for smooth and near-term adoption of these features.
Work on JavaScript syntax. This work (let, destructuring, iterators, object literals, etc.) adds to the expressiveness of the JavaScript language, but also requires heavier weight versioning for developers, such as opting in to new script tags.
We prioritize the JavaScript runtime because it fundamentally limits the capabilities of the Web. We participate in the standards body to make sure these features can become ubiquitous tools developers can depend upon.
When building applications on a larger scale, developers depend upon high quality authoring and tooling experiences. For applications of this scale, higher-level abstractions such as classes and other common programming patterns can be the basis for better tooling.
The Office Web Applications, which consist of hundreds of thousands of lines of JavaScript, are written primarily in a variant of Script# that is then compiled into JavaScript that can be executed on today’s browsers. Other toolsets like the Google Web Toolkit take similar approaches. More recently, transforming compiler libraries like Traceur and CoffeeScript show how syntax additions to JavaScript and even completely alternative syntaxes can be supported in today’s browsers, without changes to the runtime.
Some examples, like Dart, portend that JavaScript has fundamental flaws and to support these scenarios requires a “clean break” from JavaScript in both syntax and runtime. We disagree with this point of view. We believe that with committee participant focus, the standards runtime can be expanded and the syntactic features necessary to support JavaScript at scale can be built upon the existing JavaScript standard.
Looking ahead, there is a great opportunity for JavaScript to continue to evolve the core runtime. From talking to developers building HTML5 Web sites, we understand that these areas represent the most value:
Better integration with the native browser platform. With the introduction of recent APIs in HTML5, such as the File API, Canvas Pixel Array, and XHR2, there is an increasing need for JavaScript to have better interoperability with binary data streams. The need is so acute that there aremanyproposals across many Web communities and they are starting to converge in the Binary Data proposal. The Binary Data proposal aims to improve usability and expressivity for the use cases above.
Improved site load, especially for larger sites.JavaScript today would benefit from a standardized pattern for loading units of code consistently, in a way that won’t cross-contaminate the global scope, with a predictable loading order. A solution would benefit from being integrated into the runtime to ensure efficient page load times in coordination with the other browser subsystems. The modules and module loader proposals look like promising starting points which we aim to make available to scripts in “text/javascript” without needing to introduce breaking changes.
Execution performance and responsiveness.Libraries for interacting with intrinsic JavaScript types should continue to be filled out. As the String and Math extensions proposals suggest, JavaScript would benefit from an intrinsic string search like startsWith or contains and additions to the set of math functions to match other client platforms. JavaScript would also benefit from a format capability to replace variables in strings. Like ES5, when integrated into the runtime, these features can provide clear performance improvements for many real-world Web sites with minimal developer effort.
These proposals are just part of a larger story of the evolution of JavaScript. In 1998, a complex JavaScript application was a few dozen lines of code. By 2008, leading-edge Web applications like Hotmail, Gmail, and CNN.com included hundreds of thousands of lines of JavaScript. Today, there are Web applications with a million lines of JavaScript. These Web applications look more and more like the applications we run on our desktops, with fewer page transitions and more processing occurring on the client, relying on the server for the occasional burst of data rather than frequent expensive server round-trips.
JavaScript is evolving to meet these needs, and it’s important that it does so in a way that respects everything that developers have invested in their own Web sites and their skill sets by focusing on compatibility and incremental introduction of new functionality.
We strongly believe in the community process driven through TC39 as the keepers of these principles. TC39’s work on ECMAScript 5 is a solid step forward for JavaScript in the Web platform. Some of the principles used to design ES5 provide a good template for future versions of the JavaScript standard:
Preserving the fundamental syntax of tomorrow’s “text/javascript” to ensure continuity in the developer skillset and deliver seamless compatibility between today’s JavaScript and tomorrow’s JavaScript.
Provide features that are additive and pay-as-you-go, to help developers get more value with minimal new effort or learning.
Strive for features to be locally detectable, to help developers build applications that work on the broadest range of browsers.
Where possible, allow for a possibly slower library alternative (or ‘polyfill’) for browsers that do not yet support the feature.
We are working with TC39 on applying these same approaches as broadly as possible for the next revision of the ECMAScript standard.
Computationally intensive Web applications quickly demonstrate that the built-in JavaScript math library is missing basic functions such as cosh and log10 that have been available in other programming language platforms such as C++, .NET, Java, and Python for years. String and Number can also benefit from some basic functionality common to all modern programming language platforms like testing if a String starts with a specific substring or checking that a Number is an Integer. These are addressed in the proposed additions to the Math, String, and Number APIs.
Web applications have been harder to globalize than native applications because JavaScript has not provided native date and currency formats that the underlying OS has. The drop includes a reference implementation of the proposed Globalization APIs which enable applications to deal correctly with locale specific number and date formats and strings in other languages. With this library, developers can show date and numbers in the specified locale and set collation options for the purposes of sorting and searching strings. Developers can also set date and number formats to use alternate calendars like the Islamic calendar or to show a number as the Chinese Yuan currency. This means that JavaScript applications no longer have to round trip to the server to properly display locale specific dates and numbers, which ultimately translates to faster interactive applications for end-users.
For the Web and Web applications to keep making progress, the programming language of the Web must continue to improve. Today’s JavaScript standard lacks a few basic objects and library helpers that are vital for building rich, world-wide Web applications. Last week at the Ecma TC39 meeting at Apple’s campus in Cupertino, Microsoft shared reference implementations of proposals to address gaps in Math, String, and Number functionality as well as Globalization.
To ensure that others in the community are also able to provide feedback, we’re releasing these reference implementations via HTML5 Labs. We encourage you to download the prototypes, and play with the sample Web pages which demonstrate their usage. Try it out, and let us know if you have any feedback or suggestions in the comments.
These proposals provide a great deal of much needed functionality by adding only a few objects and library helpers:
When running on Windows 7, the prototype implementation supports 363 available Locales, 18 numbering systems, many date patterns, and includes support for the Gregorian, Islamic, Hebrew, Buddhist, Korean, and Japanese calendars.
Note that as with all previous releases of HTML5 labs, this is an unsupported component with an indefinite lifetime. This should be used for evaluation purposes only and should not be used for production level applications.
We know a lot of our customers speak and write in more than one language. It’s important that the spellchecking engine use the right language when you are entering text, and that it is easy to switch between languages when necessary.
In IE10, the selection of the spellchecking language is determined by evaluating the following sources (in priority order):
The HTML lang attribute. The Web developer knows the design and intent of the site and can control which parts of the page are associated with which language (in multi-language scenarios).
The keyboard input language. Windows 8 makes it easy for users to specify the languages they are interested in and to switch between them on the fly. To switch the language used by the spellchecking engine while entering text, you simply change the input language. With two or more languages configured (or two or more keyboard layouts) simply press the Windows key + spacebar. On the touch keyboard, there is a key to toggle the input language as well.
Window’s current display language (the language you are using to run Windows).
Switch between keyboard input languages via Win+Space or by the language key on the touch keyboard
Spellchecking is an IE10 feature; while it is seamlessly integrated into Windows 8, we want to ensure that all users of IE10 benefit from this feature, including our users of IE10 on Windows 7. I’ll share more about the IE10 on Windows 7 experience in a future post.
Spellchecking in the browser will improve the accuracy and speed at which you input text on the Web. I’ve really enjoyed having it available and I know that the people with whom I correspond online also appreciate it!
As alluded to earlier, textarea and contenteditable elements are spellchecked by default; single-line input boxes (input type=text) are not checked by default since many sites use them for username fields or other purposes not suitable for spellchecking. We tried to pick good defaults, but if your Web site needs to change any of these defaults, it can. The ‘spellcheck’ attribute defined by HTML5 allows you as a developer to override the default spellchecking behavior for an element and all of its children.
By adding the spellcheck=false attribute value on any element, you disable spellchecking for all textarea, contenteditable, and input type=text elements that are children of the given element (including the element itself). Setting spellcheck=true enables spellchecking in the same scenario, and can also be used to override the spellchecking setting from a parent in the element tree. For example, if you want spellchecking disabled for all textarea elements on a page, with one exception, you can add the spellcheck=false attribute value to the HTML element, and then add a spellcheck=true attribute to the textarea element that is the exception.
Try out this capability using the spellchecking IE10 test drive demo.
The spellcheck attribute gives Web developers the flexibility to tailor the experience to the needs of their users.
Each of these spellchecking facilities (auto-correction, and word identification with corrective action menus), use the spellchecking dictionaries installed on your local PC. In the Windows Developer Preview, all of the dictionaries for all the supported languages are pre-installed. Many of the languages also include different language reform variants that you can toggle between in the re-designed Language control panel. All spellchecking options can be managed in the language control panel in Windows 8. On Windows 7, the spellchecking management experience for IE10 will be provided by the browser instead; I'll describe this in more detail in a future post.
The Windows 8 language options dialog for Portuguese (Brazil), including language reform variants
Internet Explorer 10 supports spellchecking in many common languages. View a list of supported spellchecking dictionaries and language/locales, including language reform variants.
There are sometimes needs for highly specialized spellchecking dictionaries, for example, in specific industries with their own vernacular or for languages not commonly spoken such as Latin. To support these scenarios, the Windows 8 spellchecking facility supports 3rd party spellchecking engines. When installed, IE10 and all other Windows components will use the installed 3rd party spellchecking engine.
No spellchecking experience would be complete without the red squiggles you’re familiar with from your favorite Office programs.
By default, as you enter text into any HTML textarea element (a multi-line input box) or any region of editable HTML content, the spellchecking engine will be used to check the last entered word. The word is checked against a dictionary associated with the current keyboard input language. If that word is misspelled or repeated it will be identified as a potential error using the familiar red squiggly underline. The identification of potential misspelled or repeated words is done in the background so that it does not slow your text entry.
The corrective actions menu has suggested alternate words and options to add the misspelled word to your custom dictionary or ignore the word. This works across all supported languages, including Portuguese (shown here).
The corrective actions menu will offer the most likely replacements for the identified word. You can replace the identified word with the suggested word in one step by selecting it from this menu. In addition you may choose to:
Add to dictionary. Your Windows user account has a built-in custom dictionary (which is initially empty). You may add frequently used words to this dictionary (in my case, I always need to add my last name). In Windows 8 this custom dictionary will be roamed to any other Windows 8 machine that you use via the cloud.
Ignore. The word will no longer be identified as a potentially misspelled word on this page. After you navigate away from the current page, the list of ignored words is cleared, and will again be flagged as a potential error.
IE10 has the first browser-based implementation of auto-correct.
In some cases, a misspelled word is so common that it is better to just correct the word immediately, rather than wait for you to review the error later In the rare case that auto-correct changes something that you didn’t want changed, you can undo the change via CTRL+Z (Undo) using the keyboard, or bring up the auto-correction context menu using the mouse. In addition to using the mouse, the auto-correction menu can be activated via the keyboard by moving the insertion point inside of the word and pressing SHIFT+F10 (that key combo works to trigger any context menu). From the auto-correction menu you can also prevent the word from being auto-corrected in the future.
For auto-corrected words, press CTRL+Z to undo the change, or bring up a context menu for additional actions
Typing quickly and accurately is a critical part of the user experience for any piece of software. When using a device without a physical keyboard, providing a great text input experience is even more important. Windows 8 provides several capabilities to make text input great on any device, and spellchecking is one of them.
Spellchecking in Windows 8 allows customers to identify misspelled words while they are entering text, have commonly misspelled words fixed automatically, and take corrective action on others. In Windows 8, spellchecking support is available to applications across the entire operating system, including IE10. Of course, spellchecking will also be available as an IE10 browser feature on all supported versions of Windows (including Windows 7).
You’ve seen SVG inuse. With its benefits outlined and some practical tips to avoid early roadblocks, there’s every reason to start experimenting with SVG to see how you can take advantage of it on your HTML5 Web site. Post some of your creations or links to other libraries – we’d love to see them!
Though SVG is readable and can be crafted by hand, it is still largely visual and often unintuitive to translate a visual graphic into a mathematical description of its shape. Using vector design tools already in existence today, static SVG images can easily be created. Inkscape is an option available for free download. Adobe Illustrator, often used by professional Web developers to create vector images, can save files in the SVG format. Microsoft Visio, also capable of exporting in an SVG format, is tailored towards developing business diagrams and flowcharts. If optimization is important to you, note that these applications do not output SVG in the simplest format; their output contains proprietary namespace elements and attributes that allow for round-trip editing but are not useful for final production graphics. Additional markup cleanup may be desired for a reduction in file size or for easy styling.
In addition to Inkscape, another free SVG editor is SVG-edit. It is a JavaScript SVG editor and uses your browser to render the SVG creation! The latest alpha version has some great features. Try it in IE9!
IE9 supports WOFF fonts instead of SVG Fonts. WOFF fonts bridge the gap between HTML and SVG, reducing the learning curve for SVG and integrating SVG as a part of HTML. This makes it easy to apply the same custom fonts to both your HTML and SVG content. For those already acquainted with SVG fonts, Font Squirrel can convert your SVG Fonts to the WOFF format.
Another common problem is providing fallback support for older versions of IE that do not support SVG. SVG libraries on the Web often provide fallback support and abstract the process away from you. RaphaelJS is one of the most widely known that displays VML in older versions of IE. Charting libraries that provide graceful fallback, such as Highcharts are springing up all over the web.
These are just a few basic resources to help you get started. The tools and libraries in existence today fall into two camps: (1) creation of static, standalone SVG content and (2) programming dynamic, script-driven, and script-created SVG. Both have their place in your toolbox. For those of you pioneering SVG on the Web, you’ll find there is a lot to play around with.
Despite SVG’s similarities to HTML, some frequently made errors can easily be avoided. Listed below are some common mistakes to avoid so that you don’t waste time figuring out what’s going on.
HTML5 Doctype
If you are including SVG inline in HTML5, make sure you use the HTML5 doctype . This is a requirement of HTML5. Without specifying the appropriate doctype, your page will not render in the expected document mode in IE9 or IE10. As a result, your SVG content will not appear. Don’t forget to specify the HTML5 doctype!
Default Overflow
Like other HTML elements such as
, the default overflow for a top-level inline visible. (This is different from the default behavior of an will be visible. In some cases, this can lead to unexpected behavior. You can remedy this by explicitly setting either the SVG attribute overflow="hidden" on your element or by adding svg { overflow: hidden; } to your document’s CSS block.
default overflow is visible
SVG content is clipped
Default Text Baseline Position
If you are creating SVG by hand, you may not realize that the y attribute of and elements refers to the baseline of your text. If you do not specify the y attribute, text is positioned at y=0 relative to its containing transform. This could mean the text baseline is positioned at the top of the SVG container and end up being invisible if you’ve set overflow="hidden" as described above. So, if you don’t see your text, check to see if the y attribute is specified with a positive value.
(default y=0)
Accessibility
Achieving a graphic fully accessible is challenging but because SVG supports adding descriptive text and titles to individual SVG graphic elements and groups of elements, it is possible to create an SVG graphic with much greater accessibility than an HTML element’s alt text.
Without any additional markup, text content is naturally readable by screen readers. For graphic elements, adding and <desc> tags as child elements of the shape or group allows screen readers access to that descriptive text. Like the <i>title</i> attribute of an HTML <img> element, SVG title elements display as a tooltip with the mouse is hovered over the containing shape.</p> <p>The following example illustrates the <i><title></i> element on a simple drawing.</p> <div style="font-family: Consolas, Monospace; font-size: 13px; color: Black; text-indent: -4em; padding: 0 0.25in;"> <div style="background-color: #f0f0f0; padding: 0 4px 2px 4px;"> <p style="margin: 0 0 0 4em;"><span style="color: Blue;"><?</span><span style="color: rgb(163,21,21);">xml</span> <span style="color: Red;">version</span><span style="color: Blue;">=</span>"<span style="color: Blue;">1.0</span>" <span style="color: Red;">encoding</span><span style="color: Blue;">=</span>"<span style="color: Blue;">UTF-8</span>"<span style="color: Blue;">?></span></p> <p style="margin: 0 0 0 4em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">svg</span> <span style="color: Red;">xmlns</span><span style="color: Blue;">=</span>"<span style="color: Blue;">http://www.w3.org/2000/svg</span>" <span style="color: Red;"> xmlns:xlink</span><span style="color: Blue;">=</span>"<span style="color: Blue;">http://www.w3.org/1999/xlink</span>" <span style="color: Red;">width</span><span style="color: Blue;">=</span>"<span style="color: Blue;">500</span>" <span style="color: Red;">height</span><span style="color: Blue;">=</span>"<span style="color: Blue;">300</span>" <span style="color: Red;">viewBox</span><span style="color: Blue;">=</span>"<span style="color: Blue;">0 0 500 300</span>"<span style="color: Blue;">></span></p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span>Abstract Art<span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">style</span> <span style="color: Red;">type</span><span style="color: Blue;">=</span>"<span style="color: Blue;">text/css</span>"<span style="color: Blue;">></span></p> <p style="margin: 0 0 0 6em;">/*<span style="color: Blue;"><![CDATA[</span><span style="color: Gray;">*/</span></p> <p style="margin: 0 0 0 6em;"><span style="color: Gray;">.c0, .c1, .c2 { fill-opacity: 1; fill-rule: evenodd; stroke-dasharray: none; stroke-linecap: round; stroke-linejoin: round; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 10px; }</span></p> <p style="margin: 0 0 0 6em;"><span style="color: Gray;">.c0 { fill: #e3caad; stroke: #4e320e; }</span></p> <p style="margin: 0 0 0 6em;"><span style="color: Gray;">.c1 { fill: #bc9dc9; stroke: #4b1268; }</span></p> <p style="margin: 0 0 0 6em;"><span style="color: Gray;">.c2 { fill: #2cec7d; stroke: #2c9549; stroke-linecap: butt; stroke-linejoin: miter; }</span></p> <p style="margin: 0 0 0 6em;"><span style="color: Gray;">/*</span><span style="color: Blue;">]]></span>*/</p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">style</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">rect</span> <span style="color: Red;">class</span><span style="color: Blue;">=</span>"<span style="color: Blue;">c0</span>" <span style="color: Red;">width</span><span style="color: Blue;">=</span>"<span style="color: Blue;">131.429</span>" <span style="color: Red;">height</span><span style="color: Blue;">=</span>"<span style="color: Blue;">168.571</span>" <span style="color: Red;">x</span><span style="color: Blue;">=</span>"<span style="color: Blue;">37.143</span>" <span style="color: Red;">y</span><span style="color: Blue;">=</span>"<span style="color: Blue;">40.934</span>"<span style="color: Blue;">></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span>Toast<span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">rect</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">g</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span>Bunch of grapes<span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">path</span> <span style="color: Red;">class</span><span style="color: Blue;">=</span>"<span style="color: Blue;">c2</span>" <span style="color: Red;">d</span><span style="color: Blue;">=</span>"<span style="color: Blue;">M314.286,78.076 340,15.219 428.571,26.648z</span>"<span style="color: Blue;">></span></p> <p style="margin: 0 0 0 7em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span>Grape Leaf<span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">title</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">path</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">circle</span> <span style="color: Red;">cx</span><span style="color: Blue;">=</span>"<span style="color: Blue;">270</span>" <span style="color: Red;">cy</span><span style="color: Blue;">=</span>"<span style="color: Blue;">100</span>" <span style="color: Red;">r</span><span style="color: Blue;">=</span>"<span style="color: Blue;">20</span>" <span style="color: Red;">class</span><span style="color: Blue;">=</span>"<span style="color: Blue;">c1</span>" <span style="color: Red;">id</span><span style="color: Blue;">=</span>"<span style="color: Blue;">grape</span>"<span style="color: Blue;">/></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">use</span> <span style="color: Red;">xlink:href</span><span style="color: Blue;">=</span>"<span style="color: Blue;">#grape</span>" <span style="color: Red;">x</span><span style="color: Blue;">=</span>"<span style="color: Blue;">40</span>"<span style="color: Blue;">/></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">use</span> <span style="color: Red;">xlink:href</span><span style="color: Blue;">=</span>"<span style="color: Blue;">#grape</span>" <span style="color: Red;">x</span><span style="color: Blue;">=</span>"<span style="color: Blue;">80</span>"<span style="color: Blue;">/></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">use</span> <span style="color: Red;">xlink:href</span><span style="color: Blue;">=</span>"<span style="color: Blue;">#grape</span>" <span style="color: Red;">x</span><span style="color: Blue;">=</span>"<span style="color: Blue;">20</span>" <span style="color: Red;">y</span><span style="color: Blue;">=</span>"<span style="color: Blue;">35</span>"<span style="color: Blue;">/></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">use</span> <span style="color: Red;">xlink:href</span><span style="color: Blue;">=</span>"<span style="color: Blue;">#grape</span>" <span style="color: Red;">x</span><span style="color: Blue;">=</span>"<span style="color: Blue;">60</span>" <span style="color: Red;">y</span><span style="color: Blue;">=</span>"<span style="color: Blue;">42</span>"<span style="color: Blue;">/></span></p> <p style="margin: 0 0 0 6em;"><span style="color: Blue;"><</span><span style="color: rgb(163,21,21);">use</span> <span style="color: Red;">xlink:href</span><span style="color: Blue;">=</span>"<span style="color: Blue;">#grape</span>" <span style="color: Red;">x</span><span style="color: Blue;">=</span>"<span style="color: Blue;">38</span>" <span style="color: Red;">y</span><span style="color: Blue;">=</span>"<span style="color: Blue;">80</span>"<span style="color: Blue;">/></span></p> <p style="margin: 0 0 0 5em;"><span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">g</span><span style="color: Blue;">></span></p> <p style="margin: 0 0 0 4em;"><span style="color: Blue;"></</span><span style="color: rgb(163,21,21);">svg</span><span style="color: Blue;">></span></p> </div> </div> <p style="text-align: center; font-size: 8.25pt; font-style: italic;"> </p> <p>In addition, the <a href="http://www.w3.org/TR/SVGTiny12/interact.html#focusable-attr"><i>focusable</i> attribute</a> can be used to enable keyboard access to these descriptions. If <i>focusable="true"</i>, a tab stop will be created for that element, making it easy for a keyboard-centric user to focus on the shape and obtain its information from an accessibility tool. Additionally, tabbing to and from these elements will trigger the <i>focusin</i> and <i>focusout</i> events.</p> <h3>MIME type</h3> <p>If you are serving up standalone SVG files, ensure that the server is configured to be serving up the files with the proper MIME type. The correct SVG MIME type is <i>image/svg+xml</i>. This is not to be confused with image/svg-xml. Some already existing content may use the incorrect MIME type due to the Adobe SVG Viewer’s acceptance of it. Make sure you are using the correct MIME type.</p> <h3>SVGZ files</h3> <p>Similar to the above, if you are using compressed SVG, you should make the line <i> Content-Encoding: gzip</i> is in your header response of the SVG file, much like how other gzip-encoded files should have this header response line.</p> <h3>Scaling: viewBox and preserveAspectRatio</h3> <p>To ensure your graphics will scale the way that you’d like it to, specify the <a href="http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute">viewBox</a> attribute on your top-level <svg> element. With a viewBox specified, changing the height and width of the graphic will scale it rather than clip the SVG image.</p> <p>The <a href="http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute">preserveAspectRatio</a> attribute can also be used to control the scaling of images within SVG. The syntax of this attribute is preserveAspectRatio="<i>align</i> <i>meetOrSlice</i>". These two parameters describe the how an image is to fit into its containing <image> element and where the image is positioned within the container. By setting preserveAspectRatio="none", the SVG <image> element behaves like the HTML’s <img> element as illustrated below.</p> <p style="text-align: center; font-size: 8.25pt; font-style: italic;"> <img alt="Photo of two giraffes" style="vertical-align: top; border: solid 1px black !important;" src="http://ieblog.members.winisp.net/images/20111027-giraffes.jpg" width="200"><img alt="Photo of two giraffes scaled to fit odd container" style="margin-left: 0.25in; vertical-align: top; border: solid 1px black !important;" src="http://ieblog.members.winisp.net/images/20111027-giraffes.jpg" height="81" width="200"><br> <span style="display: inline-block; max-width: 424px;">Left: image at its original aspect ratio; Right: same image stretched into a 200 x 81 container with preserveAspectRatio="none"</span> </p> <p style="margin-bottom: 0">Things get interesting when preserveAspectRatio is not "none". In such cases you control how the image aligns within a container of a different aspect ratio than the image itself. The <i>meetOrSlice</i> parameter determines whether the image is scaled down to fit within the container (<i>meet</i>) or scaled up to fill the container (<i>slice</i>). The <i>align</i> parameter specifies how to align the image within its container. Three options—min, mid, and max—are provided for each direction—x and y. This yields nine combinations of alignments specified as:</p> <ul style="margin-top: 0;"><li>xMinYMin – align image in left-top corner of container</li><li>xMidYMin – align image at center-top of container</li><li>xMaxYMin – align image in right-top corner of container</li><li>xMinYMid – align image at left-middle of container</li><li>xMidYMid – align image at center-middle of container</li><li>xMaxYMid – align image at right-middle of container</li><li>xMinYMax – align image in left-bottom corner of container</li><li>xMidYMax – align image at center-bottom of container</li><li>xMaxYMax – align image in right-bottom corner of container</li></ul> <p>The following examples show how an image is aligned for its controlling alignment. Note that <i>align</i> only matters in one dimension at a time; the image exactly fills the container in the other dimension so it doesn’t matter whether that dimension is min, mid, or max.</p> <div style="margin: 1em 0; text-align: center;"> <div style="max-width: 95%; margin: 0 auto;"> <table style="margin-right: 0.25in; vertical-align: middle; display: inline-block; font-family: Consolas; font-size: 13px; text-align: right;" border="0" cellpadding="0" cellspacing="8"> <tbody><tr> <td>xMin</td> <td width="200"> <img alt="Example of preserveAspectRatio="xMinY* meet"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_meet_xMin.png" width="200"></td> </tr> <tr> <td>xMid</td> <td> <img alt="Example of preserveAspectRatio="xMidY* meet"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_meet_xMid.png" width="200"></td> </tr> <tr> <td>xMax</td> <td> <img alt="Example of preserveAspectRatio="xMaxY* meet"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_meet_xMax.png" width="200"></td> </tr> </tbody></table> <table style="vertical-align: middle; display: inline-block; font-family: Consolas; font-size: 13px; text-align: center;" border="0" cellpadding="0" cellspacing="8"> <tbody><tr> <td>YMin</td> <td>YMid</td> <td>YMax</td> </tr> <tr> <td width="81"> <img alt="Example of preserveAspectRatio="x*YMin meet"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_meet_yMin.png" height="200"></td> <td width="81"> <img alt="Example of preserveAspectRatio="x*YMid meet"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_meet_yMid.png" height="200"></td> <td width="81"> <img alt="Example of preserveAspectRatio="x*YMax meet"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_meet_yMax.png" height="200"></td> </tr> </tbody></table> </div> <span style="font-size: 8.25pt; font-style: italic;">meetOrSlice parameter = "meet": image is scaled down to fully fit within the container leaving empty space if the container aspect ratio differs from that of the image</span> </div> <div style="margin: 1em 0; text-align: center;"> <div style="max-width: 95%; margin: 0 auto;"> <table style="margin-right: 0.25in; vertical-align: middle; display: inline-block; font-family: Consolas; font-size: 13px; text-align: center;" border="0" cellpadding="0" cellspacing="8"> <tbody><tr> <td>xMin</td> <td>xMid</td> <td>xMax</td> </tr> <tr> <td width="81"> <img alt="Example of preserveAspectRatio="xMinY* slice"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_slice_xMin.png" height="200"></td> <td width="81"> <img alt="Example of preserveAspectRatio="xMidY* slice"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_slice_xMid.png" height="200"></td> <td width="81"> <img alt="Example of preserveAspectRatio="xMaxY* slice"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_slice_xMax.png" height="200"></td> </tr> </tbody></table> <table style="vertical-align: middle; display: inline-block; font-family: Consolas; font-size: 13px; text-align: right;" border="0" cellpadding="0" cellspacing="8"> <tbody><tr> <td>YMin</td> <td width="200"> <img alt="Example of preserveAspectRatio="x*YMin slice"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_slice_yMin.png" width="200"></td> </tr> <tr> <td>YMid</td> <td> <img alt="Example of preserveAspectRatio="x*YMid slice"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_slice_yMid.png" width="200"></td> </tr> <tr> <td>YMax</td> <td> <img alt="Example of preserveAspectRatio="x*YMax slice"" src="http://ieblog.members.winisp.net/images/20111027-giraffes_slice_yMax.png" width="200"></td> </tr> </tbody></table> </div> <span style="font-size: 8.25pt; font-style: italic;">meetOrSlice parameter = "slice": image is scaled up to fully fill the container cuttin off some of the image if the container aspect ratio differs from that of the image</span> </div> <p>SVG’s preserveAspectRatio property gives you the control to define both the scaling and positioning of an image within its container. preserveAspectRatio="none" yields behavior common with HTML.</p> <h3>Scripting: SVG DOM vs. Core DOM</h3> <p>The getAttribute() and setAttribute() methods come from the DOM Core specification and apply to HTML and XML alike, including SVG. These methods are familiar, easy, and consistent ways to make changes to element attributes. Regardless of the attribute to be changed, setAttribute(<i>attribute</i>, <i>value</i>) can always be used. However, performance gains can often be attained by taking advantage of the SVG DOM. SVG supports its own DOM that exposes a multitude of attribute values and methods. Due to the nature of the SVG DOM, modifying attribute values requires a steeper learning curve than simply using setAttribute(). But the SVG DOM provides direct access to attribute values, which both improves performance and can make value manipulation simpler.</p> <p>For instance, the following function doubles the radius of a circle element using setAttribute():</p> <div style="font-family: Consolas, Monospace; font-size: 13px; color: Black; text-indent: -4em; padding: 0 0.25in;"> <div style="background-color: #f0f0f0; padding: 0 4px 2px 4px;"> <p style="margin: 0 0 0 4em;"><span style="color: Blue;">function</span> doubleCircleRadius(circle) {</p> <p style="margin: 0 0 0 6em;">circle.setAttribute(<span style="color: Maroon;">"r"</span>, 2 * parseFloat(circle.getAttribute(<span style="color: Maroon;">"r"</span>)));</p> <p style="margin: 0 0 0 4em;">}</p> </div> </div> <p>By contrast, using the SVG DOM, achieving the same effect looks like this:</p> <div style="font-family: Consolas, Monospace; font-size: 13px; color: Black; text-indent: -4em; padding: 0 0.25in;"> <div style="background-color: #f0f0f0; padding: 0 4px 2px 4px;"> <p style="margin: 0 0 0 4em;"><span style="color: Blue;">function</span> doubleCircleRadius(circle) {</p> <p style="margin: 0 0 0 6em;">circle.r.baseVal.value *= 2;</p> <p style="margin: 0 0 0 4em;">}</p> </div> </div> <p>With the setAttribute() and getAttribute() methods of the Core DOM, parsing will often be required to manipulate values. Modifying values based on the existing ones is easier done with the SVG DOM.</p> <p>Because the SVG DOM accesses attributes directly instead of dealing in strings, value type awareness is necessary and makes scripting with it more complex.</p> <p>Below is a table describing a generalization of how to access a few common attributes:</p> <table style="border-collapse: collapse; margin-left: auto; margin-right: auto;" cellpadding="0" cellspacing="0"> <tbody><tr> <th style="padding: 4px; border: 1px solid gray !important;">Value “type” </th> <th style="padding: 4px; border: 1px solid gray !important;">Attribute examples </th> <th style="padding: 4px; border: 1px solid gray !important;">DOM access </th> </tr> <tr> <td style="padding: 4px; border: 1px solid gray !important;">Presentation attribute </td> <td style="padding: 4px; border: 1px solid gray !important;">fill, stroke </td> <td style="padding: 4px; border: 1px solid gray !important;">elem.style.<i>fill</i> </td> </tr> <tr> <td style="padding: 4px; border: 1px solid gray !important;">Length </td> <td style="padding: 4px; border: 1px solid gray !important;">r, width, height, cx, cy, x, y </td> <td style="padding: 4px; border: 1px solid gray !important;">elem.<i>r</i>.baseVal.value </td> </tr> <tr> <td style="padding: 4px; border: 1px solid gray !important;">Object </td> <td style="padding: 4px; border: 1px solid gray !important;">viewBox </td> <td style="padding: 4px; border: 1px solid gray !important;">elem.<i>viewBox</i>.baseVal.<i>x</i><br> elem.<i>viewBox</i>.baseVal.<i>y</i><br> elem.<i>viewBox</i>.baseVal.<i>width</i><br> elem.<i>viewBox</i>.baseVal.<i>height</i> </td> </tr> <tr> <td style="padding: 4px; border: 1px solid gray !important;">List </td> <td style="padding: 4px; border: 1px solid gray !important;">transform, d </td> <td style="padding: 4px; border: 1px solid gray !important;">elem.<i>transform</i>.baseVal.getItem(0); </td> </tr> </tbody></table> <p>The SVG DOM interfaces are documented at the end of each chapter in the <a href="http://www.w3.org/TR/SVG/">SVG specification</a>.</p></DIV>