Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2004-419
$eventId
ID of event: wwdc2004
$eventContentId
ID of session without event part: 419
$eventShortId
Shortened ID of event: wwdc04
$year
Year of session: 2004
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC04 • Session 419

Best Practices in Website Development

Application • 54:26

This best-practices session provides a comprehensive overview of Safari's Document Object Model, CSS, and JavaScript support. It will also include a discussion of common development pitfalls and techniques you can use to keep your content W3C-compliant and working across multiple browsers.

Speaker: David Hyatt

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

All right. Good morning. Welcome to session 419, whose official title is Best Practices in Website Development, but whose unofficial and, I think, more interesting title is Building Visually Compelling Webpages for Safari, as well as other WebKit applications. All right. Good morning. Welcome to session 419, whose official title is Best Practices in Website Development, but whose unofficial and, I think, more interesting title is Building Visually Compelling Webpages for Safari, as well as other WebKit applications.

So who are the primary consumers of WebKit technology? Well, the first and most obvious target audience is the website author. So in the first portion of the talk, I'm going to be outlining some best practices in website development that you can use when designing websites that you want to work in as many browsers as possible. In addition, some of you may be developing applications that use WebKit and may be interested to learn what kinds of things you can do when you're free of the cross browser constraint.

And then finally, some of you may have come from the dashboard session earlier this morning and may be interested in learning what kinds of tips and tricks you can use to make your widgets look really cool. So towards the end of the talk, I'll be covering some of the WebKit-specific enhancements that we've made that you can take advantage of when building your widgets.

So what I'm going to cover in order, I'm going to start by talking about web standards, what they are, and why it's so important to adhere to them when designing websites for deployment in multiple browser environments. Next, I'm going to talk about how to use standards well, in particular, how to use CSS to separate the presentation of your website from your website structure. And I'm going to demonstrate how doing so will result in smaller, faster, and more easily maintainable websites.

Then I'm going to get into some technical details and cover some basic styling techniques, modern CSS techniques that work in most browsers. And then I'm also going to cover some cutting edge techniques that work in WebKit, but that more importantly also degrade gracefully in browsers that don't support those features. And then finally, I'm going to cover some of the extensions that we've made to WebKit for you widget authors and WebKit app developers.

So what are web standards and why are they so important? Well, web standards are a set of recommendations released by an organization called the W3C. And what web standards define are the rules that browsers should use that they should adhere to when they're parsing and rendering HTML. And the reason these standards are so important is they basically provide a way of ensuring interoperability among all of the browsers that support the standards.

So the idea is that you can write once and expect your code to work, just work, on all of the browsers that support those standards. Now, an added benefit of standards is you'll find that if you use them well, you're going to end up with smaller and faster web pages in all modern browsers.

So the most obvious and well-known specification, of course, is HTML, the primary language of the web today. But in order to achieve richer presentational capabilities in HTML, as well as to achieve more dynamic effects or more complex behavior, there are some other specifications that you should be familiar with.

And the first of these is CSS, or Cascading Style Sheets. And what CSS is is a language separate from HTML but includable in HTML files that defines rules for how to define the look of your website or the theme of your website. So you can do things like set the font color, size, weight, set background and foreground colors and images. And you can define the entire layout of your page, as well, where elements go and how big they are. And this is a spec that's been around for a while, nearly 10 years. And the first version of it, CSS1, is actually very well-supported in all modern browsers.

Now, a second revision was released a few years later. And this spec actually added a lot of cool new features. But unfortunately, there were a lot of ambiguities in the spec, a lot of holes. So when browser makers tried to implement this spec, they ran into issues of having to fill in gaps in the spec. And so there were interoperability problems as browsers made different choices in their interpretations. So that led the CSS Working Group to produce revision 2.1. And this is the sort of definitive CSS spec, if you will. This cleared up a lot of the ambiguities.

It finally defined how a lot of the cool new features in CSS2 work. And it even drops CSS2 features that no browser maker had ever bothered to implement. So if you're looking to see what Safari supports, this is the definitive spec to read to find out how a web kit's going to behave when you use CSS.

Now, in addition, CSS3 is in development at the W3C. And although it's not yet a standard, Safari actually supports many CSS3 properties. And we've added even more-- we've added a lot of support for CSS3 in the beta in Tiger. So I'll be covering some of the highlights of Safari CSS3 support later in the session.

Now, another specification that you should be familiar with for achieving dynamic effects in your web page is the Document Object Model, or DOM for short. And what the DOM is is a collection of APIs that are accessible both from JavaScript in your web pages and now also from Objective-C in the latest WebKit beta.

And this API allows you to walk the structure of your page as a tree view. So you can iterate over the nodes in your page and look at element names, attribute names and values, and even query for style information in the latest WebKit beta. Now, in addition, the DOM is not just a read-only API. It's completely dynamic.

So you can actually change all of this information on the fly. So you can append nodes, remove nodes, change attribute names or values, or dynamically change style information. And those effects will take place in real time as you make those changes in your web page. So the DOM is a great way to achieve very dynamic and complex behavior.

Now, like CSS, it's been around for a long time. Before there was even a DOM standard, there was an informal collection of APIs that you could use to do some of these things. And so that's sort of been informally known as DOM level zero. And then over the years, there have been three revisions to the DOM spec, refining the behavior, adding better traversal mechanisms and support for custom events.

And in addition, there are also a lot of popular DOM extensions that have never found their way into any standard. And Safari actually supports many of those. Examples are the content editable attribute to do in-page editing, as well as methods for querying for the size and position of elements on your page.

So I've talked about what the big three standards are-- DOM, CSS, and HTML-- and why it's important to follow them. Now let's talk for a moment about how you tell the browser that you even want to adhere to web standards. So by default, if you leave off this special tag that you can put at the top of a document called a doc type tag, the browser is going to assume that you're sort of an old-style web page, that you're a legacy page, and that you aren't really supporting modern standards. And what browsers are going to do is they're going to go into their essentially worst mode of rendering, a compatibility or quirks mode.

And what you're going to find if you leave this doc type off in your web pages is that the various quirks in the browsers actually are not going to be the same. Some browsers are much quirkier than others. So what you'll find is that you may test in one browser and inadvertently trigger quirks that you didn't even know about in another browser.

So by putting this doc type in your web pages up front and most importantly specifying a modern version of HTML, specifically HTML 4 or higher or XHTML 1 or higher, you're going to let the browser know that you're a modern standards-compliant page, and you're going to trigger the browser's strictest mode of rendering.

And this is really important because all of the browsers will go into strict mode with this sort of doc type that I have on the slide behind me. And when they do so, the rendering of the browsers differs a lot less. So this is just something that you can do to not only make sure that when you read a spec and then try the feature out, it actually works the way the spec says, but it'll also guarantee that your site will hopefully just work when you bring it up in browsers that you never tested it in before.

So let's say you've got this old-style website that's just HTML, and you're trying to modernize it, bring it up to date. So you've put the doc type in and triggered strict mode. Well, one of the things that's going to happen when you put that doc type in is the browser's going to get a lot more draconian in its error handling.

It's going to get a lot less tolerant of stupid mistakes that you make in your website. And so the onus is going to be on you as the website developer to check your web page for errors. And there are online tools at the W3C called validators that can do this for you.

And there's both HTML and CSS validators. And what they do is take your CSS and HTML files as inputs, and they'll print out a list, a nice list of all the errors and where they occurred in your file. So they catch things like unclosed quotes or misbalanced tags or bad tag nesting.

So if you run your site through a validator, you can basically ensure that it's structurally correct and minimize the number of errors in the page. Now, the problem is if you don't do this is you run the risk of having this error in your page. And of course, we wouldn't have a web if browsers just crashed every time you made an error. So browsers are going to try to second guess you and try to figure out what it was that you really meant.

But there's an infinite number of errors that you can make in a web page. And so it's impossible that the error recovery rules for any two browsers is going to be the same. So again, if you leave these errors in the page, you run the risk that your site's going to render differently in the various browsers as they recover from your errors in different ways. So make sure you validate your code up front.

Now, it's worth noting that validators can be a bit pedantic as far as their reporting of errors. So I'm not going to stand up here and say that your sites have to be 100% valid according to HTML and CSS. But you should eliminate the more egregious errors up front. Use validators with a dash of common sense. And at least make sure you have a well-formed DOM tree and stuff like that.

On the slide behind me now, I have documentation links to both the CSS and the DOM specifications. So again, you can go here and look at the DOM level 2 spec to see what Safari supports and look at the CSS 2.1 spec to get a feel for what Safari supports in CSS. And then the validator links are up here as well for both CSS and markup.

So let's say you've got this old-style website. You've now put the doc type in and triggered strict mode, and you've run it through a validator, and you've eliminated all the errors. So now you have a site that, technically speaking, is correct. It's well-formed. There are no mistakes in it.

But you haven't started using any CSS yet. In particular, all of your look is still achieved through old-style HTML tags. Because HTML was around before CSS, a lot of presentational features crept into the language before CSS came into existence. There's a lot of presentational tags and attributes whose sole purpose in HTML is to supply this presentational information.

And they said nothing about what your website actually should be structured like. They were just there to achieve an appearance. And examples of these tags are the font tag for doing font colors and sizes, the bold and italic tags, and then various attributes like the width and height attribute and colors and background colors.

Now, why is this presentational markup bad in your website? Well. For one thing, when you intermingle the presentational markup with your structural markup, you're effectively hard coding your presentation. If you find that you want to make any changes to the presentation, you'll have to get in there with this intermingled markup and make changes. And you might inadvertently introduce a structural error.

And then the opposite is also true. Maybe you're just wanting to change your site's structure. But it's hard to even tell what the structure is because the presentational tags are in the way. And you might even introduce presentational errors when you're just trying to change your website structure.

In addition, you can't define multiple looks for your site. There's no way to actually effectively theme your site because the presentation is mixed in with the markup. And finally, this presentational markup is a waste of bandwidth because frequently you'll have similar constructs on a web page, like, for example, the links in a nav bar. And maybe you're relying on a complex appearance with table cells and images or whatever.

And you end up using a lot of presentational markup per link. What happens if you always use this markup is it'll be duplicated in every construct on the page. So, for example, if you have 10 links in your nav bar, maybe you have 50 or 60 pieces of presentational markup that are all duplicated along with those links.

So this results in really, really large web pages, and it's a waste of server bandwidth, which will cost you money when running your website. And of course, this results in inferior performance in any modern browser because a web page that's larger, that has a bigger DOM tree, is going to take longer to parse and longer to render.

So to really hammer this point home, let's actually look at an example. And the example I've chosen is a typical weblog article. And I think a weblog is a very representative example, because a prolific blogger might have as many as 100 of these blog articles on their front page.

And we're even going to assume that a blog article is simpler than they often are. We're just going to say it has three pieces of information-- a header, which is like the title of the article, a date, which is when it was posted, and then the content of the article.

And what we want to achieve is a layout or appearance that I put up on the slide behind me. We want a slightly larger, bold title in a different color. And then we have a different font for the date. And we want the date on the far right, the title up on the far left, and then the text of the article slightly indented and underneath. So this is the layout we're shooting for.

So let's look at how we might do this using old-style markup. So you probably can't even read this, because there's so much of it. I mean, it's just a sea of bad markup. You have table cells used to do spacing. You have alignment attributes on the table cells to push things to the left and right. We needed multiple tags-- the font tag and the B tag-- just to make the header bold and maroon for the title.

And if I hadn't highlighted the three relevant pieces of structural information-- the title, the date, and the text-- it would have been hard to even see where they were in this web page. So if you wanted to make changes to the structure, look at how hard it would be. Because you'd just be messing around with this sea of presentational markup.

So now let's look at a good example. In this example, just ignore the CSS for a second and look at the HTML and look at how much easier it is to read. And look at how what it represents is exactly the structure of your website. You can think of your web blog as a container for a bunch of articles.

Each article is a container that has exactly three pieces of information-- a title, a date, and a body. And you can see that it's very easy to locate these pieces of information. And if you wanted to make structural changes to your website, it's fairly trivial if you move to this model. And now let's look at the CSS. So the CSS is where we've put the presentational information.

So for example, the title we've put in a different font, given it a larger font size, made it bold. And we've even said where it goes. We added the float left to say that it should sit in the far left. And we did that all with just one rule that can be used by all the blog articles on the page.

And you can see that there are similar single rules for the date and-- the body, basically, in achieving the layout that we want. And these two layouts basically look exactly the same. But this one will load about three or four times faster in a web browser-- in any web browser you try it in.

So a good example, observations. Well, first of all, it's just plain easier to read. If you have to get into either the presentational side of your website or the structure of your website, it'll be a lot easier to read and therefore a lot easier to maintain. information is shared. Because the rules in CSS can be applied to all of the articles on the page, you don't have the problem of duplicating a bunch of presentational markup. So those single rules apply to each article, and that's going to result in better performance.

Now, even more importantly, CSS can be reused across pages on your site. A typical web blog has archive pages that have the same look as the front page. And they can load the same CSS file. And then the multiple pages are even sharing information. So let's say your user browses to the front page of the blog. Then the CSS is going to get parsed and loaded for the front page.

And then the user is going to start browsing into your archives. And that same CSS is already ready to go. So by using CSS to share this presentational information even across pages, you're not only going to improve the performance of individual pages, but you're going to improve the performance of your entire website.

And this is going to result in significant bandwidth savings for you, because you're going to load the presentational information frequently once for a website and then share it across pages. And in addition, you're going to eliminate all of this presentational markup that would otherwise bloat your HTML files.

And of course, it's going to result in better performance in any modern browser, because there's going to be a lot less work being done by the browser to render your page. So what I'm going to show you now is a demo that's perhaps the ultimate example on the web today of the separation of structure and presentation. So if we can switch to the demo now.

Okay, so what a web designer named Dave Shea did is he made a very simple, basic piece of unstyled markup, which you can see behind me. It's just got some headers, you know, some list items down towards the bottom. And basically, this started off unstyled. It almost looks like we're, you know, we've traveled back in time to the year 1993, but not quite. Ah, there we go. That's better. Much more like Mosaic 1.0 now.

All right, so what Dave Shea did was he made this markup. And he said he challenged web designers to produce innovative and creative designs by styling this markup. And the restriction that was placed on all of the web designers was, you can't change this markup. You have to take this existing markup that I made and come up with a great design for it, all without being able to change the HTML. And the range and variety of designs that people have been able to produce using only CSS is just pretty incredible. and we can show you some of the better ones right now.

So we start with a newer design that was posted relatively recently that's sort of a more basic one. But you can see nifty examples like the fixed bar on the left, a much narrower column, a lot of interesting use of background images, and different fonts. But you can actually achieve a lot more radical effects with the layout than this. In this next example, the designer actually took the headings and the subsections and laid them out horizontally in columns. So remember, this is all the same markup. These web designers are all operating on the exact same HTML page.

And what this designer did was actually laid things out horizontally. But you can get even wackier than that. In this next design, the page is laid out like panels in a comic book. And so this is the Wiggles the Wonder Worm design. And that's actually real text that you can select. The text has been positioned within the panels. So what you're seeing is a really clever use of positioning and background images to achieve a layout that was just completely different from the previous ones that I showed.

So now we can go to another design. And this one contains an interesting technique that I'm going to talk about next. Notice how the headers of the sections, the text, has gone away, and what's there instead are images. So somehow the designer of this page, of the CSS, actually managed to get rid of the text that was in the markup and put an image there instead. And this is kind of a really clever trick. So what I'm going to do now is actually talk about how that was done. So if we can go back to the slides.

So this technique is called image replacement. And what image replacement is is pretty obvious at this point, having seen the demo. You basically are taking text in a web page, getting rid of it, and somehow replacing it with an image that you specified in the CSS file. And there are a lot of different ways to accomplish this, a lot of very sort of clever, clever hacks that people have come up with to use CSS to accomplish this. So I'm going to cover some of them. And just a reminder, here's what we're trying to do. The original unstyled markup had just an actual header, an H3 element. And what we're wanting to do is actually take that H3 element and treat it like an image.

So what's the point? Well, an obvious point, of course, is multiple themes. If you have the restriction that you can't change the markup, but the semantic meaning of the markup is header, what you need to do is somehow get an image in one design and text in another. So in order to support multiple themes with different looks, this technique is a requirement.

And you also don't have to change the markup. If the structural meaning of the markup, for example, in this file, those headers are headers. They're not images. If you think of the web page being displayed unstyled, those are headers of subsections. So you don't actually want to turn the markup into image tags because that's not actually what the structure of the website really represents.

Now, in addition, image replacement can actually save bandwidth because if you actually have-- say you're using a blog article example again, and you have comment and track back links, and you want to represent those as images, then you might be reusing the same image 100 times on the page.

And with CSS, you'd only specify the width and height and URL, source URL, one time, whereas with an image tag, you'd at least have to specify the source URL over and over again. So there's actually a minor bandwidth savings from using image replacement as well in certain scenarios.

So just a reminder, the reason we don't want to put an image tag in there is this is a header. Semantically, it's a header. It is not an image. If we were to throw an image tag in there, then now the onus would be on another designer to hide the image and put the text back in. So this is not actually what we're wanting to achieve. So we can't change the markup, remember.

So an amusing trait of these image replacement techniques is web designers like to throw their names on them like they're mathematical theorems or something. And with this one, this one wasn't even invented by the person who it's named after. In fact, I'm not even sure who invented it. I think Todd Farner is notable for saying that CSS should have a mechanism for doing this, a simpler one than all of the mechanisms that I'm going to show you, actually. So this first technique, the earliest one, is called Farner Image Replacement, or FIR for short.

And what it does is it adds an extra span to the markup in order to hide the text. So you can see that the H3 header has had a span placed inside it. And then what we've done is using CSS, we've set the display to none, which effectively hides the text and makes it not be rendered at all.

And then what we've done is taken the header itself and changed its width and height to match the width and height of the image. And then we just have put the image in as a background image on the header. So basically we ditch the text, resize the header, and put a background image on it to just make it look like just the image. So that's the trick.

Now there's, of course, a very obvious problem with this technique. I just preached that we didn't want to pollute the markup with unneeded tags whose sole purpose was for presentation. And that's what we just did. So a problem with this technique is it pollutes the markup with that span that you really shouldn't need.

It's also not accessible to screen readers. Because Display None is used to actually just get rid of the text completely, accessibility devices like screen readers won't be able to find the text, and they won't be able to speak it aloud. And then in addition, this technique doesn't work in browsers that support the ability to turn images off.

Because if the image turns off, all you've done is made the background image of this header go away, and the text is still gone. You've still hidden the text. So if you turn images off, you just won't see anything. So ideally, what you'd like is a technique that actually shows you the text again when you turn the images off.

So here's another second amusingly named image replacement technique, FARC image replacement. And this one-- Is that his real name? What was that? Is that his real name? That is his real name. OK. And what FargImage Replacement does is actually manages to get rid of the span with another clever hack.

And like the other replacement technique, it sizes the header to the width and height of the image and puts it down as a background image. But what it does with the text is instead of hiding it, it uses a CSS property called text indent. And you would think that you'd be shoving the text to the right, but for some reason what the hack does is shoves the text to the left. Very, very, very far to the left. Negative 5,000 pixels, in fact.

And what that does is basically makes the text render way, way, way off to the left, off-screen. But then furthermore, you can add this overflow hidden property, which tells browsers to clip anything that's outside your box. So what happens is the text gets shoved way out to the left and then clipped.

So the nice thing about this technique is it avoids having an extra span in the markup. And this one works with screen readers. Because the text is still there, just shoved way off into a wacky position, the screen reader can still find it, and therefore it can still speak it.

So the nice thing about this technique is it avoids having an extra span in the markup. And this one works with screen readers. Because the text is still there, just shoved way off into a wacky position, the screen reader can still find it, and therefore it can still speak it.

So this one is similar to the FARC one, but will work with images off. And the way it does this is instead of shoving the text far out to the left and instead of using a background image, what it does instead is creates a piece of generated content. This is a feature of CSS 2.1. And so this generated content is done using the second rule on the slide.

And so by making an actual image as a piece of content that actually gets put inside the header, when you turn images off, that content will go away and the text will get pulled back up. So the idea was to make the image sort of participate in layout and actually go away-- when it goes away, actually have it affect the layout of the text. So this example will work in Safari, Mozilla, and Opera, I believe, in the latest versions. And it avoids having an extra span in the markup, works with images off, and works with screen readers.

So another neat technique that is used on the Zingarden site that I'm going to cover is the sliding doors technique. Now, this is a neat CSS trick for making tabbed user interfaces. You can also use it to make rounded, for example, Aqua-style buttons. And the idea is to make these elements such that they still have foreground text that you could select conceivably or that's actual text that's accessible to screen readers as well. So these tabs can also participate in text zoom as well. And this technique was invented by a web designer, Doug Bowman. And you can read much more about this technique on a list of part.com.

And so I've got an image up here that is the layout that we're going to try to achieve just using CSS. So we're going to start with some markup. We're just going to start with a unordered list of links. And we're going to take that simple unordered list, and we're going to turn it into a set of tabs. So these are just like the links that you might have in a typical nav bar going to various subsections of your website.

So the concept is that each tab is going to use two background images, one on the list item and one on the anchor that was inside the list item markup. And the idea is like sliding doors, the images are going to go over one another. And the narrower the space, the more the two images are going to actually overlap. And then the wider the text on the tab, the less the images will overlap. So you can see this idea with some images here.

Now, on the images on the left, you can sort of see the concept of overlapping. You know, the narrower the text, smaller the text, the more they'll overlap. And then the wider the text, the less. And in the images on the right, what we're doing is using background images.

And background images are always only drawn within your element's bounds. So the idea is that you make these really large background images, and you'll just expose more and more of them in sort of the visible doorway as you do text zoom or as you have wider or taller text.

So the idea, the easy way to do this is to make the left image narrow and then have the right image be the rest of the background. So you sort of do the left edge that you want to achieve, and then all of the rest, the right edge plus your background pattern, goes into the second image. So you can see how you can use this technique to do aqua-style buttons or sort of rounded buttons as well.

And the idea is that the right image is going to be the one that slides behind the left image. And that'll just happen naturally by virtue of the fact that the anchor is a child of the list item. Or sorry, that the-- yeah, exactly. And then the wider the tab, the less the two images will overlap.

And you want your images to be tall enough to accommodate the maximal text zoom in browsers, which is typically about 300%. And then you want the right image to be wide enough to accommodate the degree-- you always want the two images to at least overlap. So your background image should be wide enough to accommodate the maximal width of text you're going to put on the tab.

So here's a lot of CSS that sort of just is housekeeping to set up the lists as objects that sit horizontally and don't have bullets anymore. And the relevant piece for the sliding door technique is the background URL. So you can see with the background URL, what we've done is specified the image. And we've also said the image should not be tiled, because we don't want it to repeat itself.

And for the list item, the image should be anchored at the right and the top. So you can think of it as being anchored on the right and then spilling out to the left. And those of you with high-powered binoculars in the audience can take a look at what we have so far on the slide. So now we add the second image to the anchors.

And this is like the other one, only we're going to anchor it to the left and to the top, and also set it to not repeat. Because remember, this image is narrow, so we don't want it tiling on top of the right image. And so the anchor has this left image, and it's going to slide over the background image of the list item. And once we add this rule, what we have now looks very much like tabs. And so now what we're going to do is switch to a demo and show you these tabs in action, so you can see what they look like.

So what you can do is zoom the tabs. We can see that they work with text zoom. And one thing that we're missing is we don't really have a notion of a current tab. All the tabs look the same when in reality, you know, you're always on some particular subsection of the site. So we can show you how you can use the sliding doors trick to actually add the notion of a current tab.

And what you can see is you can basically add rules that, again, just use the sliding doors technique to add a different set of background images for the Current tab. And when we do that-- And what you can see is you can basically add rules that, again, just use the sliding doors technique to add a different set of background images for the Current tab.

So that's sliding doors. It's a very, very simple technique. Now in addition, what we can do is-- I'm going to put in a shameless plug for HTML editing here. So what we're going to do is actually demonstrate content editable and show how we can actually edit the current tab. And again, this is sort of just demonstrating that it's all a dynamic layout and that everything will flow as you're editing.

All right, so now we can go back to the slides. So the CSS in Garden is a great site. I encourage you to check it out. Here is the URL that you can go to. And there are hundreds of designs there at this point. And it's basically-- especially if you're wanting to design dashboard widgets, look at these, study this stuff. Because all of these creative techniques, all of these things that these designers do, you can do in your dashboard widgets. So check it out.

In addition, there's a great website called a listapart.com. It's essentially an online magazine that regularly publishes articles on CSS. And that's where the content of this sliding doors section came from. And since the first sliding doors article, Doug Bowman's actually even published a follow-up. So I highly encourage you to check out a listapart.com and learn more about this technique.

So now that we've talked about more basic styling techniques that work in all browsers, let's start getting towards the edge of standards and talk about some cool CSS3 stuff that you can really use in WebKit to spice up your web pages. Now, one that's become quite popular on the web since we introduced it in Safari 1.2 is the text shadow property. And this property was actually originally in CSS2.

No one implemented it, except Safari got it in right before CSS2.1 became a standard. But unfortunately, it was not in time for them to actually put it back in. So it'll be returning in CSS3. So I'm effectively going to consider it a CSS3 property, despite it having been around for a while.

But what it does is lets you add really neat shadow effects to text. And a shadow consists of three components-- the color of the shadow text that's going to be behind the regular text, an offset, which represents the distance, the x and y distance of the shadow from the original text, and then a blur radius, which is sort of a fuzz or distortion that you can apply to the shadow. And the higher the blur radius, the more diffuse the shadow will be.

So here's a nifty text shadow example that's showing one trick you can do with shadows. This is an eclipse effect. And what I've done is made a red text shadow on the body, offset by four pixels, and then with a small blur radius. And the foreground text is black, and the background text is black.

But because there's a shadow, you get this sort of eclipse effect where the text is readable because the shadow is what's drawing. So this is just one of the nifty creative uses of text shadow. You can also use it more traditionally in text where the foreground color does not match the background. But this is a really great, simple declarative way to make text look better in your web pages. And if a browser doesn't support it, no harm's done. It'll degrade gracefully.

Another great CSS3 feature that Safari has rich support for is transparency and transparency effects. Now, this is basically the ability to make elements in your page partially transparent so that you can see what's behind them. Now, there is currently a cross-browser way of achieving this, and by cross-browser I mean in every modern browser except for WinIE. And this is, you can do this with transparent pings, which are images that can incorporate alpha channels.

And so that's a way of -- that's a safe way -- I should just say that up front -- that's a way of at least achieving transparency that will work in more browsers. Now, there's some more lightweight mechanisms, though, that can prevent you from having to make images just to achieve transparent effects. I'm going to talk about two of those. One is RGBA colors, and the second is opacity.

So RGBA colors are basically just a color specified as four components, a red, green, and blue component, and then additionally an alpha value. And the syntax looks kind of like a function in CSS. You basically say RGBA, parentheses, and then in a comma-separated list, you enter the red, green, and blue values and the alpha. And the RGB values range from 0 to 255, but the alpha value goes from 0 to 1.0, with 1.0 being fully opaque and 0 being fully transparent. So if you make the object fully transparent, you won't see it at all.

So here are some examples of RGBA colors. And I've basically put this up here to demonstrate that everywhere you can use a color in CSS, in WebKit, you can use these transparent colors. So this is a great way to apply transparency only to particular portions of your content.

In particular, you can make the foreground text red and 50% opaque. Or maybe you want to make only your borders transparent while the rest of your element remains non-transparent. Maybe you have a border and you want the background to show up behind the border. So that's a nifty visual effect you can achieve by using transparent borders. In addition, you can make a background transparent. Just use a transparent background color to get the content behind to show up. And then finally, you can even use opacity with text shadow. So you can actually make the shadow itself even be transparent.

But the really cool CSS3 feature is Opacity. And Opacity is a way to basically make your element, all its descendants, all be transparent as a unit. So background borders and your children all can become partially transparent with one simple declaration. So for example, if you wanted to make all of your articles 30% opaque, this is all you'd have to do. It's just a single property with a value that ranges between 0 and 1, just like the alpha value in the RGBA colors.

So now what I'm going to show you, we spent a lot of time talking about CSS, so now let's combine this with the DOM. I talked earlier about how the DOM was a great mechanism for achieving dynamic effects. So what we can actually do is take the support for opacity in modern browsers and use DOM and JavaScript to create fade effects when switching between our sliding doors tabs in the previous example. And what's even better is we can write this to degrade gracefully in those browsers that are unfortunate enough not to support opacity. And this example I'm about to show you works in both Safari and in the latest Mozilla 1.7.

So let's walk through how we add these fade effects. Well, the first thing we want to do is add a handler to the links such that when you click the link, we're going to call a function to begin our fade, to begin our fade out. So that's just done with a simple onClick handler attached to the links. And what we're going to do is assume that the content of the web page underneath the tabs is in a div whose ID is content. And that's what we're going to operate on as we do the fade out effect.

So what we have here is first we decided the fade is not going to be interruptible. So we're going to track that with a fade in progress Boolean. And if that's already true when the user clicks on a link for, say, a second time, we'll just return false, which indicates to browsers that you shouldn't follow the link. So that'll basically ensure that if a fade out is in progress, we don't stop it and start it again and visually stutter.

And then what we're going to do is actually a check, basically a check to see if the browser supports opacity. So what we do is we get our content element, and we just try to set its opacity to be fully opaque. and if that fails, essentially if we then query for the style that we set and we get the empty string back, we can return true, follow the link, and assume that opacity is not supported. But if you're using Safari in Mozilla, we can keep going. So what we then do is set the fade in progress to true.

And we set a timeout to continue the fade with a 25 millisecond value. So what this means is we'll get a callback very, very shortly that will allow us to start doing the dynamic effect. And another minor note here is we've also made this slick enough that if the user changes his or her mind about what anchor they wanted to click on, if the fade's in progress, note that we update the current anchor always. So that always ensures that the fade effect will just continue, and then you'll always go to the last anchor that the user clicked. And now, finally, we return false to indicate that we can't follow the link yet because we're going to be doing the fade-out effect.

So now let's look at the continue fade function. So this is very simple. We start off with our current opacity at 1. We're going to decide that we're going to fade out in basically 2% increments. So we subtract 2% from the opacity effectively. And if this puts us below 0, at or below 0, we're done.

So we set our Windows current location to be the href of the anchor, the last anchor that the user clicked.

[Transcript missing]

And then we set a timeout to keep continuing the fade. So we'll just keep getting called back and fading out further and further until we're finished. So now let's see a demo of this fade effect in action.

So what you can see here is we've got the same sliding door tabs, but now when you click on the home link, you'll see this really neat fade-out effect. And then if you click back on the news link, again, you see. So very, very slick, very, very simple, and it just adds some visual spice to the web page. And a user in a browser that doesn't support Opacity will never know that it wasn't there. All right, so we can go back to the slides.

So here's another new CSS3 property that we now support as of the latest WebKit beta, and that's support for text truncation. So instead of clipping text when it spills outside of a box, we can actually now render an ellipsis instead. And this is done with a new CSS3 property called TextOverflow. And TextOverflow takes two values, clip and ellipsis. So clip is essentially the default behavior, but you can actually change this to ellipsis to achieve the truncation effect.

And the basic idea, the common way that you'll use this sort of thing is when you have single line headers, or maybe even URLs-- URLs are another good example-- where you would like them to stay on one line. And you don't want to have some ugly visual rendering where they spill over the rest of your content. So what you do-- there's basically three very relevant properties here, not just text overflow.

For one thing, you could already have done overflow hidden to make sure that, say, a long URL was clipped so that it didn't paint on top of other content that you didn't want it to. So that's a good thing to just do in general, like, say, with the content section of a website, to keep the things in the content from spilling out onto, say, your blog roll or your sidebars.

[Transcript missing]

So I've covered basic styling techniques and then even gotten into cutting edge techniques in CSS3. Now let's sort of leap into the realm of dashboard and WebKit and see what we've done that's gone beyond the standards.

So one thing that we've done is we've added two new form controls that you can use. And those are sliders and search fields. And we've exposed those as form controls in a web page. Just like all the other form controls, they can be submitted, their values can be queried and set. And this gives you richer widget capabilities.

In addition, I encourage you to attend the WebKit session tomorrow, where Richard Williamson will be covering the advanced graphics effects that we've added for Dashboard. And those include image compositing, where we've added a new composite attribute to the image element to allow you to achieve more advanced compositing effects with images. And in addition, we've added a new canvas element to HTML that lets you do programmatic two-dimensional drawing, like lines and fills.

In addition, there's a lot of new advanced layout capabilities in Safari. It has a complete spring and strut implementation that's also implemented by Mozilla that allows you to achieve a lot of layouts that are currently not achievable in CSS and that are considered quite difficult by web designers, like the ability to easily center elements in the center of a viewport.

In addition, there's a lot of new advanced layout capabilities in Safari. It has a complete spring and strut implementation that's also implemented by Mozilla that allows you to achieve a lot of layouts that are currently not achievable in CSS and that are considered quite difficult by web designers, like the ability to easily center elements in the center of a viewport.

And finally, the big feature of WebKit is HTML editing. And that includes both editing of entire web views from WebKit applications and the ability to do in-page web editing using Content Editable. So to find out all about HTML editing, I highly encourage you attend the talk that's vaguely named Advanced WebKit Features on Friday. That talk's actually going to be all about HTML editing, as well as showing you how to use the DOM API from Objective-C.

So let's cover some of these new form controls. So the way you do a slider is with input type equals range. So that's all you have to do to introduce a slider. Whether or not it will be horizontal or vertical will depend on whether you make the width or height larger. Which dimension is larger will control the orientation of the slider. There are attributes called min and max that set the range of the slider.

There's a precision attribute that allows you to specify whether you want the slider to report float values by default or integer. If you basically make it report integer values, it'll always lock to an integer value, even though you're doing continuous slider dragging. And then, of course, the value attribute that nearly all of the form controls support can be used to query for the value and set it. And this slider can participate in form submission by submitting its value.

In addition, we've added support for the input event. This is an event also supported by Mozilla. And we've added it not only to sliders but to text fields. And this event fires immediately when you're typing. And for sliders, it fires immediately when you're dragging. So the basic idea behind this new input event is if you want to have things happen live or in real time immediately, this is the event you want to use. And so for sliders, it'll fire whenever the value changes, for any reason.

So here's a great, really tiny slider example that sets the opacity. So here we have a slider, a floating slider, that goes between 0 and 1.0. Remember, 1.0 is fully opaque. 0 is fully transparent. It will say it starts off at 0.5 right in the middle. And we have an onInput handler that grabs the content div from the previous example and just sets the opacity to the current value. So it's that simple. And if you were to put this in your web page and the user were to drag it, you'd You'd have a neat dynamic transparency effect.

So another cool widget we introduced is the search field. And this is basically just a HTML way of getting to the functionality of a Cocoa in a search field. So this is done with input type equals search. The incremental attribute controls live searching. You just have to put that attribute with no value into your HTML, and the control will be live.

There's a results attribute that you set to the number of results you want to remember, and that will remember previous searches. In addition, you can give an autosave name with an autosave attribute that tells-- basically is an identifier that's used to store the results of the search. And what's neat about this is you can even say something like autosave equals Google, throw this thing on your website, and everybody who wants to implement a Google search field can use a common autosave name, and all of those results will actually be shared among those search fields.

The placeholder attribute is used to control the grayed-out text that you see in the search field before you begin a search. And then finally, there's a new event. Because the NSSearch field has a rather complicated heuristic that it uses for determining at what time you should begin the search, rather than force you to put in key handlers and click handlers and all of that garbage, you can just listen for a search event, and it will fire exactly when it's supposed to, making it easier for you to implement.

And it just fires exactly when you're supposed to perform a search, and you can do whatever it is you'd like to do. What's really kind of nifty about this that may make it interesting to use on websites is that an unrecognized input type actually results in a text field in other browsers.

So that means that you can actually use a search field if you just want to get the different look with, say, storing results using a magnifying glass icon. If you maybe just want to achieve that different look, you can safely use this in a web page, because other browsers will still show a text field.

So this degrades gracefully in other browsers that don't support it. And here's just a very simple example of a search field that's incremental, so it's live, with a little placeholder string that says, click here to search, and then some action that you would perform. An example is, of course, that we'll show in a minute, is the dashboard widget for searching address book.

So let's put it all together with these enhancements and sort of start looking at the Safari RSS feature as well as dashboard from the perspective of this is just an HTML page with some slick new features in it. So what we can do is start by going to an RSS feed.

And what you can see here is there's some truncation in action. If you resize the window to be really, really small or just zoom the text, you can see that the headers in the Safari RSS actually are truncating. And they're just doing that with the text overflow property. This is just a web page that's been generated by the RSS engine.

And in addition, there's some very complex layout at work here. There's a spring and strut layout on the header and date, as well as to do the vertical stacking of the articles and to participate in the slider. So you can see there's a slider widget up there. If you drag it, there's a really neat dynamic effect that can be achieved. And note that it's actually a fairly speedy effect. And you can do everything that this page is doing you can do. This is all open. This is all there in WebKit for you to use.

And so now what we can do is actually look at a dashboard. So we can bring up dashboard. And we can show, let's demo drag and drop. So if you drag the address book out slowly, note how the drag image started off as the address book and then we dynamically updated it.

And we even did a fade as we dynamically updated it. So the drag image for the widget actually slowly faded in. And then when you drop it, of course, you get the whizzy ripple effect. And you can see the, this is just an HTML page. And you can see the search field, input type equals search in the bottom right.

And you can type things like last name. And you can even click on the magnifying glass and you'll see, hit enter. Oh. Bug. There you go. And you'll see that it will start storing results for you. It's incremental. So all of this is very straightforward, very simple, very easy to use. And so back to slides.

[Transcript missing]