1. Introduction to CSS3 and Modern Web Design

CSS3, the new, modular version of the CSS3 spec, contains many awesome new features that will make your web design work easier, more flexible, and more interesting. What’s not to love? Browser support is not complete yet, but many of the features have enough support to be useful in a production environment, and you can work around nonsupporting browsers.

In this chapter I’ll provide the rationale behind why the new version came about and gently preach a manifesto of modern web design to you. Then I’ll provide a brief roundup of the CSS3 modules before examining some of the general new features of CSS3 that are useful to explore as background knowledge before you go any further.

Why CSS3?

CSS3 has been around for longer than you might think. In fact, work had started on the earliest parts of CSS3 at about the same time as the CSS2 spec was being finished in the late 1990s. CSS2 has many very powerful features, and you can do a lot with it, but it was clear all those years ago that despite this a number of features were missing from the spec. This was evidenced by the fact that web designers tried to do many tasks using weird and interesting hacks or unusual techniques, often involving lots of nested <div>s or other semantic backstabbery, images, or even proprietary technologies like Flash. Some examples that spring to mind include:

• Font embedding. Downloading custom fonts for use on websites has been available in Internet Explorer (IE) since version 4 but wasn’t standardized until years later with CSS3 web fonts. Before web fonts gained popularity and cross-browser support, web developers used to rely on all kinds of weird replacement techniques, such as image replacement and siFR (Scalable Inman Flash Replacement—see http://en.wikipedia.org/wiki/Scalable_Inman_Flash_Replacement) if they wanted custom fonts in headings.

• Bulletproof CSS. Back in the late 1990s and early 2000s a lot of pioneering techniques started to spring up for creating CSS UI features that wouldn’t break if the text was resized. The text wouldn’t spill messily out of its containers; instead, the design would expand along with it. These techniques were referred to as “Bulletproof CSS,” and they worked well if done properly. But often they required a number of nested <div>s, each with a single background image hung off it. Bulletproof rounded corners on a container required four nested <div>s! Such designs were inflexible as well. If you wanted to then change the color of the background, you’d have to go back into your preferred graphics editor and update all the background images each time. This is exactly the kind of problem that properties like border-radius were created to fix.

• Multiple column layouts. It is very common to use CSS floats to create multiple column layouts; this everyone knows. But this is somewhat of a hack. Floats were never originally intended for this purpose. They were intended for simple magazine layout image floats.

• Dynamic UIs. Many “dynamic UI features,” such as layouts that automatically adapt to different screen widths and smooth animations and transitions for user feedback, have been traditionally done using JavaScript. There was no way to achieve them using CSS alone until recently; hence, the rise of DHTML in the late 1990s (yuck!) and more recently, the overwhelming popularity of JavaScript libraries, such as jQuery and Dojo.

And the list goes on. CSS3 was created not to give users a completely new set of amazing features to play with and create “spangly web innovations” (a great design agency name if ever there was one), but more to provide users with standardized, more flexible ways of solving existing problems.

There are now more than 40 modules in CSS3 at various stages of completion and browser support. The modular system is beneficial in many ways. It makes CSS3 easier to write by the spec teams and implement by the browser vendors: It is always easier to tackle small chunks than a single giant monolith. It also makes it easier for web designers and developers to get their heads around, and in my opinion, it makes it easier to “sell” to clients who may have issues about using “unfinished” technologies in their sites (yes, CSS 2.1 was technically only finished in 2011, but hey).

Modern Web Design Philosophy

I am a great supporter of CSS and the rest of the open standards landscape. The last couple of years have been very exciting for open standards. You’ve seen browsers leap forward in terms of rendering speed, feature support, and so on. New web technologies like CSS3 and HTML5/WebGL really do allow you to create some amazing digital experiences (Figure 1.1).

image
image

Figure 1.1 It’s highly impressive to be able to create web pages like this, just using open standards (see http://operasoftware.github.com/Emberwind and http://helloracer.com/webgl).

But everyone needs to take a step back when considering such innovations and not lose sight of the original qualities and best practices that made the web great, such as accessibility, usability, and graceful degradation.

Accessibility Comes First

In terms of my perspective on web design, I am really a “web 1.0” kinda guy. Innovative technologies are exciting, and you can fully appreciate their importance in the evolution of the web. But what is more exciting is the universal nature of the web. It’s the fact that you can take the same content, style it in a million different ways, and still have it remain accessible to all web users the world over regardless of how they use the web—be it on a mobile phone, using only keyboard controls, or via a screen reader.

It is something designers and developers shouldn’t lose sight of, but often we do. Whenever an exciting new web technology comes to the forefront, too many sites tend to pop up that go wild with the shiny and forget about the basic tenets. Recently, you’ve seen a sad reemergence of “This site is best viewed in...” messages, which should have been eliminated after the original browser wars ended a decade or so ago. And what about important text content rendered in <canvas>, which is therefore inaccessible? And how about CSS3 features that could work across multiple browsers but don’t because the designer has only used the -webkit- prefixed version of the property? That designer might say, “Oooh, but it’s an app; therefore, it’s important to lock out anyone who isn’t using a device of the correct level of shininess” (Figure 1.2).

image

Figure 1.2 “Best viewed in Google Chrome” sounds like a step back to the days of “Best viewed in IE4.” Now, I’m not saying that all content should be accessible to all people: It is not always that simple. But you should make such allowances whenever possible.

Usability Next!

Once your users have managed to access your content and services, can they make sense of it and glean the information they wanted from it? This is a simple, perhaps obvious point to make, but I’ve lost count of the times I’ve gone to a company website and scratched my head in vain while trying to find contact details, opening times, or an address. Instead, I find nothing useful amidst the sea of marketing BS, cheesy videos, and other propaganda being presented.

Why do people not think more about what information is most useful to people viewing their websites and how to present that information in an easily digestible way? A simple, well-written, and clearly available bit of copy is nearly always more effective than reams of flashy, whizzy, technical stuff.

My mantra for usability (and many other people’s, too) is “don’t make me think.” Don’t make your users think about how to get what they want. If you’ve not already read it, Steve Krug’s book Don’t Make Me Think: A Common Sense Approach To Web Usability, 2nd Edition is essential reading.

Graceful Degradation and Progressive Enhancement

Graceful degradation and progressive enhancement were two terms that first became popular (or at least noteworthy) about a decade ago. Both were used when talking about what happens to content when the browser viewing it doesn’t support all the features used to create it.

Graceful degradation means that the content falls back to something simpler but still perfectly accessible and usable. So, for example, if a content box is built and then styled using lots of CSS3 glitz, older browsers should still be able to display the text in a readable form, even if it doesn’t look as nice.

Progressive enhancement means that the base content is accessible by all, but then usability and stylistic enhancements are built on top of that base for those browsers that support those enhancements.

These are design philosophies that I have always held dear. They have not always been easy to uphold, because you often meet clients who are “obsessed with pixel perfection across all browsers” or some similar weird fetish. But they are certainly becoming cool again, especially with all the CSS3 features to make use of and lots of mobiles and other alternative browsing devices to make your content work across. Oh, and IE6, 7, and 8 still have significant market share and often need to be supported.

The wide variety of new devices you have to support these days (mobile phones, tablets, TVs, etc.) actually makes things easier in terms of clients craving pixel perfection across all devices: It is impossible for sites to look and function the same across all desktop and mobile platforms, and indeed it doesn’t make sense (as aped by dowebsitesneedtolookexactlythesameineverybrowser.com, seen in Figure 1.3). It is all about context. What makes sense on a standard desktop computer might well provide a bad user experience on a touchscreen mobile device or tablet.

image

Figure 1.3 Dan Cederholm said it best with this cheeky little site.

The good news is that CSS3 is fairly easy to progressively enhance and gracefully degrade, and otherwise get to work OK across old browsers. Most of the features, if used in the right way, will degrade gracefully so that the base content will still be accessible in nonsupporting browsers. Also, there are mechanisms that allow you to build in support or provide alternative content if need be.

Thought Process for Content

A good thought process to go through when implementing shiny features on a website interface is as follows:

1. Create a base of accessible HTML content. The styling and behavior you build on top of this content should, wherever possible, be usability and stylistic enhancements, and not essential for accessing the content.

2. Consider whether you need to use all the cool, cutting-edge technologies or whether you just want to because you’re a cool kid who wants to be in with the in crowd.

3. Check whether your proposed implementation will gracefully degrade while leaving the base content accessible.

4. Test whether the content is accessible and OK looking across varying devices (e.g., different screen sizes, control mechanisms).

5. In cases where the content is not accessible without the CSS3, WebGL, or whatever, or not accessible to certain users, do your best to build in alternative mechanisms that will provide access to that content.

You should constantly look at making content work for as many users as possible by:

1. Keeping graceful degradation/progressive enhancement in mind.

2. Providing alternatives for inaccessible content using built-in features (e.g., alt text, transcripts for video).

3. Building in your own alternatives when no built-in mechanisms exist (e.g., feature detection and provision of alternative styles using Modernizr).

4. Using polyfills to provide support for features where none exists.

The rule I used for deciding what to cover in this book was to include a CSS3 feature only if it has support across at least two major browsers and if you can make designs employing it work in older browsers that don’t support it via polyfills, alternative content, graceful degradation, and so on. I’ve broken this rule a few times, but only when I thought a feature was very significant and likely to have more implementations soon, and when nonsupport didn’t completely break sites.


image Tip

A great site to consult for quick summaries of which CSS3 and HTML5 features are ready to use on production sites, and whether fallbacks and the like should be provided is http://html5please.us by Divya Manian, Paul Irish, et al.


CSS3 Modules in This Book

Let’s look at a brief roundup of the major CSS3 modules you’ll be utilising and their main features. You can find more details on the latest status of each module at the W3C CSS Current Work page at www.w3.org/Style/CSS/current-work.en.html. As you’ll see, many of the modules are not yet finished, but this shouldn’t stop you from using some of those features. Many such features are already supported in browsers, albeit with vendor prefixes (see the section “Vendor Prefixes” for more details).

The major CSS3 modules featured in this book include:

• CSS Color (www.w3.org/TR/css3-color). CSS Color defines the many ways to specify color in CSS3, including RGB (red, green, blue), HSL (hue, saturation, lightness), RGBA and HSLA (same as before but includes an alpha channel to specify transparency), and a separate opacity property to apply transparency to a whole selection of elements.

• CSS Fonts Level 3 (www.w3.org/TR/css3-fonts). As well as containing the definitions for downloadable web fonts (previously in a separate module known as, you guessed it, CSS web fonts), this module also contains definitions for other font-affecting properties, such as font-feature-settings. I won’t talk about many of these beyond web fonts, because many do not have much browser support yet. You’ll mostly meet these in Chapter 3.

• CSS Text Level 3 (www.w3.org/TR/css3-text). This goes hand in hand with CSS Fonts Level 3 to give you more power over your words! As well as housing familiar items from CSS2, such as letter-spacing and text-transform, CSS Text introduces new friends, such as hyphenation and text shadow.

• Selectors Level 3 (www.w3.org/TR/css3-selectors). Selectors Level 3 defines a much more powerful, robust set of mechanisms for selecting the elements you want to apply styles to than was available in CSS2. Pretty much all of these selectors have good support across modern browsers. These are discussed later in the “CSS3 Selectors” section of this chapter.

• Media Queries (www.w3.org/TR/css3-mediaqueries). The primary means by which you can now serve optimized different layouts of the same content to widely differing browsing devices—for example, wide screen and narrow screen. You’ll mostly meet these in Chapter 8.

• Backgrounds and Borders Level 3 (www.w3.org/TR/css3-background). Backgrounds and Borders defines anything to do with background and borders, including rounded corners (border-radius), drop shadows (box-shadow), and fancy border effects (border-image).

• CSS Multi-column layout (www.w3.org/TR/css3-multicol). CSS Multi-column layout defines an easy way to break up content into multi-column layouts that reflow nicely rather than having to hack it with imprecise floats. You’ll meet these in Chapter 7.

• CSS transforms (www.w3.org/TR/css3-2d-transforms and www.w3.org/TR/css3-3d-transforms). These two specifications define mechanisms for transforming the size, position, and shape of elements in two and three dimensions. I’ll mainly talk about these in Chapter 5.

• CSS transitions (www.w3.org/TR/css3-transitions). CSS transitions give you a way to smoothly animate changes in state, such as a change in link color or an increase in banner size on hover. You’ll mainly see these in Chapter 5.

• CSS animations (www.w3.org/TR/css3-animations). CSS animations allow you to implement Flash-style declarative animations using keyframes detailing different property values, which the browser then “tweens” between. These are also covered in Chapter 5.

• CSS Flexible box layout (www.w3.org/TR/css3-flexbox). Mainly intended for equally distributing the height or width of rows or columns, this module defines new values for the display property to allow more powerful layout techniques. This is supported to varying degrees across modern browsers, but it is definitely worth mentioning.

• CSS Image Values and Replaced Content Level 3 (www.w3.org/TR/css3-images). This module contains some useful features for controlling background images and replaced content, some of which is starting to be supported across browsers. I’ll cover linear and radial gradients among other features.

General CSS3 Features

To whet your appetite, let’s now look at some general CSS3 features. These features are grouped together because they are general features that you’ll meet time and time again throughout different chapters: They are useful in many different circumstances.

Vendor Prefixes

Vendor prefixes are not exactly specific CSS3 features, but at the time of this writing (and for some time after), you’ll meet them repeatedly when working with CSS3. The reason is that many of the modules you’ll be using features from aren’t finished.

The idea is that before a CSS feature is completely “finished” (e.g., the spec is not quite stable, and changes may be made before the final version), it can still be implemented inside browsers. At this stage, browser vendors add their own vendor prefix to the start of the feature and use the prefixed version. This allows each vendor to support the feature inside its own “sandbox,” as it were, so if the spec changes and future versions work differently, this won’t result in a single property that works differently across different browsers. As an example, CSS transitions are currently supported across browsers with vendor prefixes. A sample block of code might look like this:

a:link {
    background-color: #666666;
    -webkit-transition: 1s all;
    -moz-transition: 1s all;
    -ms-transition: 1s all;
    -o-transition: 1s all;
    transition: 1s all;
}
a: hover {
    background-color: #ffffff;
}


I’ve put the prefixed properties in my example in the order they are in for two reasons. First, it looks aesthetically pleasing to have the widest prefix first and the narrowest last.

Second, at the time of this writing, a number of non-WebKit browser makers were discussing adding support for -webkit- prefixed versions of some properties, as well as their own prefixed versions. By putting -webkit- first, you can make sure that if this happens, such browsers will end up using their own prefixed version if it is present, not -webkit-, because the others all appear afterwards in the cascade.

Using the correct prefixed property will always be better and more accurate than relying on faked -webkit- support, especially considering that in some cases you might feed the different browsers different property values because of varying support. For example, at the time of this writing Opera does not yet support 3D transforms, so you could provide Opera with this 2D transform that would work:

-webkit-transform: rotate3D(1,0,0,10deg) translateX(300px);
-o-transform: translateX(300px);

Why are other browsers considering adding -webkit- support? Because so many developers have been harboring an ill-conceived idea that WebKit is the only browser engine worth supporting. So they were using lots of CSS3 features only with the -webkit- prefix, thereby making those features arbitrarily fail in other browsers that support them. As far as users are concerned, it is the browsers that are at fault. The average site visitors don’t know any better, and neither should they be expected to. Messy as it is, non-WebKit browsers adding -webkit- support is a somewhat desperate potential measure to try to fix this browser support mess to some degree.

To sum up, it may sound nightmarish having to include five different versions of the same property in such situations. Quite a few people think that you shouldn’t use vendor prefixes at all in production projects, and that they are only for testing purposes (this is the W3C’s official stance too). But don’t let that stop you. As you’ll discover throughout this book, it is easy in most cases to retain an acceptable user experience in browsers that don’t support those properties, as long as you give it a bit of forethought!

If you want to use prefixed CSS3 features, please do so responsibly and use all the different prefixes for all supporting browsers. And don’t make your sites dependent on a particular feature that doesn’t have cross-browser support!


This transition shorthand property tells the browser to smoothly transition every property that changes when the link’s state changes over a duration of 1 second (see Chapter 5 for more details). In this case it is just the background color that changes. The aspect to focus on in this code is the fact that there are five copies of the transition property. The first four include vendor prefixes. At the time of this writing, you need to include these so the effect will work in Chrome and other WebKit-based browsers (-webkit-), Firefox and other Gecko-based browsers (-moz-), IE (-ms-), and Opera (-o-). I’ve also included the fifth—prefixless—property so that when browsers start to support the prefixless version instead of their own specific prefixed property, the code will still work for them, and you won’t have to update it unless the spec has changed since then.

There is no single correct way to order the vendor prefixes in your code, and different people have different opinions about how it should be done. I’m just presenting my opinion of what I think works best.

CSS3 Colors

The new CSS3 Color units (www.w3.org/TR/css3-color) are most useful, particularly because they allow you to programmatically define transparency for colors. This allows you to create advanced graphics and features that blend nicely into each other and their backgrounds without having to create loads of transparent PNGs all the time.

Table 1.1 shows what current support looks like.

Table 1.1 Browser Support for CSS3 Color Units

image
RGB and RGBA

RGB (actually available since CSS2) works in a similar way to hex values. You define red, green, and blue channels, but you do it using numbers between 0 and 255, not pairs of hexadecimal numbers:

rgb(255,0,0). image Equivalent to #ff0000 or red

rgb(255,255,255). image Equivalent to #ffffff or white

RGBA takes this a step further, adding a fourth value that specifies the alpha channel, or the opacity of the color. This value is between 0 and 1; 0 is completely transparent, and 1 is completely opaque:

rgba(255,0,0,1). image Full red with full opacity

rgba(255,0,0,0.5). image Full red but 50 percent transparent

rgba(255,0,0,0.2). image Full red but 80 percent transparent

HSL and HSLA

HSL—hue, saturation, and lightness—is a different way of defining a color, which makes a lot of sense to many people, especially designers who are used to using graphics editors. The syntax looks like this:

hsl(0,100%,50%). image Equivalent to #ff0000 or red

hsl(0,0%,100%). image Equivalent to #ffffff or white

The first value—hue—takes a value between 0 and 360. It’s basically a point around a standard color wheel circle.

The second value—saturation—takes a value of 0–100% and refers to how bright the color is; 100% is full color, and 0% is greyscale.

The third value—lightness—takes a value of 0–100% and refers to how light the color is; 100% is completely light/white, and 0% is completely dark/black.

HSL makes sense in a lot of ways; for example, you could select complementary shades of red to go with the preceding red color, just by varying the lightness, like this:

hsl(0,100%,30%) image
hsl(0,100%,40%) image
hsl(0,100%,50%) image
hsl(0,100%,60%) image

HSLA works in the same way as RGBA. You just add the alpha channel value to the existing color like this: hsla(0,100%,50%,0.5), which results in full red but is 50 percent transparent.

Opacity

A separate opacity property is available in CSS3. You can add it to any element to set a level of transparency for that entire element and everything within it, including all child elements. As you’d expect, it takes a value of 0–1:

opacity: 0;

This property makes elements completely vanish!

The content is still available in the DOM, just invisible to sighted viewers (in contrast to other methods of hiding content, such as display: none;, which renders the content inaccessible to screen-reader users). I mainly find this useful for hiding certain content and then making it appear again when you mouse over/focus on a certain area of the document, as in pop-up information boxes and suchlike.


image Note

Because old versions of IE do not support transparent CSS colors or opacity, you’ll need to make provisions for this by adding in support or alternatives. You’ll learn various ways of doing this throughout the book.


Sizing Text Using Rems

CSS3 introduces a few new size units (see www.w3.org/TR/css3-values); one in particular that seems stable and is getting good browser support is the rem, or root em. This makes text styling a lot easier because all sizes defined in rems are relative to the text size of the root element—<html>. Rems get rid of the complications caused by ems and percentages: They work relative to the sizing of their parent elements. So, for nested elements, you’ll often have to do all kinds of weird calculations to work out what values to use to get the font size you want. Consider the following example (see rem_example.html in the chapter1 code download folder):

<h1>Example <em>rem</em> exploration</h1>
<p>This example is written to show why the new CSS3 rem unit is useful. It allows you to much more easily size text and boxes, as rem sizing is always relative to the size of the <code>&lt;html&gt;</code> element.</p>

Here you can start off by sizing your text like so:

html {
    font-size: 62.5%;
}

h1 {
    font-size: 3em;
}

p {
    font-size: 1.4em;
}

This is simple CSS. You start with the tried and tested 62.5% font setting to take the base font size for the whole document down to 10px (62.5% of 16px, the standard default body text font size in all browsers). Then you set the <h1> size to three times that, which results in a computed size of 30px. The <p> is set to 1.4 times the size of the base font, or 14px.

The trouble starts when you try to resize children of those elements. If you wanted to, say, size your <code> element at 11px, how would you do that with ems? Well, 1.1em wouldn’t work, because it would be 1.1em of 14px (the size of its parent element). The actual value you need is 11/14 = 0.786em. Extrapolate this to more complicated and precise designs, and you’re looking at a whole load of complicated math and hair pulling.

Rems make text sizing a lot easier. If you instead used rems for these text sizes, everything would be relative to the font-size on the <html>. So getting 11px code font would be a matter of using the following:

code {
    font-size: 1.1rem;
}

Table 1.2 shows the current state of browser support for rem units.

Table 1.2 Browser Support Matrix for Rem Units

image

IE only supports rems since version 9, so support for older versions needs some attention. The best way to handle this is to provide fallbacks in pixel sizes so older IE versions at least get the same sizing, albeit with a lesser degree of flexibility. For example:

code {
    font-size: 11px;
    font-size: 1.1rem;
}


image Tip

IE6 and IE7 don’t resize text set in pixels, so for accessibility’s sake, if you are planning on using rems for text sizing, you might want to consider bumping up the text size just for these browsers using an IE conditional stylesheet (see Chapter 2.)


CSS3 Selectors

CSS3 features an entire toolbox of new selectors that allow you to select more specific elements for styling while nullifying the need for a lot of those arbitrary IDs and classes you tend to often include to select “the last item in the list,” or “the first paragraph in the post that always contains the introduction,” or even “the twelfth div across on the 17th shelf because I want it to be the prettiest.”

I won’t discuss every selector exhaustively. If you want a detailed reference for each one, consult a resource such as www.w3.org/community/webed/wiki/Advanced_CSS_selectors. Instead, I’ll provide a quick reference in Table 1.3 for all the selectors, and then showcase some of the most powerful and interesting ones (as well as some seldom-explored selectors first included in CSS2) to give you a good flavor of what selectors are now capable of.

Table 1.3 CSS Selectors Reference

image
image
image
image
image

image Notes

The word All in Table 1.3 means all the browsers you’ll likely need to support in most projects.

Some interesting new selector developments are in the CSS4 Selectors module, so keep checking www.w3.org/TR/selectors4 for the latest.


Let’s move forward and look at a few cases in point to illustrate why CSS3 selectors are useful.

CSS3 Attribute Selectors

CSS3 extends the basic attribute selector functionality by allowing you to select elements based on strings within attribute values. For example, you could select and style <img src="alert.gif"> using the following:

img[src^="alert"] {
    border: 1px solid #000000;
}

The ^ character dictates that this selector should select <img> elements only if they have the string 'alert' at the start of the src attribute value.

<img src="alert.gif"> could also be styled like this:

img[src$="gif"] {
    border: 1px solid #000000;
}

The $ character dictates that this selector should select <img> elements only if they have the string 'gif' at the end of the src attribute value. This is really useful for styling links that point to specific types of resources: You could perhaps add specific icons to different links depending on whether they link to PDFs, Word documents, and so forth.

You could also style <img src="alert.gif"> like this:

img[src*="ert"] {
    border: 1px solid #000000;
}

The * character dictates that <img> elements with the string 'ert' anywhere within the src attribute will be selected.

The Negation (Not) Pseudo-Class

The negation pseudo-class can be used to explicitly apply styles to elements that are not selected by a simple selector. Let’s say you wanted to apply a specific width to a number of form elements but not the submit. You could do this:

input[type="text"], input[type="url"], input[type="email"], select, textarea, etc, etc {
    width: 15em;
}

But this code is a total messy pain. The :not selector allows you to do this:

input:not([type="submit"]) {
    width: 15em;
}

You can put multiple simple selectors inside the parentheses separated by commas, like so:

input:not([type="submit"], [type="file"])

CSS3 Pseudo-Classes

Pseudo-classes don’t just select elements; they select elements in certain states—for example, a {} to select links, but then a:hover {} to select links only when they are being hovered over by the mouse.

CSS3 introduces some new pseudo-classes for you to sink your teeth into. My favorite, :target, allows you to select elements that are the target of the current page URL. This is very useful and allows for some cool effects, because it effectively lets you set styles to be applied when links are clicked. For example:

<a href="#target">Click me</a>
<div id="target">Woot!</div>

The page URL targets the <div> when the link is clicked. To style it in this state, you could use this:

div:target {
    ...
}

Note that you can see a real working example of CSS-only tabs using :target inside the target-demo folder in the chapter1 code download folder.

New pseudo-classes are also available for styling form inputs when the data is valid and invalid (see Chapter 2 for more about HTML5 forms). Funnily enough, they are:

input:valid { color: green; }

and

input:invalid { color: red; }

:nth-child allows you to select a repeating pattern of elements inside a continuous series—for example, several list items or several paragraphs or articles next to one another. Let’s look at an example:

<ul>
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
    <li>Fourth</li>
    <li>Fifth</li>
    <li>Sixth</li>
    <li>Seventh</li>
    <li>Eighth</li>
    <li>Ninth</li>
    <li>Tenth</li>
</ul>

To select list items, you’d do this, where n is a formula, number, or keyword:

li:nth-child(n)

To select just the odd or even list items, you’d do this (a very easy way to create the infamous zebra-striped table effect):

li:nth-child(odd)
li:nth-child(even)

Or, you could use this:

li:nth-child(2n+1)
li:nth-child(2n)

To create the same zebra stripes, let’s look at some other formula examples:

li:nth-child(5). Selects the fifth adjacent list item.

li:nth-child(4n+1). Selects every fourth list item, and then adds 1 to each result. So numbers 5 and 9.

li:nth-child(3n-2). Selects every third list item, and then subtracts 2 from each result. So numbers 1, 4, and 7.

nth-last-child does the same thing as nth-child, but it counts backward from the last element in the sequence.

nth-of-type and nth-last-of-type are very similar but have one important difference: of-type ignores any rogue elements interspersed within the repeated sequence of elements because the selection is done by type of element, not child number. For example:

<div>
    1. <article class="abstract"> ... </article>
    2. <article class="abstract"> ... </article>
    3. <article class="abstract"> ... </article>
    4. <article class="abstract"> ... </article>
    5. <article class="abstract"> ... </article>
    6. <blockquote><p> ... </p></blockquote>
    7. <article class="abstract"> ... </article>
    8. <article class="abstract"> ... </article>
    9. <article class="abstract"> ... </article>
</div>

The <blockquote> is child number 6 out of 9. If you used article:nth-child(2n) as your selector to select all the even-numbered children of the <div>, you’d select the <article>s in positions 2, 4, and 8. The <blockquote> (position number six) wouldn’t be selected because it is not an <article>.

If you used article:nth-of-type(2n) as your selector, you would select the <article>s in positions 2, 4, 7, and 9. The reason is that this selects by the type of element, not the child position. Therefore, in this case the <blockquote> is completely ignored and the even-numbered <article>s are selected. Yes, two of them are odd numbered according to my original numbering scheme, because in reality the <blockquote> exists and offsets their position. But article:nth-of-type(2n) ignores the <blockquote>, effectively counting positions 7 and 9 as 6 and 8.

Here are a few other pseudo-classes to quickly consider:

only-child. Selects an element only if it is the only child of its parent—for example, article:only-child wouldn’t select anything in the preceding example because there is more than one <article> child.

only-of-type. Selects an element only if it is the only sibling of its type inside the parent element. For example, blockquote:only-of-type would select the <blockquote> in the preceding example because it is the only one of its type present.

empty. Selects an element only if it has no children whatsoever (including text nodes). For example, div:empty would select <div></div> but not <div>1</div> or <div><p>Hi!</p></div>.

Pseudo-Elements

Pseudo-elements differ from pseudo-classes in that they don’t select states of elements; they select parts of an element:

first-letter and first-line. You can select the first letter inside a given element using the first-letter pseudo-element and the first line using first-line. In my King Arthur blog example (introduced in Chapter 2 and found in the king-arthur-blog-example code download folder), I’ve created a rather cool drop cap and first-line effect using both of these pseudo-elements in tandem (see Figure 1.4 for the result):

#main>article>p:first-of-type:first-line {
  font-variant: small-caps;

}

#main>article>p:first-of-type:first-letter {
  font-size: 400%;
  float: left;
  /* loads more styling! */
}

image

Figure 1.4 first-letter and :first-line in effect!

Generated content using :before and :after. You can use the :before and :after pseudo-elements to specify that content should be inserted before and after the element you are selecting. You then specify what content you want to insert or generate. As a simple example, you can use the following rule to insert a decorative image after every link on the page:

a:after {
  content: " " url(flower.gif);
}

You can also use the attr() function to insert the values of attributes of the elements after the element. For example, you could insert the target of every link in your document in brackets after each one using the following:

a:after {
    content: " " "(" attr(href) ")";
}

This is a great technique to use in a print stylesheet where you want to just show the URLs in the document rather than having them hidden inside links (useless on a printed page).

CSS3 Pseudo-Element Double-Colon Syntax

Note that the new CSS3 way of writing pseudo-elements is to use a double colon—for example, a::after { ... }, to set them apart from pseudo-classes. CSS3, however, also still allows for single colon pseudo-elements for the sake of backward compatibility. This is what I’ll be using throughout the book, although you might want to use double-colon syntax for better future proofing; it is really up to you.

Getting the New Breed of Selectors to Work Across Older Browsers

As you’ll have gathered, many of the new selectors available don’t work in those irksome older versions of IE that are still hanging around (like someone’s rhythmically challenged dad on the dance floor at a wedding reception). So what hope do you have of using these selectors in the real world?

As luck would have it, for situations in which you really need old IE support, JavaScript can come to the rescue in the shape of Keith Clark’s Selectivizr (http://selectivizr.com). It sits on top of an existing JavaScript library and adds support to IE 6–8 for many of the new selectors.

To add it in, download Selectivizr and apply it to your site. Then make sure you also have one of the compatible libraries detailed on the Selectivizr site applied to your page (I’m using NWMatcher in my example). The code will look something like this (again, check out my king arthur blog example in the chapter2 code download folder):

<script src="http://s3.amazonaws.com/nwapi/nwmatcher/nwmatcher-1.2.5-min.js"></script>
    <!--[if (gte IE 6)&(lte IE 8)]>
        <script type="text/javascript" src="script/selectivizr-min.js"></script>
<![endif]-->

And there you go! This CSS3 selector support for IE 6–8 works like a charm!


image Note

Selectivizr works only on CSS contained in external stylesheets, not inline or internal CSS.


Wrapping Up

By now I’m sure you’ve conceded that CSS3 is awesome, and that you should start to embrace it as soon as possible. You’ve read about the philosophy and general approach you’ll be adopting for this book, reviewed the main CSS3 modules you’ll be dipping into along the way, and learned about some general CSS features to whet your appetites. With all this information under your belt, you’re ready for the next chapter, which focuses mainly on markup—riveting material.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.144.214