iPhone • 1:02:28
Safari brings a new level of interactivity to the web by supporting the latest innovations in CSS on both the desktop and iPhone. Learn to take advantage of CSS animations and effects to create exceptional user interfaces and stylized content that make your web application more intuitive and visually appealing. Discover best practices for implementing the latest CSS technologies to deliver optimal performance.
Speakers: Simon Fraser, Dean Jackson
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
My name is Simon Fraser, I'm tech lead on the Rich Media Team which is part of the Internet Technologies Group at Apple. Today I'm going to talk about adding innovative styling and animation to webpages with CSS Effects.
Whoo.
[ Applause ]
Okay, so just to give you a brief coverage of what we're going to talk about today, I'm going to talk about some of the cutting edge CSS features in WebKit, and I'm going to show you how you can use these to create innovative and really exciting web experiences for your customers.
Throughout the talk I'm going to tell you which of these features are available in Safari on iPhone and Safari on desktop, and that's actually most of them. And then throughout the session I'm going to give you some quick tips that you could do today to improve your website with some of these CSS Effects. So the talk is going to be broken into three main sections. In the first section I'm going to talk about CSS Effects that you can do using text and images.
In the second section I'll talk about the two types of animation we have now in CSS, transitions and keyframe animations. And then in the third section I'll talk about two-dimensional and three-dimensional transforms in CSS. But before I get started, I want to jump back a bit and ask why CSS Effects are important or why we think they're important.
So I'm I don't need to tell you, the web designers and web developers, that the aesthetics of your webpages are vitally important for the way that users perceive those webpages. For example, users are much more likely to find a site or to think of a site as being trustworthy and credible if it has a really nice appearance. Would you want to put your credit card number into a website that looks like this?
[ Laughter ]
Looks much cleaner, much nicer, and much more reliable. So that's the first aspect of the types of things obviously you'd use CSS to style this webpage to make it look really good. Now aesthetics and design are also important because they communicate the function and behavior of the content to users.
When users browse a page, they're looking for information, they're looking for images, and they're looking for things they can interact with. So you can CSS Effects to style your content so it's really obviously to the user what they can click on. Here's an example of a page which has a really bad experience, like which of these brightly colored things can you actually interact with? The answer is not much, it's only the list on the left.
Compare that with a site where the buttons really look like button, because they look kind of like the native buttons, they have this nice shine, 3D appearance to them. So you can use CSS to make elements on your page really pop out and be really obvious as to what their function is.
So this is a sort of static effect of the site. There are a couple of dynamic aspects of aesthetics and behavior that are also important. Many webpages will have different states to the content, you see often these sites where they have a slideshow or an image that pops out to fill the window and so the user is focusing on that one thing. And it's important to communicate to the user what's happening during those state changes.
So here's an example where we take a video full screen to zoom up to focus the user's attention on that video and you saw a nice transition affect when that comes up. We now have transitions in CSS that make this kind of thing really easy. Here's another use of animations.
[ Laughter ]
Let me just do that pose. Animations are important because they communicate the behavior of the underlying system to your users. So if your webpages may be pulling a database on the backend then that's going to take some time, you can use an animation to communicate to the user that something is going on.
And we have CSS keyframe animations now which make this type of thing really easy as well. So why do we think that CSS is the right technology for this? Well cascading style sheets have been around for a while now, and the way that you can separate the style from the content on your webpages, you can load a new style sheet and have an entirely different appearance for your page without changing the content. This is useful because it allows you to tailor the presentation of your content to different devices. You might have an iPhone style sheet and a desktop style sheet.
And you can use all the phone specific CSS properties to really tailor your content, for example, adjusting the text size. And we like CSS also because it's very easy to author just in a text editor or there are some great authoring tools from Mac OS X now that allow you to write to to CSS. And the final useful property of CSS is that it allows a graceful fallback. What I mean by this is when a browser encounters a CSS property that it doesn't understand, then they'll simply ignore it.
What this allows us to do is to add new features to CSS that you can use on your webpages, but these new properties will be ignored by the older browsers, so you have a nice backward compatibility story. And because many of these are new features that we've added, I'd like to take a moment to talk about how Apple innovates in web technology. And the way we like to do this is to work with the other browser vendors and the standards bodies to put the properties that we think are interesting into the Open Standards world.
And we worked very hard with the HTML 5 working group and the WHATWG on new elements in HTML 5, for example, the audio and video elements. And then a lot of the properties I'm going to talk about today have been submitted to the W3C in various working drafts that we've offered and we're working with, with the CSS working group.
Now many of these are still draft properties, the standards haven't been finalized yet, and because of that you'll see a lot of -WebKit in my slides today. And that -WebKit indicates that these properties are sort of protected by a name space that allows us to do innovation without breaking consistent pages. So everything I'm going to talk about today is just web development.
If you already write webpages and know a bit of CSS, this should be really easy for you all to pick up. It's almost all CSS in fact, there are a few small places where we touch the JavaScript and we have a few DOM events related to animations that I'll touch on later. And almost everything I'm going to talk about works in Safari on iPhone and Safari on desktop.
And of course if you're embedding WebKit in your native apps both on the phone and UIWebView and on the desktop on WebView, you can use all of these new properties because you know which browser version your content is going to be rendered in. So we have some great demos today and some really nice content, so I'd like to invite my colleague, Dean Jackson on the stage to show you the first demo.
[ Applause ]
So it's actually not a coincidence that Simon is wearing the same clothes, he wears the same clothes everyday.
[ Laughter ]
So I'm Dean, I work on the Rich Media Team. Rich Media is sort of a generic term, it doesn't mean anything. The way I like to think of it is it's an experience, you're trying to provide the best experience on your website.
Now for this session today, we were lucky that one of our favorite bands, Wilco, generously donated their content for us so you could see what we could do with it. Now Wilco already used their website, it's a also already a valuable part of the band, they use it as a way to connect with their fans.
And it's a great example of a rich media website because it's got a lot of assets, for example, and obviously audio, they stream a lot of their concerts. They take photography of their gigs, and videos or whatever. So we thought we'd take the Wilco site and see how far we could push it using the CSS Effects technology and Safari 4 and Safari on iPhone, and see what we could come up with.
And what we'll do is we'll go through it here and then Simon will take it apart through the presentation or at least the first half of the presentation, and we'll show you how it was done. So just note here, pretty simple example of a menu that hovers. Now this isn't a plug-in in any way, there's no plug-ins used in this page. This is an interactive menu that's done purely through CSS, in fact there's no JavaScript behind it, and we'll go into that later.
Now let's select News. Now you might have noticed the background was a cross side transition there, we'll explain that. Another thing to point out is this text is a custom font, obviously branding the fonts is an important part to the experience. This is a custom font embedded in the page, also the scroll bar. Again the custom scrollbar, this is a WebKit extension.
This has actually been implemented using border images, so at least you can actually get some pretty crazy scrollbars if you want to code it up. You'll also see that the image of the album, this is the new album coming out soon, it has a reflection on it. Again, done through CSS, so I don't have to generate the image on the server or my client upload it. And again, I've just applied it to every image that's in the News feed. Next we'll go to Records.
Now again there was a transition in the background, this time we transition to a color. And the reason for that is Wilco wanted the color of the page to reflect the album art. So here if I select a different album, the background color changes, and it changes through CSS, I don't have JavaScript running to do the change. Again, if I pick different albums, the color changes. So let's go back. Obviously audio is important, now what we've got here is the HTML 5 audio element in the page.
It's hidden because we don't want to see the control, we want the experience to be sort of a more ambient experience. So I'm going to select a song.
[ Music ]
[ Music ]
There's other songs there so let me select, and the one we crossfade to the next song, we've got another one going.
Now I said that there is not control in the page, but what we do have is an element that's hooked up to JavaScript events so when I click off the music just stops. Next up we'll see Photos. Again, another crossfade. Now let me just go through, this is a slide show.
Wilco has these fantastic photographers that follow them around the world taking great photos of their gigs. Now let's just say I want to do a slideshow, I'm just going to come backwards and forward between these images And what I'm doing here is just changing the opacity property on an element.
The JavaScript is actually doing the animation, it's the browser engine through CSS that's doing the animation. It's opacity, we can also move things around on the page, people know how to position things in CSS so we can get these effects where we move things up or down, it doesn't really matter. We can have a look at that in slow motion.
And you see what's happening there is the front image is being pushed down the page and fading, its opacity is going to zero, as the new image comes in the back from above. But we're not limited to just these sideways moves, we've got the pair of 2D transforms behind us, so we can actually do scale effects. Again, you can see this - I'll show it in slow motion. Again, fading opacity and scale at the same time.
And you can do some sort of more complicated effects here. Don't necessarily need to do slides. This one is another one, again, you don't just limit it to scale, we can do rotation. Let's have a look at that in slow motion again. Pretty cool effect. Again, this is all just one line of CSS, you don't need an authoring to do this, you can write it pretty simply yourself. And that's the fans of 60s television shows. Now we've touched on 2D transforms here and transitions, but we want to give you a little taste of what we'll get to in the second half of the presentation.
And in fact, you can do 3D effects on the desktop. So this is of course the information on the photo. Now you'll notice one thing, this really is 3D because as you'll see, it's pointing in one direction and we can see through the back of the element in this case and he's facing another direction. I should say that this stuff is like really fun to code if you've been living through the years of browser and compatibilities or whatever, it's a blast.
So let me go back to - this is an example, Wilco has a show coming up later in the month and we want to do a custom poster for their event. This is a pretty generic page, it's in Berkeley so we've got a person off to buy their tickets and they forgot their wallet.
Berkeley residents.
[ Laughter ]
This text is actually real text even though it's got the custom font I've selected, and in fact, this is a link, if you can see down here. This is the last time he drives past. You can see in the status bar it's actually a link to a page so I can go to a website. Now I won't point out all the effects here because Simon is going to go through it, well actually that's I introduce Simon, he'll actually show you how we coded up this demo, so where is he. Simon. Thank you.
Great. Thanks, Dean.
[ Applause ]
Slides. Okay, so let's dive into the first main section of the talk. So in this section I'm going to talk about CSS Effects you can do with text and images. So the theme for this section is that many of the things that you've been doing and your designers have been doing in Photoshop to generate assets with your web content, can now be done dynamically in CSS.
We have a very rich and varied set of CSS Effects you can apply. Those are things like stroked text, text shadows, and web fonts, and then things you can do on other elements on the page, image borders. We have various ways of generating images on the fly in CSS like gradients and masks and canvas, and then reflections as you saw in the demo which can give you very nice reflections just with one line of CSS. And I'll explain some of these to you by building up this poster that we saw in the demo, so let's start with that.
Actually before I dive in, why are CSS Effects a much better way of doing this than using static image assets, and there are a whole bunch of reasons. So the first one is that the content is still HTML content, the user can bring up Find in the browser and then search the page. And that content is also going to be indexed by search engines.
As Dean showed, the content can still be selected by the user, so in this case they could select the date and maybe use it to make an event in the calendar. The text is still scalable, it's still real text, so when the user zooms in, instead of seeing jaggers as they would with images, the text stays nice and sharp. And then also for users who are using voiceover on Mac OS X, voiceover will be able to identify the text and identify links in the text and then read it back to the user.
So it's much better for accessibility. And a final reason is that by CSS Effects you can do many of the things dynamically on the page that you would have had to do with static images, so that means that CSS is going to be a much smaller description of those effects than the massive image assets you would have had to use before And there's another advantage that we'll see a bit later in the session, and because this is all done dynamically in the browser, we can then do animations and other things to these effects on the fly.
So let's start building up our poster. Here we have some HTML markup and a pretty bare bones styling of that markup. So we've just got a div element with an id of poster so we can apply some style to it. That has an H1 and then a couple of paragraphs with a date and then a link to the location.
And here's the final thing, this is what we're trying to get to, and we'll build this up step by step. So the first thing you may have noticed there is that the font is different from the Wilco branding font. So what we need to do is use a custom font in our web content, and we can do that using web fonts in CSS, and this is a two-step process.
In the first step, you describe your custom font using an app font face rule. And that has two parts, we assign a name to this font which we're going to use later on in the CSS using the font family property. And then we specify a URL which is where the browser can go and download this font from.
One thing to not is if you're uploading fonts out there your web server, you need to have the distribution rights for that font just as you would for images or video, so be aware of the legal implications. Now we've described our custom font, we can actually use it, and we use it in the same way that we use any other font on a system, which is putting it in the font family property.
So here it is, we've called HelveticaNarrows and then we've got a couple of fallback options, Helvetica and Sans Serif for browsers that don't support downloadable fonts. So this is one example of the way that CSS gives you nice grace for fallback behavior. So here's what we started with, now we've got a custom font, so we're getting a bit closer. And this is actually closer to the final thing.
And what I've done here is just apply some colors, some line height adjustment, and some text size adjustment, which is standard CSS stuff, so I won't cover that today. This is what it looks like with the background. And one thing you'll notice here is that the text is a little bit hard to read because we spaced it very closely, the lines are running into each other.
So let's try some things that we can do to make this easier to read. The first thing we might try is to apply text stroke, and we can do that in WebKit with the text stroke property. We're going to give a 5 pixel width and then a red color which looks like this, so it does help the text stand out, but it doesn't look particularly pretty.
Something else we might try, something you may not be aware of, but WebKit supports RGB colors, and these let you specify a color by the red, green, and blue components between zero and 255, and then an alpha component which is between zero and 1. So that gives us a translucent effect to our text, and you can see the poster showing through the images there, showing through the characters.
I think we've gone a bit overboard here, this is getting too far away from the Wilco branding, so let's go back to what we started with and try another effect, and this effect is text shadow. And this has been supported for a while, let me just knock out the background so you can see the effect more clearly. The property is called text shadow, and you describe the shadow with a color, and X and a Y offset, and we're just using zero, and then a blur radius. And when we apply that to a the text, we get something that looks like this.
And if I put the background in it's like this. So I think that's giving us a much better appearance, it's much easier to read now, so we're happy with that. Now so far our poster has this really boring gray border around it, and we want to make that a bit more interesting to look like this.
So there's another property we can use to do this border using images, and that property is called border image, and it's specified like this, border image, and you supply a URL to an image frame.png in this case. And then four values which are distances from the top, the right, the bottom, and the left, which we're going to use to slice up this image. And then those middle sections on the top and the sides can either be repeated or stretched when this image has grown to fit the final thing.
Here we're going to stretch them so it ends up looking something like this. So border image is a great way to customize the borders on your page using image assets, but those image assets are really small. Okay, so here we are with something that looks much closer our final appearance. Now you may have noticed on the final one we had this sort of glass effect over the top, a sort of glassy effect to make it look like there's a sheet of glass in front of the poster.
So let's see how we've built this up. And the first thing we can try is making an alpha.png image which we sit on top of the poster, and we could do that, but that's a pretty large image that's about 136k if you actua6lly make the image. So there's a way we can do this effect without using any additional image assets, and we can do this with CSS gradients and then using a canvas as a mask image.
So let's go into those in more detail. Canvas is one of a couple of types of generated images, what I referred to as generated images earlier in the slides. And by generated images I mean that by using this property, under the hood WebKit is making image on the fly which is can then use in the CSS.
And you can use those anywhere in CSS where you would normally supply an image. So in this case we have a div and we're setting its background image property to a WebKit gradient. And the way you describe the gradient is maybe familiar to you if you've used something like Photoshop that has similar controls, there are two types, linear and radial, so we're going to use a linear gradient.
And then we specify the end points, and our end points are going to be with a start on the top left and then the end on the top right. Then we specify the end colors, red and blue in this case, and we could stop here, but you can optionally supply one or more color stops. For example, we could have a color stop which is a transparent green color, 40 percent of the way through the gradient. And this gives us a really nice gradient we can use anywhere in CSS without any additional image assets.
And this is just a few lines of CSS. So in the poster the one we used is a little more complex, it actually uses a white color with varying levels of alpha for the end points and the color stops. And the CSS experts in the audience may notice that I've assigned that gradient to the content property of a colon after, that's a generated pseudo element in CSS. And this means I'm able to apply this gradient over the rest of the content without changing my markup at all.
and that's really small, that CSS is just around 400 bytes, so that's way smaller than that big alpha ping that we started with. So if I apply that gradient it would look something like this, which is a good start but our final one has this sort of slice taken out to make it look more reflection, so let's see how we did that. And the way we did that is to use a mask image.
And what masks allow you to do is to take an element or an image like this and then apply a mask using the alpha pixels of the mask to govern what shows through in the element the image is being applied to like this. And the property is called mask, and you can supply a mask image like this. And again, we could use an alpha.png for this mask image, we probably want to png because we want a nice feathered edge along that diagonal otherwise it'll look jaggy.
But that's again a pretty large image, that's 120k. So let's see how we can do this again without any new image assets. And the way we do this is by using a canvas. Now you may be familiar with canvas as an element that you can put into an HTML and then get out from from JavaScript and use JavaScript to programmatically draw into the canvas. And that's what we're doing here, but the difference here is that this canvas is generated dynamically on the fly when we call getCSSCanvasContext.
So this is one of the few places in this presentation where we'll use JavaScript to do something non-trivial. So what we're doing is we're telling the browser to give us a canvas that it's creating on the fly and that canvas has a name called mask that we'll use later. And then we use the standard canvas 2D drawing APIs to actually draw into that canvas.
So we start a path and then we move to the starting point, and then do a couple of lineTos and then we close the path. Now we have a shape that we can fill, so we're going to set the fill color to black and then tell it to fill the canvas.
So that's now given us an image that we can use later on. There's one more thing we have to do which is we have to tell the browser to actually render this canvas at least once so our image is ready for us to use in CSS. And the easiest way to do that is with an onload handler on the body element, or probably if you're more experienced with JavaScript, you'd use AddEvents list load for the load even and then do it there.
So now we've programmatically created the mask that we can use, and then we apply it with the mask property, and we're setting the mask to the WebKit canvas, and then specifying the name mask in green that we saw earlier. So now we've done all of this, all of that glass effect without any new image assets. And here's the final poster.
[ Applause ]
So there's one more effect that you saw in the demo that we didn't actually use in the poster because it didn't fit into the theme, but that's the ability to describe reflections in CSS. So this is a fairly new feature in WebKit, and property is called box reflect, and it takes three values. The first one is the side the reflection is going to show on, below, above, left, or right.
And then there's an offset between the reflection on the element which is in this case two pixels. And then the third value is an image that's going to be used as a mask, and this could be any image, but to get the standard reflection faloff effect, it's very useful to use a web gradient. So we plugged in gradient there, and that gives us the reflection effect you see here.
Very simple. So let me summarize this first section, WebKit now has a very rich collection of CSS Effects that you can apply on text and images, and you can generate images on the fly with gradients and canvas in order to do really interesting effects without having to download additional image assets. And then finally you have things like masks and reflections that allow you to modify the presentation of elements on a page and get a really interesting look.
So here's the first tip I'm going to give you about something you can do right now on your website. You might want to open your laptop and log onto your web server, bring up your CSS, and then you can just type some of this stuff in and get a really interesting look on your website.
So what we're going to do here is apply text shadow to the H1 and H2 headers in our site. So here it's specifying text shadow, we're using a gray color with a zero pixel X offset and a 5 pixel Y offset, and then 5 pixels of Blur Radius, and you'll see we get this nice little drop shadow effect.
So that was the first section, that was things you can do with text and images, sort of static CSS Effects. Now let's talk about some much more dynamic stuff. We now have two types of animation in CSS, we have transitions and keyframe animations, and so I'll talk about those next. So let's start with transitions which are the simpler one. And as you may already have seen in some sessions today, transitions give you what I like to call animation for free. With one line of CSS you can start having animations on your webpage that look really good.
Here's an example, this is a video where the video control of it pops up, but the video control just snaps in, it's just changing the bottom offset of that div, it looks okay, but it's not great, the user experience is not good. With one line of CSS we can add a transition to that effect which gives us a nice animated appearance.
It gives the user a much better feel for what the content is doing. Animations are in CSS are also really good because they let you get rid of all this JavaScript code that you would have had to write to do those animations by hand or maybe you had to put in libraries and deal with all of those issues.
You can get rid of all of that and just add transitions with a single line of CSS. So in a bit more detail, let's look at how transitions work. Now the key point with transitions is that they work on existing CSS property values. So here we've got an example with a box that has a left offset of zero, the box is positioned so we can change its position on the screen by changing left.
And then when the user hovers over the box, it's going to jump over a little bit, it's going to jump by ten pixels. And normally when the user hovers, that change is applied immediately, the box snaps to its new value. If you want the animation, we can specify that there's a transition that happens, so here we set the transition property, we're saying that left is going to run the transition, and that's going to happen over two seconds.
And that immediately will give us this nice smooth animation between the old value and the new value over that two-second period. And the default animation is nice and smooth because it's an easing function, but if we want we could have a linear transition by specifying a timing function of linear.
And here note that we're using the short hand, so we've got all these values and the same transition rule. Just a little more detail about the transition properties. So you have to choose which properties you want to run transitions on, and you do that with the WebKit transition property. And then you specify how long the transition is going to take with transition duration. If you want to, you can change the timing function as we saw. This has a number of keywords you can use like ease, ease in, ease out, and so on.
And you can specify custom timing functions if you want to. And then there's also transition delay, and this allows you to specify a delay before the start of the transition, this could be really useful if you want to do interesting builds where a number of elements kind of flow onto the screen one after the other. So you may be wondering what other CSS properties support transitions.
Well the answer is that a lot of them do, pretty much anything that's a length or a number, like positioning and size, border widths, padding, margins, background, select position, all that kind of stuff. They also put transitions, things to do with fonts or font size, line height, letter and word spacing, those too. And we can also transition colors, and we can transition shadows with text shadow and box shadow, opacity, and transforms, and we'll come back to transforms later, and a bunch of other things. So pretty much anything you expect can change between two sizes will run a transition.
So here's something else you can do on your website. Maybe your site has an effect where when the user hovers over one of the links or a heading you change the background color just to show that it's something the user can interact with. By default the background color snaps, it'll just snap to that new color when the user hovers, and that's a bit jarring. So we can give the user a much better experience if we set a transition, and here we set a transition on the background color property of one second, and we get that nice smooth fade between the old and the new colors.
So those were transitions, and transitions are very easy, they give you animation pretty much for free, but they're a little bit limited. If you need more explicit, more expressive animations, then we have keyframe animations which let you do those too. And keyframe animations, the key concept with keyframe animations is that you're using CSS to put the element into an animating state, you're saying to the element please start animating now.
and then it will just do a number of animations and stop or it'll just keep running the animations. And because they're more complex, it's a little more work to set them up, the first thing you have to do is describe the set of keyframe, kind of like font face that you saw just now.
And then secondly you have to actually use the properties that start the animation, and then describe its other behavior. Types of things like whether the animation is going to repeat, whether it's going to alternate, and alternate means that every other cycle it'll go backwards so you can do sort of bouncing back and forth animations, things like that.
And then here's where the DOM Events come in, which I touched on earlier. Animations are more complex, and if you're using animations, it's fairly likely that you have some other behavior on your webpage that you want to tie into those animations. Maybe you need to know when the animation repeats or when the animation ends. And you can do that because we emit DOM Events which you can listen for in your JavaScript to know when those animations start, then they loop, and when they end.
So the animation properties in a bit more detail. You describe the keyframes in an at rule, so it's @-Webkit-keyframes, and then you give it a name which you will use to identify those keyframes later. And then to actually apply those keyframes, you use the animation name property. What animation name is doing is it's saying please apply this keyframes to this element.
Then you control the length of one cycle of the animation with the animation duration property. You can control the number of times it's going to repeat with animation-iteration count, and that has a keyword called infinite if you want it to keep going forever. And if you want that reversing behavior that I mentioned, you can set animation direction to alternate, the standard one is normal which means it will just keep going forward.
And then animations also have a way of controlling the timing function which is a per keyframe timing function, and that's the animation timing function property. So let's look at the example you saw on the slides where the guy is running to get his tickets and then he forgets his wallet, and then he runs back again.
So to do this we had an image element in our document in the standard way, and we've absolutely positioned it so we can move the bus around by changing the left property. And then here are the two stages we do to set up an animation. The first one is to describe the keyframes of that animation.
So we've set our @-WebKit-keyframes, and we've given the name drive, so we'll use drive as the name. And the first keyframe puts the bus off to the right-hand side of the screen, our content has a div with overflow hidden and it's less than 1200 pixels wide So the bus starts basically off the right-hand side of the screen. And at the 40 % mark, the bus has that same position, so the bus is sitting there unchanging for the first 40 % of the animation.
And then in the final keyframe, the bus is off to the left of the screen, so that means the bus is going to sit on the right-hand side for a while, and then it's going to animate over to the left, and then it'll snap back to that right-hand side and come back again. And now once we describe those keyframes, now we can apply them to the element by setting an animation name, and we want a duration of six seconds, and here we want the animation to just keep looping for as long as the user has the page loaded.
So we're using the intranet keyword for animation duration count. And the final thing we set is a linear timing function so the bus moves at a constant velocity across the screen, ends up looking like this. So keyframe animations, because they're applied sort of on top of everything else, when that animation is running, the CSS values in the keyframes trump all other values.
And then when the animation stops, its effects disappear and the element reverts to its unanimated appearance. Because of that, you can override animations if you want to by overriding the animation name property and setting it to none. So here's another tip you can do, it's slightly more complex because you have to set up some keyframes, but we can get a nice animating progress bar without using any animated gifs or plug-ins or anything else.
Here we have a div and we're going to use background image to do the animation. So we're setting the background image to a little square image called progressBar.png and then it's repeated across the div, so it fills up the div. Now we set up some keyframes, and in these keyframes we're going to animate the background origin property, and we're going to start with an X offset of 32 pixels, zero pixels and Y. And then it's going to animate to a left offset of zero pixels.
This means this image is effectively moving backwards inside the box, but it's getting tiled, so it simply fills the box but appears to be moving. And now when we apply those keyframes by setting the animation shorthand in this case, the image starts animating. So we've named the keyframe spin, we're using a duration of one second. Again we're repeating an infinite number of times so it just keeps running. And we're using a linear timing function, so it appears to move smoothly.
So that's it. Now let me just tell you the differences between these two types of animations I've talked about, transitions and keyframe animations. Transitions, as I said, operate on existing CSS property values. They're the sort of magical interpolation that happens when one of those values changes. So they're quite automatically when other things change. Keyframe animations are more under the author's control, so the author applies them specifically by setting the animation name property to a set of keyframes and setting a duration to something greater than zero.
Both of these support timing functions, for animations that timing function is per keyframe. But if you need more complex behavior, if you need keyframes to have something moving in a very complex path, then keyframe animations are the way to go. And those also give you repeating behavior and they give you alternating behavior. So I'd like to invite Dean back on the stage to show us how we used transitions to spice up that Wilco demo.
So let's take a look. You remember this menu from earlier on, and what I'll do is open up Xcode and show you.
This is the code that's giving this menu, so it's basically just an unordered list a UOL element with a bunch of list items. Now when I hover over these elements, the color changes. This is something you've all seen on the web millions of times. Let me just show you the CSS that's behind that.
So I'm saying by default the list items get this color, and when the pointer is over them, the hover pseudo class applies, and we have a different color. So let's say I want to add a transition to it. Like Simon said, this is sort of animations for free.
So all I have to do - locate transition, and I just say color. And let's say I wanted to fade in over two seconds, save that, reload the page. And now as I move my mouse over, you can see they fade in. Well that's not very easy to see, so what we'll do is we'll make it pop a little bit, so I'll add a padding left and let's say 50 pixels, save that. And now you can see, they pop out. Do I want that to transition? So just add the next property, so now I want the transition padding left.
I'll make this one just 500 milliseconds so it'll be a little quicker. And now, let's see, very easily we've got this animation effect. That's not quite what you want, you'll notice what's happening is that it animates even when my mouse gets over the element, but as soon as I leave it, it jumps back to its original position. Maybe it's because the transition properties apply the same way every other property in CSS style through the cascade.
So what I'm saying here is that when I'm in the hover state, I want the color property and the padding left property to animate because the transition applies in the hover state. But the fact that we want the transition to apply both in the hover state and in the normal state. So all I need to do actually is just take it from here, if I could move the keyboard right.
I'm going to move it up to the element. So now I move it up or down into the hover state of saved or reload, and you get the effect going in and out. And you can see here that you don't actually need to let the transitions run all the way to completion, they'll restart from wherever they happen to be, so you always get this smooth effect.
[ Applause ]
Now we get it. There we go. Simon mentioned at the start that these effects work both on desktop and iPhone, we wanted to actually show you exactly how they perform, so let me close that. Let me fire up the iPhone simulator.
Now I've got this icon on this home page, it's actually a full-screen web app, so it's still a web content, it's no native app. Now imagine this is site that Wilco wants to give out to their customers on iPhone, and we want to see how they show their slideshow.
I'm going to just start the slideshow off, and you can see here that because the engine is performing really well, we don't have to iterate JavaScript, it performs just perfectly. We can do all the transitions, we can do the 2D effects on the iPhone. Now again, Simon is going to be talking about transforms in the next section, and we mentioned 2D and 3D trans-forms, so let's have a look at what you be able to with the 3D transform.
You can see here we've pushed things out into a ring, and I can also apply a CSS animation. Because this isn't a plug-in, these elements are really part of the page, so I can apply CSS to anything. So let me just start off an animation, and you can see them rotate. Now it's a bit close to you can't actually really see the whole effect, this is just CSS.
So what I'll do is just apply a transition, I'll push the elements back, and there you can see it. And this animation is basically two animations happening at the same time, we've got one that's spinning around and the other one that's rotating the ring. And again, I think this is a pretty effective way to get a slideshow. So now Simon is going to tell you how to do this in code.
[ Applause ]
Thanks, Dean, that looks really cool. So we've talked about image effects and text effects, we've talked about transitions and animations, so now the final section, two-dimensional and three-dimensional transforms in CSS. So you might be familiar with these kinds of transformations from maybe your image editor which allows you to select a piece of the image and rotate it, scale it, move it around.
Or you may have used them in SVD or canvas, or even native code, these transformations. So now we have the ability to describe them in CSS. Now a poster that we saw before, actually on the final page had this tilt to it, and that was just one line of CSS that set the transform property to a rotation of three degrees, very easy.
So in a bit more detail, the property name is called transform, and it has a number of values that describe the standard affine transformations you can do, translates, rotates the scales and skews. So for translates, you can move an element in X and Y using pixel values or lengths or percentages.
Rotations take an angle in degrees, radians, or grads. With a scale, you can pass an X and a Y scaling multiplier, and then skew takes an angle for the X skew and the Y skew. You can also control the origin of the transformation with the transform origin property. And if the default origin is in the property.
And if the default origin is in the center of the element, so if you do something like a rotation that's going to rotate about the center But you can set transform origin to say top left, and that means the rotation is going to happen about the top left corner of that element. So here's another little tip you can do on your website with transformations.
Maybe have some icons somewhere on your site, and you'd like to apply a nice little effect when the user hovers over those. So you could set a transform. And in this case we set a transform to a rotation of ten degrees and then a 1.2 scaling, and that means that image just pops out and gets a bit bigger so the user can really see it.
Again, we have this kind of snapping behavior which isn't really very pleasant for the user, so as you might expect, we can then put a transition on this, and transforms and transitions work really well together. So now you can see that when the user hovers, they get a nice smooth animation effect when they're rolling over those images.
Now that's two-dimensional transforms, and we've had two-dimensional transforms for a while. I'd like to talk for a moment about 3D transforms. And when I talk about 3D transforms, I'm not talking about having a full 3D kind of modeling system in HTML and CSS. HTML is by definition a planar medium, the elements are all sitting there on this flat space. But when we apply three-dimensional transforms, what we're doing is moving those elements around in three-dimensional space, so think of it as planes in space.
And we've had 3D transforms in= Safari iPhone since iPhone 2.0, and then we've been working really hard and we've now got support for three-dimensional transforms in WebKit open source. And we could do that because these both share the same rendering engine under the hood, it's WebKit in both places. And I'd like to peek under the hood there and talk a little bit about how we implemented this.
Now naturally when you think about 3D you think about OpenGL and games and all that kind of stuff. And the way those are rendered by the machine, by the computer is that it uses the graphics processing unit. So this is effectively what we've done, we've added support for rendering via GPU to WebKit.
We can take elements on the webpage, render them to a hardware layer, and then have the GPU composite those to the screen. And this has a number of advantages. First of all it allows us to do three-dimensional transforms. Secondly it allows us to hardware accelerate certain transitions and animations on the webpage. And actually in the demos you're seeing today, we're using this feature to get really nice smooth animation. And finally, you can imagine that we could accelerate other things like video playback for example.
So this is an area we're working really hard in and we're very excited by this. So here's the example that you saw on the demo. We have this really neat 3D effect, this flip effect, so we can show the information on the back of the image. And this is all done again with CSS, no plug-ins, no magic here, it's all good. So let's look in a bit more detail about CSS transforms.
So 3D is really just an extension of two-dimensional transforms, it's the same transform property but with some new values. And those values are things like translate 3D, rotate 3D, and scale 3D. And we also have the ability to describe a full 4 x 4 matrix if you need that amount of control.
And as I mentioned, what you're doing here is you're positioning those HTML elements in a three-dimensional space. Now 3D is a little more complex, you need a bit more control over how that scene is going to appear to the viewer. In other words, you need to make it look 3D by giving it some perspective, and so we have a perspective property for that.
It also becomes very interesting when you can build hierarchies of three-dimensional objects. For example, you could build something like a cube out of these planes and then spin the whole cube around. And to give you control over that type of thing, we have a property that allows you to do three-dimensional hierarchies called transform style.
And then finally, there's a property that we'll see in a moment that allows you to control whether both faces of an element are visible or whether only the front face is visible. So let me explain how these transforms work by building up this flip effect that you saw on the demo.
So first of all we'll start with the markup. And that's a pretty simple markup, we've got a div for the container, and then that has a div inside of it which is the div that represents the card. We're calling this a card because it's kind of like a playing card with a front face and a back face.
And that card has a JavaScript onclick handler that simply toggles the class name on the card, and we'll see why in a moment. And inside the card there are two other divs, there's a front face and then a back face. And the front face has the image in it, and the back face has the Wilco text.
And you'll notice we use two classes on those elements, they both have a common property which is their faces, and then one is the front, one is the back. So that's the markup we're going to use and we're not going to change that markup for the rest of this. I'm just tilting this in 3D just so you can see what's going on in the next steps. So now let's start building up this card by applying some three-dimensional transforms.
Now the first thing we have to do is we have to take the back face and fold it behind the front face. We're essentially trying to place these elements back to back, and we do that by a rotateY transform. Now in 3D you have three axis, you have Y which is up and down, X which is across, and then the Z axis which comes out towards the viewer. So here we're rotating about the Y axis which is the vertical axis, and we're rotating by 180 degrees so we're flipping it on its axis.
So now we've got these things positioned back to back, I've actually just separated them out here so you can see them more clearly. In actual fact, they would be sandwiched together, and here you can see the two elements. And in actual fact they're sandwiched together like this, but that actually has a bit of a problem, it's not quite the result we want. And what's happening here is these elements are actually sitting at exactly the same point in space, that co-planar. And then it's ambiguous for the rendering engine as to which one should show in the front.
And this isn't a problem with our implementation, this is a problem that's common to 3D, but we have a solution to it, and the solution is that property that I mentioned earlier which is the one that allows you to specify whether both sides or just one side of the element are visible. So that property is called backface-visibility, and it has a couple of visible or hidden.
Visible is the default meaning both sides will show, and then hidden is what we can set here. And what hidden does is it means that when the back face of an element is facing the viewer, that element essentially disappears as you can see here. The gray border is just so you can see where it would have been.
So now what we can do is we can sandwich these things together, and then we don't have any problems about which one is in front because the right one will display depending on how the card is oriented to the viewer, so this is much better. So we've got these two faces sandwiched together, now we have to actually build that flip effect. And the way we do that is to apply a class name to the element that already has the card class. And just here's a note about how we build up these kinds of demos, these bits of content.
We've found that a very powerful way to do this is to describe the states of the content using classes, and then we can write CSS that describes or that sets up the positions and the transforms on those elements based on those class names. This means that we have a really tiny amount of JavaScript, and the JavaScript is essentially just applying and removing those class names. So we're just using JavaScript as a little bit of glue in order to change the document between these various states, and of course we have transitions which will give us those animations between the states.
So it becomes a very easy way of coding up our content and getting really rich experiences with minimal amounts of JavaScript. Anyway, to get back to the example, when the card is in the flip state, we want the back side of the card to show, so the flip state has a rotateY transform on the card element. And then as you can guess, we want to have a nice smooth transition over one second that gives us the really cool rotation behavior.
So that's looking pretty good except that if we actually coded this up and did it, it would look like this, it actually looks flat. And the reason it looks flat is because we haven't described any perspective, there's no notion of depth in the scene yet. So the final thing we need to do is to set up some perspective for this on the container element.
And the container, if you remember, is the parent of the card. So we have a property called perspective, and the value here describes the distance of the viewer from the content, so a large perspective means the content behaves like it's a very long way away, so it's very little forshortening. And then a small value has much more forshortening, it looks like the element is coming right up against your face. So here we've chosen a medium perspective value of 800, and now with that perspective we have our final flip effect.
[ Applause ]
Okay, so let me summarize transforms. So two-dimensional transforms, just like CSS Effects or the other CSS Effects, allow you to do things in CSS that previously you would have had to burn into your image assets. You could do things like diagonal banners across the corner of a page, stuff like that, stuff that you would have had to generate images for before. Three-dimensional transforms open up a door to lots of really interesting interaction behaviors that you can code up in your web content. You can create some very interesting models that users can interact with.
And transforms, we found, combine very interestingly with transitions and animations, there's a really great synergy between the two And as I mentioned before, transforms benefit from hardware acceleration when they're running transitions and animations. So that gives you really good performance. Now let's see what we can do when we put it all together. And I'd like to invite Dean back on the stage to give the final demo.
[ Applause ]
Okay, so you can go nuts with this stuff, seriously, it's amazing. So let me jump back into the photos, the slideshow, and I'll skip ahead to where we were when we last met, so this is the point where we got off. Previously we just had 2D transitions in the slides, let's add some 3D ones.
The easy one is we could do a horizontal flip. You see a lot of these in keynote, another common one is the cube. Play that back. It's pretty easy, here I'm just setting up the rotation so that the incoming element is sort of transformed across to the side and rotated a little bit. You can do a fall effect. This one of my favorites, you can look at it in slow motion and say "timber."
[ Laughter ]
Rotating doors.
And this is again one of my favorites. You can say "Alohamora," for the Harry Potter fans. Now you notice this was a transition, there's something special about this element, the other ones were images, this is in fact a video.
[ Music ]
I can scrub. So just because these elements, HTML 5 media elements audio and video are native to the page, they undergo the same CSS Effects that every other part of the page does.
I'll just turn it down a little bit and let it play. Now someone mentioned that the approach we take when developing these demos where we try and describe a state on elements. Now I've set up the CSS to have a state on it that isn't applied yet, and let's see, what we'll do is we'll play a game. I want you to all think as hard as you can, you've got to try and push the page away from the screen.
At the same time I'm going to sort of grab it and give it a little twist. So you can see what happened there is this is just a state where I've set the translation in Z which is between you and the screen, I've set it to be about negative 1,000 pixels, and I've given it a rotationY of about 30 degrees around the Y axis which is up and down. And you notice that the video is still playing.
[ Music ]
[ Applause ]
But wait, there's more.
[ Laughter ]
So this is a pretty simple page. Let's look at it in terms of the number of elements in the page. We've got a back draw, we've got a navigation menu down the side, we've got the photos or the video elements, and we've got the thumbnails on the bottom, so that's four elements. So let's take a look at that.
Whoops, I went back, let me go back again. You can see it's split out into 3D mode. And again, all the elements are still interactive.
[ Music ]
But wait, there's more.
[ Laughter ]
So this is still really a normal regular webpage, I can actually interact with it any way I want. So we can actually see around the back.
[ Applause ]
So you remember the flip effect, we saw it from front on, we can actually see it from side on here and you can see how it works in 3D. And actually really see, as Simon mentioned, that the back of the card has the text, and then we flip it around. You'll notice you can still see the video playing backwards through the slightly transparent element.
[ Music ]
Okay, so again, at the start we had these transforms that were sliding the photos around. Let me just try and do one of those, and you can see exactly how it was in 3D. When it was flat it was sliding in from the left side, but when we slightly rotate it we can actually see it come in to the right place. And again, you know, down. And we go to a crossfade that just happens so let's back out.
Whoa. And it gets the page to work, I didn't do any tricks, this wasn't a special mode in the browser, this is all done JavaScript and CSS in the page. So like I said, you know, these things give you incredible power. It's just so much fun to code with them, so that the world is the limit, you can do whatever you want. As you may notice, it's kind of easy to get carried away.
[ Laughter ]
[ Applause ]
Thanks, Dean. So Dean was working on that demo at 4:00 this morning, and I saw one of his checking comments, and his checking comment was "I think I may have gone too far."
[ Laughter ]
Totally. No, it's great. So I talked about CSS Effects we can do on text and images, with text and images, static effects.
And what I did mention at that point was all of these CSS Effects in the first section are fully supported on Safari on iPhone and Safari on desktop, in Safari 4. And then I talked about transitions and animations, and again, those are supported in both places too. And right in the beginning I was talking about how transitions are useful for communicating the changes in state in your page and really how easy they are, and that's the key point, is transitions are really easy.
With one line you can get these really nice effects on your page. Then in the final section I talked about two-dimensional and three-dimensional transforms. And again, these allow you to use CSS instead of using static image assets on your webpages. 3D is really great for doing very neat interactive stuff like you saw on the demos.
And these interact really well with transitions and animations, those things work great together. We've got some other things we can do, that we can integrate with our web content too, we've got audio and video as you saw in the demo, it was first class citizens in the webpage. And the key point here is that all of these features that I've talked about are fully integrated into the web engine, so they all work seamlessly together exactly how you would expect.
And you know, go nuts, they're all inside of WebKit. We really want to see what you can do when you use all these CSS Effects, animations, and transforms. So if you want to jump in and get started and you have questions, you can email Vicki Murley or Mark Malone if it's more iPhone related. And there's a bunch of documentation on this on the Safari Dev Center.