CSS Effects, Part 1: UI Elements and Navigation

Session 503 WWDC 2010

You can use the latest CSS technologies to deliver a top-notch web experience in Safari on iPhone OS and the desktop. Discover how to use CSS to dynamically position, scale, or rotate any web page element in 2D space, create rich animated menus, and implement image-free mastheads and buttons. See how to optimize with CSS to take advantage of hardware-accelerated animations and reduce your overall page load time, and learn the best practices for creating content that degrades gracefully in older web browsers.

My name is Jing.

I will show you how you can create some great transitional animations that you would normally associate with plug-ins, with just CSS.

If you already have a site that works on the iPad, I will show you how you can use CSS to create effects that replaces the need for images, and your site will load faster and use less bandwidth.

So, first, I would like to take you through a very brief history of the Web, to show you why using these open Web technologies have become necessary.

So, in the olden days, websites were mostly about how much information you could get to the user.

And the challenge designers faced were how do I get all this text, all these documents, to the user.

But as the Web advanced, and there is more and more information, the challenges designers face are more of How do I organize this information?

and How do I attract the user and make an immersive experience so the user can absorb this information?

So, for a while, Web technologies have lagged behind these needs, so people had to turn to plug-ins like Flash to implement some of these great animated experiences.

But now, these open Web technologies have advanced enough that you can use them to create some very immersive sites.

And one of the advantages of using these technologies is that you will have a consistently immersive experience both on the Mac and on the iPad.

I keep saying open Web technologies.

Specifically, I am talking about HTML5 technologies.

You may be familiar with that term in two different ways.

It could mean the HTML specification, or, in this case, I'm using it to mean the technologies HTML, CSS and JavaScript.

In addition to working on the iPad, these technologies have a lot of benefits.

For example, they're lightweight, because they replace images and plug-ins.

That means your site will be smaller, it will load faster onto your user's browser, and especially for your mobile users, that means they'll see less money on their monthly bill.

They're also faster, because these technologies are built into the browser, and therefore optimized by the browser.

They're accessible, because all the text is searchable, indexable by search engines, and readable by screen readers.

And lastly, they intergrate well with older browsers.

So to show you some of these advantages, we've built a sample Web page, and I'd like to invite my colleague Mike Thole, who is also an engineer on the Safari and WebKit team, to show you how we created this great page.

[ Applause ]

Thanks, Jing.

So, like Jing said, we've created a demo site to show off some of these great technologies.

And we call it The CSS Site of Awesomeness.

The name may be just a little bit over-the-top, but it does a great job of showing off some of CSS's awesome powers.

So when you look at this page, the first thing that I want you to know is that there are absolutely no images used in this page.

It's all just CSS styling.

So let's take a look at a few of the elements, starting with this red badge on the left.

You'll notice it has a shadow, as well as a reflection, and it gives it some visual depth.

It actually looks like it's sitting on a plane.

If we look at the sticky, we can see a subtle light gradient on the bottom portion of the sticky, and a shadow underneath it.

And we combine these effects to make it look like the bottom width of the sticky is actually curled up.

The sticky itself looks like it's stuck to the page.

Even the paragraphs for the text have some visual depth to them.

They look like they're stamped into the page, using this Inset Shadow.

Next, let's look at the headline.

The CSS Site of Awesomeness.

You probably don't recognize this font, and that's because it's not a standard font that is usually used on websites.

It's not installed on most users' systems, so you generally wouldn't be able to use it.

Traditionally, if you wanted to be able to use a custom font like this, to brand your site, or get just the look you wanted, you would need to basically render your text into an image and then use that image on your page.

Here, what we're using is a CSS font face, which instructs the browser to go out, download the actual font, and use it to render this text.

So next, let's look at these buttons.

They have some nice, smooth interactions, where they it's called the accordian effect, where the one we hover over is expanded and the others contract.

And we implemented a variety of different submenu animations.

Please don't make four different animations on your own site; this is just for demonstrative purposes.

[Laughter].

I like that one; we'll see it again.

It's called the zoom-down animation.

So usually when you see these kinds of smooth interactions, you think, Well, that's not HTML; that must be some sort of a plug-in.

But with CSS transitions, you can do this all in the browser.

And another great thing about that it works on the iPhone, the iPad, and on the desktop.

So, as I mentioned at the beginning, this site is all done with CSS no images.

One advantage of that is that it makes your site more accessible.

I'm going to do a Find On Page for the word "awesome".

If that headline were rendered as an image, we wouldn't be able to find that.

I'm also going to look for the word "Javascript", or "avascript" since I'm missing my "J", and you'll see that it finds it even in that graphical red badge.

This isn't just useful for Find On Page.

It's also useful for search engines that are indexing your site, and for Voiceover, which is a screen reader, or any screen reader, to make your site more accessible for the visually-impaired.

And finally, another advantage of using these technologies is that it makes your site more lightweight.

So I just opened up the Web Inspector, which is a built-in developer tool in Safari, and you can see all the resources that we used to create this page.

You can see I have an index page, the HTML, a little bit of JavaScript, a couple of CSS files, and then the Lobster Web font.

Everything all together comes in a little over 70 kilobytes.

The vast majority of that is actually the Web font.

So without the Web font this would be like 15 kilobytes, which is really small.

If you took the more traditional approach of cutting up your images into a bunch of pieces and using that to render your page, which we did, it took 28 different images and weighed about 190 kilobytes at the end.

So this is less than half the amount of bandwidth necessary to give this page, which is really important especially on a 3G connection, where those 100 kilobytes could be several seconds.

And with that, I'll turn it back over to Jing, and she'll show you how to use these technologies on your own sites.

[ Applause ]

Thanks, Mike.

So Mike just showed you this really pretty page we've implemented with just HTML, CSS and JavaScript.

And in today's session, I will show you how to do three different things.

First, I'll show you how you can create some of these rich visual effects you see on this page for your site, without using any images.

Then, I'll be talking about giving you some tips and tricks you can use to make the text on your site searchable, accessible, and easily maintainable.

And lastly, I will show you how to create those animations you just saw in the menus.

So first, let's look at what types of visual effects are on this page.

For example, there's this effect on these paragraphs, where the paragraphs look like they're stamped into the page.

And there's also the gradient, the shine on the top navigational menu buttons, something that you've probably seen around the Web.

And then here's this really graphically-rich badge that's really eye-catching.

So I'll show you how to do each of those things.

So perhaps you've tried to create this paragraph style before, and if you tried to create this with images, you probably know that you need a total of nine different images to create such an effect.

And after you upload those images, you still have to position them correctly in your page, and it's just really a pain to implement and to maintain.

So, with CSS, you can do this exact effect with only two lines of code.

So with the first line of code, all you need to do is use the Border Radius property to add the rounded corners.

And this gives you the same rounded corners on all four corners.

So if you wanted different types of corners on each side, you could also specify a different radius on each different corner, giving you some kind of really funky shape.

Even cooler than that is that you can specify a different horizontal and vertical radii to make some kind of leaflet page look.

So this is really, really useful.

You can use this to create something similar to the sticky effect that we've created on our site.

All right, but let's go back to the basics, just having the round corners.

Now, the next thing you need to do is add the shadow on.

And you can use the Box Shadow property.

You may know this, but here the Box Shadow has a -webkit prefix.

I will explain why it has a prefix later, but all you need to know now is, you can start using this property now, and it will work on all current and future versions of Safari.

So, to add the box shadow, just specify the style, which means you want a shadow on the inside; the color, the horizontal offset, the vertical offset and the blur radius.

And this gives you a shadow, when put on top of a lighter background image, you get this inset look.

So say if you wanted your paragraph to jump out from the page, instead of set into the page.

You can still use the Box Shadow property without the Inset style.

And that will help you create a drop shadow.

So with only two lines of CSS code, you can create this awesome inset paragraph effect.

Now, let's take a look at an effect that you might have seen somewhere on the Internet, where navigational menu buttons look like they're shiny because they have this glossy sheen to them.

And you might have seen how they were made.

Usually they're made with a different background color and a semi-transparent image on top.

And together, they make this nice gradient.

So you can get rid of that image by replacing it with a WebKit gradient.

And it's very easy to do.

Just specify the type of gradient, the starting and ending points of the gradient, and the starting and ending colors.

So this creates a smooth gradient, which, if you're looking for the sheen look, is probably not enough.

So to add that sharpness to it, you can use a color stop between the front and ending colors.

So color stop, you specify where you want it to be and what color should be at that point.

So adding a few color stops, you can create this sharp sheen, which, applied to the background color, looks like the button you want.

And you can just replace that background image with this code.

And in fact, CSS gradients can replace any images you're using in the CSS styles.

So, you may be thinking that if you already had this made as an image, it's not really worth it to learn the actual line of code and to have to change all of it.

But CSS gradients can do some things that bitmap images can't.

For example, if you had a diagonal image, and you wanted to scale your element up really, really big, if you're using CSS gradients, you're preserving the quality of the gradient.

You still get that sharp line, which you can't reasonably do with bitmap images.

So, with just that one line of gradient, you've created an image for your glossy button.

Now let's look at this shiny badge.

This badge is really useful for calling out important things on your site, because it's very eye-catching.

It's very visually pleasing, and it's really useful for, say, highlighting a new feature or something like that.

So I'll show you how you can have a similar badge on your page.

So for this badge, there are several different effects.

There is a gradient that comes down from the top, there's this embossed border looking thing around the badge, and there's a reflection and a shadow, which together make the badge look like it's sitting on the flat plane.

So I'll show you how to do each of those four things in turn.

But first, if you're wondering how did I get the round thing, this is just applying a border radius to a square element.

That's the easiest way you can make a round element in HTML.

Now, let's look at the shine.

You're only seeing part of the effect here, because the rest of it is being clipped by the borders of the element.

So if you want to see the whole thing, it actually looks like that.

And this can be created using a CSS radial gradient.

And it's similar to a linear gradient, so you specify the type first, then you specify the starting circle for your colors, and then you specify the ending circle for your colors.

And just like linear gradients, you specify the starting and ending colors.

And all of this is being clipped by the borders of your element, creating a nice smooth gradient.

So to create that shine look, we'll do the same thing we did with the linear gradient, by adding some color stops.

And to make it off to one side, just adjust the radius a little bit and move the centers of the gradient off to the bottom right, so that you can only see the top left, giving you this very nice-looking shine effect.

So, radial gradients are great for creating a shine like this, but they're also great for creating dynamic borders on your round elements.

For example, this embossed border is actually a second radio gradient applied to your elements.

And you can do this by just comma-separating your radial gradients inside the background image.

Okay, so let's see what you've learned.

I've shown you how to create that shine and that border on your round elements.

So just with those two, you already have a very eye-catching, non-standard element on your page.

To go a step further, you can create some feel of three-dimensionality by using the addition of a reflection and the bottom shadow.

So let's look at the reflection first.

Using the Box Reflect property, you can specify where you want your reflection to be, how far it is from your element, and the mask for it.

The easiest thing to do is to make a white mask, and that just shows you a completely opaque reflection, which doesn't really look like a reflection.

So, to make it look realistic, you need something that fades out.

So you could use an image that has a color that slowly fades from black to gray, but as I mentioned before, you can use CSS gradients anywhere you use images.

So instead of embedding another image, let's just use a CSS gradient for this.

And that gives you the desired reflection look.

So the last thing you need to make this badge look like it's standing on the floor is the shadow.

And since you want the shadow to be a different shape than your badge element, the easiest thing to do is probably to just create another element using the CSS after pseudo-element.

And to make it look like a shadow, just give it a black to transparent gradient.

Now, now that we want to squish this, the way we would do this in an image editing program is to just drag the top knob down.

Well, you can do this kind of transforms also in CSS, using the Transform property.

So, there's four different things you can do with Transforms.

You can rotate your elements, you can skew the elements and slant them, you can make your elements bigger or smaller, also only bigger in one dimension, and you can also move your elements around.

And this is really convenient because Transforms don't change the layout of anything else on the page.

So going back to the shadow, all we need is a scale y to make the shadow really short.

And that looks like the shadow we want, but that's probably not what you want.

Because it's right behind your badge.

So to make it below your badge, just give it a transform origin of Bottom.

And there you have this nice, shiny badge that looks like it's standing on the flat plane.

[ Applause ]

So I've shown you how you can use some CSS effects to create some very graphical looks.

And actually, the things I've shown you are the only CSS properties you need to create all of the graphical effects you see on this page.

We did a little experiment.

How much more efficient is this, compared to using images?

We built this exact same design using images and we ended up with a total of 28 images and 190 kilobytes.

That's a lot of images to be managing.

So by using CSS, we've reduced the size of the page to zero images and half less than half of the size of what it had before.

And this was a really simple site that only had a few visual effects.

So imagine what you could do with your site.

Okay, so I've shown you how to create some rich visuals, and eliminate some unnecessary images, making your site faster.

Now, let's talk about how you can make some nice-looking text that's also maintainable.

So, as you can see, for the title of my page, I'm using a custom font, and also a glow effect.

And if you were doing this with images, you'd have a couple of challenges.

And one is that this font can only be used for static text; it can't be used for body text, or anything that is changing or is duplicated.

And you know, if you wanted to change, if you found a spelling mistake and you wanted to change it, then you would have to re-render the image and upload it again.

And this is a problem that a lot of designers face today.

It is how can you get pretty-looking fonts on your page, when there are only about a dozen common fonts between Windows and Mac?

So the great thing about CSS is that you can embed a custom font into your page.

So I had this font file, and before you embed, you should check to make sure that you have the rights to embed your file.

So I had this Lobster Font file that I have the rights to embed.

And all you have to do is specify the font face rule with the font family and the URL to that font file.

And using this font will be exactly the same as using any other font that you've been using, and this gives you a custom font that's still text, still easily editable, searchable and accessible.

Just one more small thing to really make your text stand out and give a really subtle glow: glows are done with the same thing as shadows, using Text Shadow.

So you just use the Text Shadow property with a white color and no offset, and that's your glow.

So in addition to being able to create shadows and glows with the Text Shadow property, you can also create another, different effect for your text.

Here in this badge, you see that the text looks like it's engraved into the badge, and that's just using a text shadow that's offset to the left and top.

It's that easy.

So those are just some tips to get your text working well, accessible, searchable, and easily editable.

Now let's talk about animations.

I said it earlier in the presentation: nowadays you really need animations to draw in your users.

And so far, you've done so much work making a great site that goes fast, that has accessible text, so you just need to add that final polish and really engage your users with animations when they're interacting with your site.

And we showed you four different effects we made with animations.

There's the menu that fades in, there's the drop-down menu, there's one that comes in one after another, and there's another one that goes "Bam!"

or something.

So I'll show you Mike and I, actually, together, will show you how to do some of these.

And they're really, really easy.

So first, let me explain how this is done.

All of these are done with the CSS Transition property.

And the Transition is something that makes an instantaneous state change into one that can happen over a period of time.

So let's look at this fading menu in slow motion to see what type of effect you can create.

So the menu is waiting for a button to expand fully and fading in.

And when the user hovers out of the menu, it disappears immediately.

So, to create this effect, the first thing you need to do is to define the starting and ending states for your animation.

And for a menu like this, your starting state would be the Mouse Out state, and the ending state would be the Hover state.

So on the starting state, you want your menu to be transparent, and on your ending state, you want it to be completely opaque.

Now, to transition between the two, all you need is the Transition property with the CSS property you want to transition, and the duration for which you transition it.

And this is a shorthand way for writing these two properties.

If you wanted to write them out separately, you can also use the Transition Property property, and the Transition Duration property.

So let's take a look at what this code does.

So it looks like the menu is fading in.

But it's not waiting for the button to expand fully.

So to chain your animations together, to make them wait for one another, you can use the Transition Delay property.

And here I know that button expands for a quarter-second, so I'll just add Delay of a quarter-second.

So now, what will happen is, when the user mouses into your button, your button would wait a quarter-second, and then become opaque over a period of a quarter-second.

When the user mouses out of your button, it will do exactly the same thing, because you're applying the same cell to both states.

So if you want a different animation on Mouse Out, you know, Mouse In, you can separate the animation.

So for example here, I want no animation on Mouse Out So what I would do is to take the Transition Duration and Delay and put it in the Active state.

That means when you're going from the Inactive state to the Active state, the transitions defined in the Active state will be used, and when you're going from the Active state to the Inactive state, the transitions defined in the Inactive state, in this case nothing, will be used.

So that's all you need to create this fade-in menu.

Now let's look at something that's a completely different effect.

This drop-down menu.

And let's look at it again in slow motion to see what it does.

So it looks like the button is getting bigger, the same as the Fade In menu, and then your menu items slowly get taller.

And the easiest way to do this is probably to just change the height of the entire menu.

And if you already have your fade-in menu, there's very little you need to change to get this completely different effect.

Just change the Opacities to webpage Transforms, and the Transition Property change the Transition property to the Transforms.

So you're transforming from a height of 0 to a normal height.

And that's just two and a half lines of changing code, and you end up with a completely different menu effect.

So CSS transitions are a great way to use, to prototype and to experiment with what types of effects you can have on your page.

Now, I want to show you the last two effects.

Those are really cool because they're coming individually.

But you're probably tired of hearing me talk, so I'm going to invite Mike back on stage to show you these things.

[ Applause ]

Thanks, Jing.

So like Jing said, I'm going to work you through implementing the third and fourth transitions.

Here I have the demo site.

We learned how to make these two, and now I'm going to show you how to make the Blinds transition Let's look at that one more time.

Do you see how each item comes in slightly after the previous animation begins, so it's one, two, three, four, rather than all at once?

And we have the same kind of effect here, except that they're zooming in, one, two, three, four.

So we have a second demo site, which looks exactly the same, except for these third and fourth buttons aren't yet implemented.

You can see, it just comes in instantly when I hover in this area.

So let's open the site up in TextMate.

So I've separated out the CSS for the transitions into this pretty small file, to make things a little easier to follow.

And I've got two selectors here, for the Blinds transition.

First here is the starting state, the standard state when the button is not hovered over.

And we're selecting each list item of the Blinds submenu.

And what we do to it is, we set Opacity to zero, its Height to zero, and we modify the Padding and Margins so its vertical dimension is zero.

This basically compresses each individual list item to a height of zero, which will move it up directly underneath the button and make it invisible.

For the destination state, when we hover over it, we want to of course restore the Opacity to 1, and we want to restore the Height, Padding and Margin back to its default value.

That's what we see today when we hover over this.

The menu looks right.

There just isn't a transition.

So, in a very small amount of code, I'm going to follow my nice to-do here, and add the WebKit transition property.

What we want to transition is the Opacity, Height, Padding and Margin, and we're going to set a Transition Duration of a quarter-second.

Just like we did for the other menu items, and we'll use a delay of a quarter-second, again, just like the other items.

So I'm going to save, go back to the demo, and now when I mouse in, you'll see we get a Blinds effect, but it's not exactly what we want yet.

They're all coming in at once.

We want them to come in one, two, three, four.

So to do that, what we really want to do is for each individual list item, to give it a different transition delay property.

So that each one is slightly longer than the one before it.

Now, we could do that manually, but I think it would be a little bit cleaner to use some JavaScript to do that.

So I have a JavaScript file here, and I already have a function stubbed out called SetIncreasingTransitionDelay.

It takes a container element, which is going to be the container of the list items, the initial delay, and the delay increment, which is going to be how much time we want to pause between one, two, three, four.

So let's implement this stub function.

I will cheat to avoid typos.

So, all we're doing is getting an array of the children, writing a varisome For loop.

For each child, it's going to set the transition delay property to be the initial delay plus the delay increment times the iterator, and we're going to append S because the units we're using here are seconds.

So that looks good.

But of course we need to actually call that somewhere.

So I've already got this in a thing called Load, which is called when the page loads.

And inside of it, I'm going to get the Blinds submenu, just using Document.GetElementByID.

And we're going to call the SetIncreasingTransitionDelay helper function on it, passing in the Blinds submenu, and we're going to use a quarter-second initial delay, and a .15 second delay increment.

So it's just that little bit of JavaScript, which is just setting up the CSS property.

It's not actually doing anything at animation time.

We can go back here, and there we go.

One, two, three, four.

[ Applause ]

And we're going to do this fourth button as well, and we're going to go back to the completed site to remind you of what it should look like.

And because I love seeing it.

So notice that when it starts out, the items are very large.

And then they get smaller, and zoom into place.

So what we're going to want to do is go back to our Transition CSS, go down to the Zoom area.

I have these same two selectors, one for the Unselected state and one for the Selected state.

And right now, I'm transitioning the Opacity from 0 to 1, but it's instantaneous.

There's not yet a transition here.

So the first thing we need to do is to make our items very large.

And we're going to use a Transform property to do that, and we're going to make it five times as large in both directions.

So that's the Transform property, where we scale 5 by 5.

I'm also going to make the Transform Origin be the top center, so that they all align underneath the button.

So if we just do this, we'll get something pretty ridiculous looking.

Whoops, wrong one.

We'll get something pretty ridiculous looking.

That's actually what we want as a starting state, obviously not as an ending state.

So let's modify the Destination CSS and reset this Transform back to a scale of 1 1.

So now, when we hover over it, we'll just see this standard, boring menu.

That's because we haven't yet implemented the transition to make the state change, transition nicely, rather than be atomic.

So that's very easy to do, as you've already seen, and we're just going to add the Transition property, this time with the WebKit Transform and Opacity as its value, and again with a duration of a quarter-second.

So with that change, we now have all of the items zooming down at once, which is pretty neat, but that's still not the effect we want.

And I bet you can guess what we're going to do now.

We just need to use our Helper function again, and set up a delay for each of those different list items.

So we get the Zoom-down submenu, just like we got the Blinds submenu.

We call our helper function, use the same quarter-second initial delay where we're going to make the delay increment a little bit smaller, because for this particular effect I just think it looks a little bit better if it's pretty fast.

So with that change, I'll reload, and there we go!

[ Applause ]

So you saw how we got four different effects with just the few lines of CSS, and it was all, I think, pretty simple to understand and explain.

So with that, I'll turn it back over to Jing.

[ Applause ]

Thanks, Mike.

That was awesome, wasn't it?

I hit the slide.

So, Mike just showed you how to create some really cool transitions, and you saw that there really wasn't a lot of code involved, and this is great.

Okay. So I'm going to go back to something I referred to earlier in the presentation.

I told you that I will talk about why some of these properties have the -webkit prefix.

And that's because CSS properties take a very long time to finalize, and during revisions, their syntax can change, and different properties, and different parameters could change meanings.

And as Web developers, you don't want your site to break if you're using these properties.

So that's why browsers have browser-specific prefixes.

This differentiates them from the finalized CSS syntax, so you can start implementing using these properties now, and have them work in the future.

All right, so we've bombarded you with a lot of information, and just as a summary, if you learned nothing else, remember that you can create a lot of rich visuals with CSS properties.

You don't for all the things that you think you might need images for, you actually don't.

You can also make your text more searchable, more accessible to screen readers, better indexed by search engines, and more easily maintainable by using custom text effects.

And you can really add polish to your site and differentiate it from the millions of other sites out there by using these transitions when interacting with the user.

So this is just a really small sample of all the things you can do with CSS.

And if you're interested in learning more, you should refer to the CSS specifications that have all the properties, and if you're a Web designer, A List Apart, if you haven't heard of it, is a really good resource site, talking about how to create great designs on the Web with open Web technologies.

And the Font Squirrel is also a really good resource for finding fonts that you can embed into a Web page, and they even generate the embedding code for you.

So all you do is click, copy, paste, and you're done.

If you have questions for us, you can contact our Safari technology evangelist, Vicki Murley.

You should also check out the HTML5 demos if you haven't already done so, and obviously also go to the Safari dev center and development forums to learn about all the features that we support.

And we also have many sessions coming up this week to help you build a great website.

So right after this session in this same room is CSS Effects Part 2, in which you will learn how to create amazing 3D transforms and keyframed animations, things that you see a lot in photo galleries.

If you're interested in how to really integrate your website with the iPhone OS, you should attend the Touch and Gesture Detection that happens tomorrow afternoon.

And we've shown you how you can inspect how much space your Web page is taking and how fast it's loading using Web Inspector.

And there's a session tomorrow morning here that teaches you how you can really take advantage of it to more streamline your Web development process.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US