9781430237891_CO-01.jpg

Chapter 5

Exploring Fundamental Concepts of CSS

By now, you should have a solid understanding of how to create web pages using HTML markup. You should understand how to encode semantic meaning into your page content, and you should be familiar with the concept of page elements and how these elements can be nested inside one another to give a page an orderly structure. Finally, you should also understand the basics of how a web browser interprets your HTML source code and determines its rendering. All of these topics were covered in the previous chapter, and all the concepts in this chapter will build on them.

In this chapter, we’ll take a much closer look at how the web browser actually displays elements inside its window, and we’ll discuss the specifics of how you can control this behavior. We’re going to dive into the world of Cascading Style Sheets (CSS). Before we get carried away writing code, however, we’ll first explain where CSS came from and why it’s such a powerful tool for web designers.

The origins and evolution of Cascading Style Sheets

Many web designers are surprised to learn that style sheets have existed in some form or another since the inception of HTML’s ancestor, the standard generalized markup language (SGML), back in the 1970s. This is because, even before the Web was born, documents marked up in SGML needed some way to encode formatting information in addition to their semantic meaning. In the early days of HTML, both this visual formatting information (called presentational style) and the semantic meaning were encoded directly inside the markup of each element. Over time, as discussed in earlier chapters of this book, this proved problematic for many reasons.

CSS1 is born

It was clear that the Web needed a better way to encode formatting information both to ease the development and maintenance of content already published on the Web, as well as to increase the capabilities of web browsers. What you know today as Cascading Style Sheets (CSS) was first formalized in 1994 by the joint efforts of Bert Bos and Håkon Wium Lie, two developers involved in the World Wide Web Consortium’s (W3C’s) presentational style debates. Together, with the support of the W3C’s HTML editorial review board, the CSS level 1 (more simply called CSS1) specification was officially published at the end of 1996.

Even then, CSS boasted some special features that made it especially well suited as a generalized presentation language. For example, CSS was not limited to applying stylistic information to web pages marked up in HTML; it could be just as easily applied to any other markup language. Today, CSS can be applied to such XML dialects as SVG (a markup language for describing vector-based artwork) and XUL (a cross-platform user interface language). Indeed, it’s this ability to separate the information about specific content from the information about how that content is displayed that gives CSS its power.

Another advantage that CSS held over other display languages was its ability to apply multiple style sheets to a single document. This allowed one document to inherit the declarations of all the styles in each style sheet it referenced, with each successive style sheet cascading on top of the others. This cascading effect—the fact that later declarations about certain styles can overrule earlier declarations about the same styles—is part of what gave CSS its name. Later in this chapter, you’ll see how this capability directly benefits web developers like you.

Best of all, CSS had an incredibly simple syntax that made extensive use of English keywords. This makes it easy to read and understand. For the same reason, as you’ll see here, it’s also easy to learn.

Followed quickly by CSS2

Even though the benefits of CSS were very quickly realized by the W3C and it took only another two years for CSS level 2 (CSS2) to become an official recommendation in 1998, it is only recently that reliable, widespread support for CSS in web browsers has given it a prominent place in the tool sets of web designers and developers. We know what you’re thinking: if CSS was this good this fast, why did it take so long to make it into mainstream web browsers?

For many years after the original release of CSS, it was difficult for web developers to make full use of this technology. Thanks to competition between the major browser vendors to one-up each other on features; differing opinions regarding what the standards should actually be; and in the worst cases, the complete failure to even approach support for said standards; it became nearly impossible for a professional web developers to be able to rely on the use of CSS for web design. At the time, web developers used a patchwork of techniques that relied upon nested table layouts, presentational HTML markup, and the implementation of proprietary browser features that required developers to write browser-specific code or else completely abandon support for certain browsers.

Eventually, with the numbers of different browsers on the Web rising and the seemingly endless browser wars causing developers even more grief, it was the release of Internet Explorer 5.0 for Mac OS 9 on March 27, 2000, that finally gave everyone a way to move toward standards compliance. Specifically, the new version of the web browser from Microsoft, written partly under the direction of Tantek Çelic, implemented a rendering engine (called Tasman) that provided a means for web developers to explicitly choose one of a number of possible “rendering modes.” Developers writing new code that conformed to the W3C’s published standards could then switch the web browser into a standards rendering mode. Older pages that would likely be incompatible with standards mode, however, would use a different rendering mode that became widely known as quirks mode.

Enter CSS3

Work on CSS level 3, which began immediately after the release of CSS level 2 in 1998, now started to hit the scene. CSS3 picks up where CSS2 left off with a series of modules where each is designed to do different things (e.g., in addition to formatting, CSS can now facilitate some basic animations, as well). Taking a module-based approach has made it easier for web browser manufacturers to implement different sets of features of the CSS3 specification at different rates (which is a good thing for us!).

A word to the wise, though: CSS3 is still a work in progress, so support for some of the things we’ll be talking about in this chapter and the next vary from one browser to the next. Sometimes, there’s a workaround, and other times not. More often than not, we’ll be using the more advanced CSS3 techniques to enhance the user experience, not to perform some essential function. So, if a link doesn’t scale up and rotate around, at least that link will still be clickable!

How CSS works

To a lot of people, CSS often looks like magic. Admittedly, it’s not easy to wrap your head around the idea that with two simple text files, one with HTML markup (that gives a page’s content meaning and structure) and a completely separate one with CSS rules (that define the layout and presentation of this content), you can end up with a visual display that looks nothing like the original. How can a humble text file full of CSS rules change so much about a web page so dramatically? Let’s find out.

Default browser styles

A style sheet is actually a pretty simple construct. Like HTML markup, a style sheet is just a plain-text file; but unlike markup, it contains no content of its own. A CSS style sheet is always applied to the content of some other document: it’s this other content that the CSS declarations affect. By itself, a CSS file can’t do anything.

Recall that in the previous chapter we developed a registration form for Summer Smash 2012 using HTML markup. Let’s use the content of that page and apply some styles to it. Right now, that form looks rather plain—but it’s not entirely devoid of formatting.

As you can see, you have a link at the top of the page (“Summer Smash 2012”), and the text of this link is blue and underlined. Beneath that, you have some smaller text (still linked) with the tagline of the event. We have some nice borders around our different sets of fields, and all form elements are displayed as they should be and are contained within lists.

So, if this is the page supposedly without any styling information, why is the page showing off some smarts about how you might envision these elements should look? The answer, my friends, is that each web browser has a built-in, default style sheet that it uses to display elements in the absence of all other styling information. Unfortunately, not all web browsers come with the same style sheet baked into them, which means that different browsers will display the same elements in different ways unless you define your own rules and override all the default ones.

Even though CSS brings with it incredible flexibility of presentation, the style sheets themselves must be constructed in a certain way, just as the HTML page you created in the previous chapter had to be written a certain way. But to start, we’ll use the default browser styles you just discovered to explain the syntax CSS uses and to show how style sheets are constructed.

Anatomy of a style sheet

A single style sheet can contain an endless amount of presentational information. This information is organized into a sequence of statements and organized by selectors, each of which specifies one rule (sometimes also called a ruleset) that is applied to all the elements selected by the selector. Rules do all of the heavy lifting in CSS; they determine what stylistic information to apply and where. When you create a style sheet, you spend most of your time writing these rules.

Each of these rules can be expressed in plain English; and in fact, you’ve already done so in the example of the default styles. For example, “a link’s text should be blue and underlined” is something a CSS rule might specify. Another rule might specify that “paragraphs should have a decent amount of whitespace between whatever is above and whatever is below it.” In CSS, you would write these rules like this:

 a:link {

  color: blue;

  text-decoration: underline;

 }

 p {

  margin-top: 25px;

  margin-bottom: 25px;

 }

This snippet of CSS is a valid style sheet. If you apply these styles to a web page, all links (we specified a:link specifically; we’ll talk more about that later with pseudo-classes) will turn blue and will have underlined text, and all paragraphs will have exactly 25 pixels of spacing above and beneath them. We used a couple of keywords in our style declarations here to make things easier to read (i.e., blue and underline). There are a number of keywords you can use in CSS, and a listing of color keywords can be found at www.w3schools.com/cssref/css_colornames.asp .

Of course, our approach here is similar to how most browsers display links and paragraphs by default, so what we’ve done thus far isn’t very exciting. However, what is exciting is that it’s not very hard to make a simple change and make all your links green or to change the number of pixels above or below your paragraphs. For instance, check out the changes in the following snippet, which are highlighted in bold:

 a:link {

  color: green;

  text-decoration: underline;

 }

 p {

  margin-top: 50px;

  margin-bottom: 50px;

 }

Now all your links will be green and underlined, and each paragraph will have exactly 50 pixels of empty whitespace above and below it. The previous example also illustrates how easy it is to change which elements in your page the declared styles apply to. For example, instead of making links underlined and green, let’s make your top headline element (<h1>) show up that way:

 h1 { color: green; text-decoration: underline; }

 p { margin-top: 50px; margin-bottom: 50px; }

Now links will revert to showing up in whatever way the browser’s default style sheet says they should, but your top-level headline will be green and underlined.

You can even change all your headlines, so that they look like your top-level headline. You simply add the other headline elements to the first rule, separating each element name with a comma:

 h1, h2, h3, h4, h5, h6 {

  color: green;

  text-decoration: underline;

 }

 p {

  margin-top: 50px;

  margin-bottom: 50px;

 }

But do your headings all really look the same? Well, their color is green right across the board, and they’re all underlined, but they’re still all different sizes. That’s because our rule specifications here only override certain properties, while other properties from the default browser style sheet are still showing through (e.g., the font size, in this case).

The reset style sheet

For this reason, it’s become popular practice to use a reset style sheet, one that sets all of the properties of elements to something consistent, and to build from there. We can’t really say that this is a best practice, as opposed to the preference of some developers who like to work from point zero and build from there, rather than let the differences between browsers dictate certain variations in their designs.

The reset stylesheet is very important in providing a fallback for certain HTML5 elements that may not yet be supported by all browsers, however. The CSS reset we’re including here is one that’s proposed by a website called HTML5doctor.com. This website is a great resource for articles about HTML5 and helping you troubleshoot problems you might run into. Without further ado, let’s look at the site’s proposed CSS reset:

 html, body, div, span, object, iframe,

 h1, h2, h3, h4, h5, h6, p, blockquote, pre,

 abbr, address, cite, code,

 del, dfn, em, img, ins, kbd, q, samp,

 small, strong, sub, sup, var,

 b, i,

 dl, dt, dd, ol, ul, li,

 fieldset, form, label, legend,

 table, caption, tbody, tfoot, thead, tr, th, td,

 article, aside, canvas, details, figcaption, figure,

 footer, header, hgroup, menu, nav, section, summary,

 time, mark, audio, video {

  margin: 0;

  padding: 0;

  border: 0;

  outline: 0;

  font-size: 100%;

  vertical-align: baseline;

  background: transparent;

 }

 body {

  line-height: 1;

 }

 article,aside,details,figcaption,figure,

 footer,header,hgroup,menu,nav,section {

  display: block;

 }

 nav ul {

  list-style: none;

 }

 blockquote, q {

  quotes: none;

 }

 blockquote:before, blockquote:after,

 q:before, q:after {

  content: '';

  content: none;

 }

 a {

  margin: 0;

  padding: 0;

  font-size: 100%;

  vertical-align: baseline;

  background: transparent;

 }

 /* change colours to suit your needs */

 ins {

  background-color: #ff9;

  color: #000;

  text-decoration: none;

 }

 /* change colours to suit your needs */

 mark {

  background-color: #ff9;

  color: #000;

  font-style: italic;

  font-weight: bold;

 }

 del {

  text-decoration: line-through;

 }

 abbr[title], dfn[title] {

  border-bottom: 1px dotted;

  cursor: help;

 }

 table {

  border-collapse: collapse;

  border-spacing: 0;

 }

 /* change border colour to suit your needs */

 hr {

  display: block;

  height: 1px;

  border: 0;

  border-top: 1px solid #cccccc;

  margin: 1em 0;

  padding: 0;

 }

 input, select {

  vertical-align: middle;

 }

There’s a lot happening here, but let’s take a quick look at some of the highlights! The first rule block lists the majority of elements we might use on our page. It sets them to a consistent size (100%) and makes sure that there are no borders, margins, or padding on any of them. We’ll definitely want to override that later on for certain elements—more than likely, we’ll want to make our headings larger than the rest of our text, and we’ll want to put some space around things. Remember that we’re just establishing a baseline with this CSS reset.

A little further down, there’s a rule that starts with article, aside. This rule lists a lot of the new HTML5 block-level elements, and it’s intended for browsers that don’t support these elements yet. By putting this rule in, we can at least tell browsers to display these as blocks, rather than inline elements:

 article,aside,details,figcaption,figure,

 footer,header,hgroup,menu,nav,section {

  display:block;

 }

Now let’s clear out the styling on lists (i.e., remove bullets and numbers) and standardize the display of tables and table borders:

 nav ul {

  list-style:none;

 }

 ...

 table {

  border-collapse:collapse;

  border-spacing:0;

 }

Basically, if you thought that our page looked drab and boring before, this adjustment ramps things up a notch and really takes all of the fun out of it! That’s okay though, because we’re going to start putting the fun back into it now! Well, we will—after we touch on just a little more theory.

Applying styles to web page elements

So you now understand what CSS is, what it looks like, what it can do, and how it does it. It’s almost time to write some new CSS rules to make the Summer Smash page sparkle. But first you need to figure out how to attach a style sheet to an HTML web page, so that the styles you write will actually be shown.

You can apply CSS rules to page elements in three ways.

  • You can embed a CSS rule directly into an element.
  • You can embed a whole style sheet inside the HTML page itself.
  • You can link a style sheet from an entirely separate file to your HTML page.

Let’s examine all three possibilities in detail.

Inline styles

Perhaps the simplest way of applying CSS styles to web page elements would be through the use of inline styles, or styles written directly into the element. By definition, an inline style applies only to the element in which it is placed, so there is no need to use a CSS selector in the rule. And since the style is already enclosed inside the element, a declaration block’s curly braces aren’t needed, either. All you need to specify for an inline style to work is the property and value you want to set on the element.

Inline styles are written into the value of the style attribute of an element, like so:

 <p style="color: purple;">Look ma, i&rsquo;m purple!</p>

Naturally, inline styles don’t give you much flexibility because they can’t use the power of CSS selectors to target multiple elements of the same type on a page (in contrast to what our previous examples have done). Worse, inline styles embed presentational information directly into your document, which is exactly what CSS was developed to avoid. In general practice, inline styles really aren’t a good solution for applying styles to elements.

There are some other cases where inline styles are useful, however. For instance, they make it easy to experiment with particular elements and to test what different values of different properties will do to an element. While you’re learning about what CSS properties exist and what they can do, feel free to use inline styles to try them out. In an actual project deliverable, however, you shouldn’t leave any presentational data inside your markup. So, once you’ve got things figured out, you should pull these inline styles out and place them in either embedded style sheets or external style sheets.

Embedded style sheets

Embedding a CSS style sheet inside an HTML file enables you to use every feature of CSS without limitation, but only within the single document that contains the embedded style sheet. By placing CSS rules in a <style> element, you’re effectively creating a small area inside your markup where you can safely put CSS rules. When the browser encounters this special area, it stops interpreting your source code as HTML markup and begins to interpret the code as CSS rules. Let’s check out some code:

 <!DOCTYPE html>

 <html lang="en">

 <head>

   <meta charset="utf-8">

   <title>Summer Smash 2012 Registration</title>

   <style>

     h1 {color: red;}

   p {line-height: 2em;}

  </style>

 </head>

Placing CSS rules inside embedded style sheets in this manner clearly gives you more flexibility regarding what you’d like your CSS rules to accomplish, but you’re still limited to applying the rules to a single page (which can be a good thing, depending on the circumstances). Sometimes, you want to override the presentation of an element on more than one page alone, though. One of the greatest benefits of CSS can be seen when you use a single style sheet to define the presentation, not for a single web page, but for an entire website that may have 10, 20, 100, or 1,000 or more individual pages.

To accomplish this feat, you must completely separate the CSS styling from the HTML markup by placing it into a separate file.

External style sheets

The most common and efficient way to apply CSS to a web page—and indeed, to an entire website—is via the use of entirely separate files that are linked to a web page with a special reference element. This works similarly to the way the <img> element references an external image file. These separate files with CSS rules in them are called external style sheets because they are placed outside any containing markup. Even though these CSS rules are separated from the actual web page document, they still behave as if they were written in an embedded style sheet.

To reference an external style sheet from an HTML page, you use the <link> element to—you guessed it—link your CSS file to your markup. Since you can link many different kinds of things into a web page, the link needs to be of a certain relationship; specifically, it must have a style sheet relationship. This is specified in the rel attribute. As when using an <img> element, you need to tell the browser where to find this external style sheet. You can do this with the href attribute; and as you have probably already guessed, its value is any valid URL. Putting it all together, the <link> element might look like this:

 <link rel="stylesheet" href="css/style.css" />

This (empty) element specifies that an external CSS style sheet can be found inside the css folder and that its file name is style.css. Inside the style.css file, you simply write CSS rules as you normally would. Since this entire file is going to be interpreted by the browser as CSS, there’s no need to enclose the CSS rules within a <style> element.

Web pages can be linked to any number of external style sheets. There’s really no technical limit, although in practice the more CSS files you link to, the longer it will take for your browser to go and fetch all of them. Of course, the benefit of an external style sheet is that more than one web page can be linked to it, which means you can reuse the style rules you write for one web page across an unlimited number of other web pages. This is what makes CSS so outrageously scalable. It doesn’t matter whether your site has one page or one million pages; as long as these pages have the basic elements that need to be styled in the same way, a single CSS file can be used to style them all.

In our Summer Smash example, we’ll take the just described route, linking to an external style sheet. While we’re currently only working on one page, the registration form, chances are that this page will be part of a bigger website and that we may want to reuse some of the styling we’re going to apply elsewhere. Let’s go ahead and get started:

 body {

  background-color: #cccccc;

 }

 header a {

  text-decoration: none;

  color: #ffffff;

 }

There’s nothing too fancy here. First, we change the background color of the page to a medium grey. The funny number shown is the hexadecimal representation of this color. Using hexadecimal values gives us a much broader range of color selections, and they’re really easy to select if you just use a color picker to figure out the value. For example, the color picker at www.colorpicker.com/ displays the value you’re looking for at the top.

Second, we create our header <a> element. Wait a minute—what’s a “header <a>” element? This is one of the great features of CSS; it lets you target elements with greater precision by using their context.

More CSS selectors: targeting page elements with surgical precision

So far, you’ve seen how to apply CSS rules to specific types of page elements. Of course, specifying style rules based on element types is handy, but ultimately its usefulness goes only so far. For example, what if you wanted some links to look one way, and some other links to look some other way. Basing all your styles solely on the element type (<a>, or anchor, in our example) isn’t going to cut it. You need a more precise way to select elements. That’s where the different kinds of CSS selectors step in to help you.

As you already know, CSS selectors allow you to target elements in your markup to which you want to apply certain styles. You already know how to use one kind of CSS selector, the type selector, which (as its name implies) selects elements based on their type (or name). For example, a selector that reads as h1 will apply to all <h1> elements. Similarly, a selector that reads as h1, h2, h3 will target all <h1>, <h2>, and <h3> elements in the page.

To be more precise, the type selectors that you have used so far are called simple selectors because they are, well, pretty simple. In order to construct more complex CSS selectors, you combine, or chain, multiple simple selectors together in specific ways. These more intricate patterns enable you to target elements on your page with surgical precision. Let’s take a brief look at what other kinds of selectors you can avail yourself of when using CSS.

Id selectors

Another kind of simple selector is the id selector. As you might expect, this selector targets an element whose id attribute has been given the specified value. For instance, on our Summer Smash page, we’ve created a <div> element with an id of pagewrap:

 <div id="pagewrap">

    <header>

   <a href="/">

    <h1>Summer Smash 2012</h1>

    <p>This summer’s most smashing event!</p>

   </a>

By using this selector, we can set the width of all of the contents on the page and make the page centered in our CSS:

 #pagewrap {

   width: 75%;

   margin: 20px auto;

 }

Id selectors always begin with an octothorpe (#) and are immediately followed by the id value of the element you want to target. In the previous example, the <div> element’s id attribute value was pagewrap, so that’s what goes after the octothorpe. This will have the same target as an id selector that explicitly specifies the <div> element, as in this example:

 div#pagewrap {

  width: 75%;

  margin: 20px auto;

 }

The first selector is more generic; it doesn’t care what type of element the header is, as long as that element has pagewrap as its id attribute value. The second selector does care, and it will target the pagewrap id only if that element is a <div>. Since id attribute values must be unique across a web page, most of the time you can be assured that these two selectors are entirely interchangeable. In some cases, however, you need the more specific selector to override another style. We’ll cover selector specificity a little later in this chapter.

Class selectors

Class selectors are yet another kind of simple selector. These selectors function in the same way as id selectors, except that, instead of targeting elements with an id value, they target elements that have been given a particular class value. We haven’t given any elements in our registration form a class value, so let’s head in and change the markup a bit:

 <legend>Registrant Information</legend>

  <ol>

  <li class="formitem">

  <label for="name">Registrant name:</label>

  <input type="text" name="name" id="name" required autofocus />

  </li>

  <li class="formitem">

  <label for="email">Email address:</label>

  <input type="email" name="email" id="email" required />

  </li>

Here, we’ve added a class name of formitem to each top level list item on our form (even those not shown in this code snippet). We can now target these list items specifically, leaving other list items (like those that appear in the footer) alone.

 li.formitem {

  list-style: none;

  margin: 5px 0;

  padding: 0;

 }

We’ve also taken out the numbers next to each item in our form and put in a little space between our form elements.

The real magic here happens if we have another form on the website, and we want to use consistent styling (e.g., a Contact Us form). Our class names are reusable, and all of our style information is contained within an external, linked style sheet. As long as we link in the style sheet on the contact page and give the form’s list items class names of formitem, the formatting that we’ve just established will carry us through. This example highlights the importance of semantic markup. It’s the sound semantic markup that underpins our web pages that enables us to leverage the benefits of CSS in this way.

pseudo-class selectors

We introduced a pseudo-class silently way back when we began talking about the syntax of CSS rules. That rule looked like this:

 a:link {

  color: blue;

  text-decoration: underline;

 }

The selector in this instance is a:link. Here, the type selector is simply a, and the pseudo-class is :link. Pseudo-classes will be discussed in more detail in the next chapter; so for now it’s simply important to be aware of their existence and to recognize them as another kind of simple CSS selector.

Yet more simple selectors

If you thought type, id, class, and pseudo-class selectors weren’t enough, there remain other kinds of simple selectors that we haven’t touched upon yet. These include attribute selectors and the universal type selector. In fact, both the id and class selectors are a shorthand form for an attribute selector (because they select elements based on a particular attribute value, such as id or class). Since attribute selectors and the universal type selector are rarely used, they won’t be discussed here.

Once again, the important point is that all of these kinds of simple selectors are merely building blocks for creating more complex patterns with which to target specific elements in a web page.

Descendant selectors

The other CSS selector we introduced earlier is known as a descendant selector. This selector consists of two type selectors separated by whitespace. And as its name implies, it targets elements of the specified type that are descendants of another element of the specified type. CSS rules with descendant selectors look like this:

 header a {

  text-decoration: none;

  color: #ffffff;

 }

This CSS rule says: “target all <a> elements that are nested within <header> elements, color them white, and remove any underlines they may have.” In this example, the whitespace in the CSS selector is called a combinator because it combines two simple selectors. You can use the whitespace combinator to chain any number of simple selectors together to create more complex descendant selectors. For example, if you want to select all links in a document that are inside paragraphs, that in turn are grouped with other elements inside <div> elements, then you can use the following CSS selector:

 div p a {

  color: teal;

  text-decoration: none;

 }

Once again, this says: “target all <a> elements that are nested within <p> elements, if those <p> elements are nested within <div> elements.” So, the previous CSS rule would affect the links in a markup structure like this:

 <div>

  <p><strong>We appreciate your

  <a href="buy.html">patronage</a></strong>, and encourage your

  <a href="contact.html">feedback</a>.</p>

 </div>

However, such a CSS selector would not affect links in a markup structure like this:

 <div>

  <h3><a href="index.html">Oh won't you please take me home?</a></h3>

 </div>

Note that, in the first example, the selector matches both of the links even though one link is inside a <strong> element and one isn’t. The descendant selector matches elements regardless of how deeply nested they are, as long as they are nested in the order specified. In other words, the selector’s only requirement is that the markup’s tree structure must match the chain of simple selectors, regardless other of intervening elements.

Child selectors

If you did want to target elements that are nested only one level down from another element (e.g., the child elements of that element), then you could use the child selector to accomplish that. Like descendant selectors, child selectors are composed of at least two simple selectors and the greater-than (>) symbol, which is the combinator. For example, to target all links placed directly inside list items (and which are not nested inside any other element between the list item and themselves), you could use the following child selector:

 li > a { ... }

Note that any whitespace between the simple selectors and the combinators is ignored, unless the only combinator between simple selectors is, itself, whitespace (that is, a descendant combinator). In other words, this CSS selector—which reads “li type selector, space, child combinator, space, a type selector”—is not a CSS selector with descendant combinators, even though it includes spaces.

Adjacent sibling selectors

The final kind of combinator that CSS provides is the adjacent sibling selector. This selector is again composed of at least two simple selectors and a combinator, which in this case is the plus sign (+). This selector gives you the ability to select a specific element only if that element is a sibling of another specific element that comes immediately before it in the markup.

Recall that a nested element in your markup is called a child, and the element that it is nested within it is called a parent. A sibling is thus an element that is also a child of this parent element.

For example, in this sample navigation menu, all the list items are siblings because they are all children of the unordered list:

 <ul>

  <li><a href="index.html">Home</a></li>

  <li><a href="menu.html">Our menu</a></li>

  <li><a href="contact.html">Contact Us</a></li>

  <li><a href="about.html">About Us</a></li>

 </ul>

The unordered list is the parent of the list items. It is also the ancestor (grandparent) of the links. The links are themselves children of the list items, but none of the links is a sibling of any other links because each link has different parents (that just happen to all be list items).

In the previous list, each list item child follows another list item sibling except the first (which can’t follow anything, because it is, of course, first). Using the adjacent sibling selector, you could write a rule to select all but the first list items in lists and make them just a bit smaller, like this:

 li + li { font-size: x-small; }

This can be a powerful tool for things like navigation lists, where you may want to style the items in that list slightly differently from one another.

Combining multiple CSS selectors in a single rule

So far you understand the building blocks of CSS selectors, what kinds of simple selectors are available to you, and how to chain them using specific combinators. You’re now ready to take a quick look at a few complex examples. First, it’s helpful to note that there is no law that says you can use only one kind of combinator in a CSS selector. This means you can use any combination of simple selectors and combinators to create arbitrarily complex selection patterns.

Let’s amend the rule you used in the previous section, so that it will apply only to this question: “Is this your first Summer Smash Event?” Currently, your rule looks like this:

 li + li { font-size: x-small; }

This rule affects list items in every list on the entire page, and that’s too broad for your tastes. Let’s narrow its subjects down to only the list items that are descended from the <ul> list. To do this, you simply add an element type selector targeting the <ul> and use a descendant combinator to chain it to your existing selector. The new CSS rule looks like this:

 ul { font-size: x-small; }

While that currently works, it’s still a bit broad. But what if you added another <ul> to the page, such as secondary site navigation? This rule would also apply to that list. Let’s narrow this example down a bit more:

 ol li.formitem ul { font-size: x-small; }

As you can now see, CSS selectors give you enormous power to target the elements you want—and only the elements you want.

CSS inheritance: making the general case work in your favor

As we discussed earlier, using properly structured markup and identifying the groups of those elements with ids and class names gives you the ability to apply certain styles to a big chunk of the elements in your web page using a single CSS rule. You’ve already seen one example of this in practice, where you styled all the text in the Summer Smash header in one fell swoop. Recall that the HTML markup you developed for the website header looks like this:

 <header>

  <a href="/">

   <h1>Summer Smash 2012</h1>

   <p>This summer's most smashing event!</p>

  </a>

 </header>

And here is the CSS rule you used to style all the text in the header with a particular font:

 header a {

  text-decoration: none;

  color: #ffffff;

 }

As you can see, we only targeted text contained in an <a> tag (which is currently all of the text). We didn’t specifically target the <h1> and <p> tags themselves. Nevertheless, the text of each of these elements has been given the style you declared in the CSS rule. How did this happen? It’s not magic; it’s simply another feature of the CSS specification that the designers of CSS were clever enough to create.

This behavior is called inheritance, and it is so named because of the way child elements acquire certain CSS properties that their parents also have just by virtue of being that parent element’s child. Another way to say this is that children inherit CSS properties from their parents and ancestors. This automatic inheritance saves web developers like you from the tedious task of explicitly defining CSS properties for every single element on a web page. Can you imagine what a nightmare that would be? There are four individual elements in just the previous HTML snippet! You’d be no better off with CSS than you were without it!

Another way to think about inheritance and how it works is to think of your HTML elements as steps, where each nested element is another step down from its parent element. When you apply a CSS property to one of the steps, it “cascades down all the steps” beneath it and gets applied to those elements, too.

As we remarked earlier, some CSS properties display this inherited behavior, and others do not. As a general rule, most of the properties that replace HTML elements for styling (e.g., text properties like font and color), including those that you’ve already seen in this chapter, are inherited properties and behave in this way. However, a number of properties are not inherited because it would make little sense for them to be (e.g., width and height). These and other properties that affect the layout of the web page (we’ll discuss examples of these later in this chapter) are specific to the elements on which they are applied.

CSS inheritance is ultimately a way to allow you to get the biggest effect with the least amount of work. At any point, you can specify another, more specific CSS rule to override an earlier rule. For instance, using the previous example, you could give our tag line a slightly darker color to deemphasize it a bit (visually):

 header a p { color: #eeeeee; }

Doing this is like pouring a new CSS property on your steps at the point of the paragraph, so that this new property cascades down on top of the one that was applied to the step above it, the <a>.

The CSS cascade and the rules of specificity

What happens when the declarations of two or more CSS rules conflict with one another? Far from being a one-off occurrence, these situations are actually at the core of how CSS works and are referred to as the cascade. Learning how the cascade works is fundamental to learning CSS.

The CSS cascade is just a fancy name given to a set of rules that define how conflicts among different CSS declarations should be resolved. These rules are based on the concept that more specific rules should override more general rules. Each CSS rule that applies to an element is examined and sorted based on its specificity. The most general rule is applied first, followed by the next most general rule, and so on, until the browser reaches the most specific rule. Each successive rule overrides the previous rule’s declarations for the element’s properties.

So, what makes one CSS rule “more specific” than another? It depends on a number of factors, such as where it was written in the source code (its source order) and the specificity of the CSS selector used. (There are other things that determine the specificity of a rule, such as its origin and its weight, but these are advanced topics that you will not likely encounter in the day-to-day web development process.)

These days, a number of tools are available that can help you visualize the cascade. Adobe Dreamweaver is one such tool, and it includes a good visualization feature for specificity in its CSS panel. The TopStyle and CSSEdit applications are also good tools to consider for getting on top of the cascade. Additionally, both the Firebug add-on for Firefox and the Element inspector in Safari and Google Chrome can also show you inheritance results and the cascade order. These two tools are especially convenient since they are embedded directly into their respective host browsers.

CSS selector specificity

The selector you use as part of your CSS rule determines a great deal about how specific your rule is. In most cases, it’s really easy to determine which selectors are more specific than others because CSS selectors translate to English quite easily. For example, it’s easy to see that a selector with multiple combinators will be more specific than a selector without any combinators:

 header a { ... }

The preceding example is more specific than this one:

 a { ... }

The first reads as “all links descended from the header,” whereas the second simply says “all links.” Clearly, links that are specifically inside the header are a more specific target than links that can be anywhere on a page.

As a general rule of thumb, the more simple selectors and combinators a CSS selector has, the more specific it is. Some simple selectors are more specific than others, however, and so are some combinators. For example, a type selector is more general than a class selector, which is more general than an id selector.

If you think about it, this is all simply common sense at work. You can have <div> elements all over your page, but a much smaller number of them might be classed as features, and only one of them might be given the feature-1 unique identifier. What this means is that given an element—for instance, <div class="feature" id="feature-1">—the following three CSS rules will all match. However, the rule that uses the id selector will actually be the one that the visitor sees applied.

 .feature { color: green; } #feature-1 { color: red; } div { color: black; }

The result here is that this feature’s text will be colored red. It doesn’t matter in what order these three CSS rules are written down in the CSS file or even if they’re not in the same style sheet at all. Since selector specificity is the primary sorting method the browser will use to determine the cascading order of an element’s CSS properties, the most specific selector will always win.

Source order cascading

If two or more CSS rules conflict with one another, but their selectors have an equal specificity, then their source order is used to determine which rule actually gets applied. This can often happen in complex style sheets that have many levels of cascading rules.

For instance, you may choose to make all the text in your feature boxes green by default, so you place the following CSS rule in an external style sheet:

 .feature { color: green; }

Next, you link this style sheet to your web page, so the <head> portion of your document might look something like this:

 <head>

  <title>Fantastic staplers: Home page</title>

  <link rel="stylesheet" href="css/global.css" />

 </head>

Now every page on your website that has been linked to this external style sheet will show feature boxes with green text. However, say that you want feature box text to be red, not green, in the special sales section of your website. How might you go about overriding the rule you wrote previously?

One possibility is to use a more specific CSS selector. For instance, perhaps each web page that is in the sales section of your site has a <body> element with the id of sale-section. In that case, you can just add the following rule anywhere in your style sheet:

 #sale-section .feature { color: red; }

However, implementing this requires changing the HTML markup (i.e., adding an id="sale-section" attribute to your body tag), even if only a little bit. There are some situations when this isn’t possible or, more to the point, isn’t advisable. Recall that CSS was invented to separate style from content; therefore, it should be possible to make this change without affecting the HTML content at all. And of course, it is possible to do just that. By adding a new style sheet to your page, redeclaring the feature box text as red, and inserting this new style sheet closer to the <body> element than the other style sheet, you can use the CSS cascade’s source order sorting to effect the change. Using this method, the <head> section of your document would now look something like this:

 <head>

  <title>Fantastic staplers: sale page</title>

  <link rel="stylesheet" href="css/global.css" />

  <style>

   .feature { color: red; }

  </style>

 </head>

Notice that this example is using an embedded style sheet to define the style sheet with the overriding rule. However, it doesn’t have to be an embedded style sheet. In fact, if the sales section of your website is more than a single page, it behooves you to create a new external style sheet and link that in after the initial style sheet, as in this example:

 <head>

 <title>Fantastic staplers: sale page</title>

 <link rel="stylesheet" href="css/global.css" />

 <link rel="stylesheet" href="css/sale-section.css" />

 </head>

In both examples, however, the concept is the same: style sheets defined further down the page (closer to the <body> element) will override (“cascade on top of”) the styles defined further up the page (closer to the start of the <head> element) when the CSS rules that conflict have the same specificity.

It’s also interesting to note that this is the same behavior you observed much earlier, when you overruled the browser’s default styling with a style sheet of your own. Since the browser’s default styles are defined “first” (they are at the earliest point of the cascade), any conflicting styles you define later overrule the browser’s styling.

One final way to override

Finally, we’d be remiss if we didn’t tell you about the one final way to override all rules: !important.

Before we show you this in action, we’re going to caution you that using !important should not be done lightly because it completely breaks the cascade on the element you override. Specifying !important after a rule will ensure that that is the rule used in displaying the element—no matter what. Keeping this in mind might help you to troubleshoot a spot where the cascade doesn’t appear to be working properly. Let’s look at a new example:

 a { color: red; }

 .featured_item a { color: blue; }

The preceding snippet is somewhat similar to our previous example. It implements two rules:

  1. Take all of the links on a page and color them red.
  2. Next, look for any links contained in an element with the class featured_item and color those links blue.

Given what we just learned about the cascade, we know that this will work in theory. However, in practice the site we’re working on shows us a different result: all of the links are showing up green.

If we keep digging, we’ll see another rule further down the CSS file:

 a { color: green !important; }

According to the rules of the cascade that we’ve learned, this rule should override our color: red rule, but it shouldn’t touch the .featured_item a rule. Why is it, then? That !important bit of the rule is giving it precedence over all other rules. It appears that somebody just got the order to “change all links to green” on the website; and instead of updating the current rules to make that happen, she took a shortcut and just overrode them all.

Visual rendering: document flow and the CSS box model

There are two final concepts to understand about CSS before you can honestly say that you know enough CSS to be dangerous. These are the CSS box model and how it relates to document flow. It’s these two fundamental concepts that make designing for web pages radically different than designing for printed media. If you really want to become proficient with CSS-based designs, and especially if you’re coming from a print design background, then these are the concepts you absolutely need to nail.

Computer screens are not magazine pages; and at least for the foreseeable future, they won’t ever be exactly like them. When you design for the printed page, you make certain assumptions about what kinds of designs might work based on facts that you understand about how printed media works. For example, you know that a standard printed page is a rectangle about 8.5 inches wide by 11 inches high, so you don’t put a picture that is 10 inches wide or 13 inches high on the page because it just won’t fit. On the other hand, you know that you can put high-resolution images on the page because such images look really good when printed on paper (though they may not look so great on a computer monitor).

The web page, like the printed page, also has certain constraints, weaknesses, and advantages. For example, a web page can have a link or can change some of its content dynamically in response to a user’s actions, such as hovering his cursor over a certain area. For obvious reasons, this is something a printed page couldn’t dream of doing.

But let’s take a quick step back. We’ll begin by taking a quick look at what document flow is, and then we’ll briefly introduce the CSS box model. After that, we’ll discuss how the two concepts are intricately related. And finally, we’ll show you some of the ways that you can use CSS declarations to alter these two things at will.

What is document flow?

Document flow is a fundamental concept to CSS designers. In fact, the concept of document flow (or just flow for short) predates CSS considerably. So, what is it?

Document flow is a system by which a renderer (such as a web browser) lays out pieces of visible content on a screen, so that they flow one after the other in predictable ways. Every element on a web page, every headline, every list item, every paragraph, and even every line of text and each individual character within every paragraph follow the rules of flow to determine where they end up on the screen.

For the most part, document flow just mimics what you would expect to see on a printed page. For example, while reading this book, you’re looking at large chunks of text (paragraphs), each of which has a number of lines. These lines have printed characters on them that start from the left side and end at the right side. When you read the full paragraph, you’re reading from the top-left corner of the paragraph, horizontally across each line, and ending at the bottom-right corner of the same paragraph.

This is the normal direction in which content flows in the English language. However, this is not true for all languages. Hebrew is an example of a language that reverses the direction of flow, so that it begins from the top-right corner and ends at the bottom-left corner. Arabic does this, too. As described in the previous chapter, web pages are really just long strings of sequential characters that a web browser sees one after the other, so it needs some way to know how to order these characters and elements on the screen. It uses the rules of flow to do this.

It’s easy enough to see how flow affects characters in a paragraph. Based on the language specified in the web page’s <html> element, the web browser simply places the first character at either the top-left or top-right corner of the paragraph, and then places each successive character it sees to the right or left of the one before it. Recall that your <html> element for Summer Smash 2012 began like this:

 <html lang="en">

Since you’ve defined that this web page is written in English by specifying the lang="en" attribute, the web browser will assume a normal flow for what is expected in English. Specifically, it will flow text in a direction of left to right. If you’re feeling experimental, go ahead and add the dir attribute with a value of rtl (short for right-to-left) to the <html> element—you’ll see that now every headline and paragraph is right-aligned (previously it was left-aligned) and the punctuation marks are all on the “wrong side” of the words.

So, some of the rules of flow control things like the direction of text and where the beginning of an element’s content should be placed. But, as you’ll see next, there’s much more to flow than that.

What is the CSS box model?

You’ll hear the term box used a lot when talking about CSS. Obviously, the first question you need to ask yourself is, “What is a box?”

In CSS, a box is simply a rectangular region that represents the physical space that a certain thing takes up. Typically, for web pages, this space is a group of pixels on a computer screen. For example, for every <p> element you define in your web page, you create a rectangle inside of which the content of that paragraph is displayed, or flows into. You can use tools such as Firebug or the Web developer toolbar add-on for Firefox to see these boxes.

Notice how the CSS boxes of the paragraphs always extend to the paragraph’s edges, even though the last line of text inside the paragraph may not. This is because it’s not only HTML elements like the <p> element that create CSS boxes. Indeed, everything on a web page that is visible creates a box of a certain type, including strings of text content.

However, not all CSS boxes are created equally. These characters inside paragraphs do not create the same kinds of boxes that the <p> element does. This is very deliberate; and as you’re about to see, it’s a very important distinction (recall that we talked briefly about box-level versus inline elements in the previous chapter).

Inline-level vs. block-level boxes

The <p> elements create what are known as block-level boxes, whereas the strings of text within them create inline-level boxes. These two different kinds of CSS boxes flow onto the screen in very different ways.

Block-level boxes always flow onto the page one on top of another, like boxes (or bricks) in a vertical stack. Since paragraphs are declared by all web browsers’ default style sheets to be block-level boxes, each time you define a new <p> element (and thereby generate a new block-level CSS box), the browser places that paragraph underneath any block-level boxes that came before it. This is why two paragraphs next to one another always create two distinct chunks of text, one atop the other, by default. Other elements that create block-level boxes are headlines, <div> elements, and lists (not list items, but the list items’ containing elements such as <ul>, <ol>, and <dl>). There are also a host of new HTML5 block-level elements, including <header>, <section>, <article>, and <aside>.

Inline boxes are almost always inside some containing block-level box; but instead of flowing one after the other in a vertical stack as block-level boxes do, they flow one after the other horizontally. Each character of text (or glyph) that the browser sees is thus placed in the same horizontal line with any inline-level elements that came before it. It’s only if there’s not enough horizontal space for things to fit on the same line that inline-level boxes get bumped down to the next line. Some examples of web page elements that create inline-level boxes by default are images, links, and emphasized text (e.g., the <em> and <strong> elements).

Runs of text that aren’t nested within any of these inline-level elements also create inline boxes implicitly. These implicit inline-level boxes are called anonymous inline boxes because they don’t have an element that is specifically associated with them.

For instance, the following HTML markup you used for the paragraph of text on the Summer Smash website footer creates two CSS boxes (not one), one of which is a block-level box and one of which is an inline-level box:

 <p>Summer Smash 2012. A Barker and Lane Production.</p>

The <p> element is the one that creates the block-level box. All the text inside the <p> element creates the anonymous inline-level box. If you then added another inline-level element into this paragraph, such as a <strong> element for some additional emphasis on the year, then you’d suddenly have four CSS boxes:

 <p>Summer Smash <strong>2012</strong>. A Barker and Lane Production.</p>

In this paragraph, the <p> element still creates the block-level box, but the text “Summer Smash” creates the first anonymous inline box. Next, the <strong> element creates a second inline-level box (with the contents, “2012”). Finally, the text “. A Barker and Lane Production” creates the second anonymous inline-level box. Thus, we have one block-level box, plus two anonymous inline boxes, plus another (non-anonymous) inline-level box. That equals a total of four CSS boxes.

The kind of CSS box that an element generates (e.g., inline-level or block-level box) can be controlled with CSS. Specifically, the value of an element’s display property determines what kind of box it will generate. The following example shows what the default CSS rules that web browsers use to make <p> elements block-level and <strong> elements inline-level might look like:

 p { display: block; } strong { display: inline; }

Of course, you can override these default styles and make any element generate any kind of box you want—something that was flat-out impossible to do before the advent of CSS. For example, you could add a CSS rule that makes <strong> elements generate block-level boxes instead of inline-level boxes:

 strong { display: block; }

If you add that CSS rule to the style sheets for Summer Smash’s web pages, you’ll see that you now have three lines of text inside one paragraph and that the number “2012” will be on its own line. This is because, as you now know, the rules of flow dictate that block-level boxes be stacked vertically. Since the <strong> element is now generating a block-level CSS box, it must be placed on its own line, so you end up splitting the footer sentence across three lines.

In this state, you still have four CSS boxes. But instead of having three inline boxes, all within a block-level box, you now have two inline boxes and two block-level boxes. One of the block-level boxes (the one generated by the <strong>element) is overlapping the one generated by the <p> element. You can make this more obvious by adding background colors to your <p> and <strong> elements:

 p {

     background-color: blue;

 }

 strong {

     display: block;

     background-color: red;

 }

There’s another thing worth pointing out about this picture. Notice that each stripe goes all the way to the edge of the browser window. At first, you might be tempted to assume that all CSS boxes will always be as wide as they can be; however, this is not true, and this fact highlights another important difference between inline-level and block-level boxes.

Block-level boxes that have no specific width declared (such as the ones generated by both your <p> and <strong> elements) do, indeed, grow as wide as they can, while still fitting inside their containing element’s CSS box. In this case, all the block-level CSS boxes are as wide as the browser window, or viewport, because none of them has an explicit width. This means they all grow to be as wide as they can be inside the web browser.

Inline-level boxes, however, grow only as wide as they need to be to make their content fit within them. Inline boxes are like shrink-wrap that surrounds whatever content they have. You can make this more obvious by giving a background color to your two remaining inline boxes.

Since both of your remaining inline boxes are anonymous, you need to use an element you haven’t seen before—the <span> element—so that you can target them with CSS. The <span> element is just like the <div> element, except that, instead of generating a block-level box, by default it generates an inline-level box. The HTML paragraph looks like this with the <span> elements added:

 <p><span>Summer Smash </span><strong>2012</strong><span>. A Barker and Lane Production.</span></p>

And the CSS looks like this with the background colors applied to the <span> elements:

 p {

  background-color: blue;

 }

 span {

  background-color: green;

 }

 strong {

  display: block;

  background-color: red;

 }

The two inline-level boxes (colored green) shrink to the width of their content, but the block-level boxes (colored blue and red) extend to be as wide as they can.

Changing CSS box properties: the CSS box model explained

Every CSS box, whether inline-level or block-level, has four distinct areas within it. These are, from the inside out, the content area, the padding area, the border area, and the margin area:

  • The content area : You’re already familiar with this area. It is the rectangular area inside which an element’s content, whether plain text or other nested elements, is placed.
  • The padding area : This is a transparent space around the content where only the background properties of an element (if any) will show.
  • The border area : This area frames the padding and the content, much like a picture frame.
  • The margin area : This area defines the amount of whitespace the CSS box should have around it.

All of these areas always exist for all CSS boxes. However, much of the time, none of them is shown, except the content area. This is because the other three areas have zero width and zero height. That is, they take up no space in the layout of a page whatsoever. However, with CSS, you can make each of these areas larger, so that they will show up and thus affect the layout of the elements on your web page.

Firebug has a great layout tab that lets you see exactly what the dimensions of each of these areas are for any given element. Let’s start by examining the content area more closely, and then do the same for each of the other three areas that the CSS box model defines.

Content area: defining the dimensions of content boxes

As you saw in the previous section, the content area of a CSS box behaves differently depending on the type of box being generated. For block-level boxes, the content area grows as wide as it can within the confines of its containing block or the browser viewport in the absence of such a container. For inline-level boxes, the content area shrinks so that it is only as wide as the widest part of its content. Both block-level and inline-level boxes grow as high as their tallest content—and no higher. This can be summed up in CSS with the following declarations:

 width: auto; height: auto;

As you’ve probably guessed by now, changing the values of the width and height properties affects the content area’s width and height, respectively. Say, for instance, that you want the footer for the Summer Smash website to be exactly 300 pixels wide. This is no problem:

 footer { width: 300px; }

The width property (and any property that accepts a length value, such as the height property) can take as its value a number followed by an abbreviation (px, in this example) that indicates the unit of measurement. The abbreviation px is short for pixels.

In this example, you’re setting the width of the element with the id of footer to exactly 300 pixels. Obviously, pixels make sense only for designs that are going to be displayed on a device that measures distances in pixels (e.g., a computer monitor, but not a printed page). There are other length units that CSS will allow you to use, and we’ll talk about those later on.

So, with the earlier CSS rule applied to Summer Smash’s footer, your footer text is now exactly 300 pixels wide all the time. Resizing the window will not change the width of your footer, nor will adding more text content to it. The footer will remain at a fixed width because you’ve told it to do exactly that.

Note that even though this example appears to be using CSS inheritance, it’s not. The <p> element inside the footer <footer> still has a width value set to auto, since the width property is not inherited. However, since the <p> element is nested inside the footer <footer> (the footer <footer>’s CSS box is the paragraph element’s containing block)—and since the footer <div> is constrained to be only 300 pixels wide—the paragraph inside the footer can also be a maximum of only 300 pixels wide.

Since an inline-level box’s width is defined by its content, the width property does not apply to these types of CSS boxes, so the width we’ve set is ignored. In other words, if this inline element had no content, it wouldn’t even display.

Padding area: giving backgrounds the floor

The padding area of a CSS box is the area immediately surrounding the content area. Padding is used to space the content of a box away from its edges. This helps a design look less cramped.

By default, most elements will not have any padding. The noteworthy exceptions are typically lists of some kind (e.g., unordered, ordered, or definition lists) where the child list item elements receive their indentation in some browsers through the application of a default padding value. (In other browsers, this same indentation effect is achieved with a default margin value. Margins are described later in the chapter.) In CSS, a box with no padding at all might be declared by using the following declaration:

 padding: 0;

Notice that there is no unit abbreviation, such as px, after the 0 in the value of the padding property. Since 0 is the same value whether it is specified in pixels or in inches (or any other length unit), no unit abbreviation is needed. It can be specified (so 0px will work), but it’s not necessary to do so—and why would we want to type more than we have to?

Of course, all we need to do to give an element’s box some visible padding area is to increase the amount from zero to some noticeable value. For example, let’s give Summer Smash’s footer 10 pixels of padding:

 footer {

        width: 300px;

        padding: 10px;

 }

This change is subtle, but using Firebug you can clearly see that you now have 10 pixels of padding surrounding the content of the footer. Any background properties you specify on a box, such as a background color or background image, will “shine through” the invisible padding area because a box’s backgrounds, unlike its contents, start at the edge between a box’s padding and its border, rather than inside the box’s content area.

You can see from this example that, in fact, you’ve applied 10 pixels of padding to all four sides of the content area. You have 10 pixels on the top, the right, the bottom, and the left sides of the footer <div>’s content. Also notice that the width of your content area is still 300 pixels, just as you left it.

The important thing to infer from this is that any space you give the padding, border, or margin areas of a CSS box get added to any size you might specify for the box’s width (or height) property. In effect, our 300-pixel-wide CSS block-level box is now a 320-pixel-wide CSS box because we’ve just added 10 pixels of padding to both the left and right sides of the box.

With CSS, we have the flexibility to define different sizes for each of the four individual sides of a box. The padding property used in the earlier CSS rule is shorthand that can be expanded to the following four declarations:

 padding-top: 10px;

 padding-right: 10px;

 padding-bottom: 10px;

 padding-left: 10px;

Every time you simply declare a value for a box’s padding area with the padding property, you’re really declaring each of those four specific padding properties with the same value applied to each property. CSS is full of shorthand properties like this, and it’s important to be aware of them and what they expand to. When declaring rules generally, shorthand properties can save you quite a bit of typing (and quite a bit of bandwidth when downloading the finished CSS style sheet, too); however, when you’re declaring rules to override other rules, it pays to be as explicit as possible.

A CSS box’s padding area behaves slightly differently based on whether the box is an inline-level box or a block-level box. The padding area of a block-level box behaves as you would expect, causing the content area to move both vertically and horizontally to accommodate the additional padding. However, while the horizontal padding of an inline box (i.e., the right and left sides) behaves that way, too, the vertical padding (i.e., the top and bottom sides) does not. Specifically, an inline box’s vertical padding will increase the area available for the box’s backgrounds, but no other boxes will be affected by the inline box’s occupation of the additional space.

Border area: drawing borders and outlines

The border area is, as its name implies, a space to define a border (or outline) for a CSS box. The edge between a box’s padding and its border is where any background stops being visible. A CSS box’s four borders (i.e., top, right, bottom, and left sides, as usual) have a number of different possible looks. Let’s use a border to outline the footer on Summer Smash’s website.

 footer {

        width: 300px;

        padding: 10px;

        border: 1px solid black;

 }

Borders behave in the same way that padding does. On a block-level box, all four sides affect their neighbors, but on an inline box, only the horizontal borders affect the layout of neighboring boxes.

The border property is another shorthand property. It sets a border width, style, and color for all four sides of a box. The example border declaration shown earlier expands to the following 12 declarations listed here, each of which can be set with a different value:

 border-top-width: 1px;

 border-right-width: 1px;

 border-bottom-width: 1px;

 border-left-width: 1px;

 border-top-style: solid;

 border-right-style: solid;

 border-bottom-style: solid;

 border-left-style: solid;

 border-top-color: black;

 border-right-color: black;

 border-bottom-color: black;

 border-left-color: black;

Borders have a lot of options—too many to go into at length in this chapter—so we encourage you to explore some of the other possible values for these properties on your own.

Margin area: defining whitespace and centering

The margin area of a CSS box defines the whitespace that surrounds the box’s other areas. Most of the spacing of elements on web pages is accomplished with clever combinations of margins and padding. As with the padding and border areas, CSS allows you to specify different amounts of whitespace (i.e., margin sizes) on each of the four sides of a CSS box. Or, you can use the margin shorthand property to set the margins of all four sides in one declaration.

Margins can be thought of as a way for an element’s CSS box to invisibly “push against” any other boxes next to it in exactly the same way as you’ve seen happen with padding. Like padding and borders, all four sides of block-level box’s margins affect the layout of its neighboring CSS boxes, but only the horizontal margins of an inline box do.

Typically, headlines, paragraphs, lists, and many other elements have a certain amount of vertical margins defined by the browser’s default style sheet. This CSS rules could look like this:

 h1, h2, h3, h4, h5, h6, p, ul, ol, dl { margin: 1em 0; }

The selector for this rule is simply a group of individual type selectors that matches all possible headline levels, paragraphs, unordered lists, ordered lists, and definition lists. The declaration uses the margin shorthand property. With two values, the margin shorthand property expands to the following four CSS declarations:

 margin-top: 1em;

 margin-right: 0;

 margin-bottom: 1em;

 margin-left: 0;

That is, the first value sets the values for the vertical (i.e., top and bottom) sides, and the second value sets the values for the horizontal (i.e., right and left) sides.

The length unit being used here is an em. One em is the same length as the width of the letter m for the currently selected font for an element. Since the lowercase letter m is a different size in different fonts (and different font sizes), this unit is referred to as a relative-length unit because the actual computed value is relative to another value that may change. Contrast this with an absolute length unit, such as pixels, which are always the same size, no matter what. When working with text on a web page, it often pays to set sizes using a unit that is measured relative to a font size.

Why might the CSS rule for a margin use a relative unit that is defined by font sizes? If you think about it, the font size of an <h1> element is drastically different from the font size of an <h6> element, which is similarly different from the size of regular body text, such as the contents of <p> elements. It makes sense, then, that the amount of whitespace (margins) on top of and below the CSS box for each of these elements is different.

It would look a little weird if you had a huge level-one headline, but you had only a few pixels of distance between it and the introductory paragraph that came next. Using relative units allows you to be consistent in your declarations and yet apply different actual values to CSS properties based on the values of other CSS properties. This is the basis for creating what is known as a responsive (formerly known as elastic) layout, an advanced implementation of designs that results in the ability to “zoom in” on a page by increasing the text size in the browser.

The margins of a box are often used to center a block-level element horizontally within its containing block. Centering blocks is accomplished by setting both the right and left margins of the CSS box to the special value auto. You’ll recall that this value simply means something like “automatically adjust this value based on the available space.” For example, let’s center the footer of Summer Smash’s website:

 footer {

   width: 300px;

   padding: 10px;

   border: 1px solid black;

   margin: 0 auto;

 }

Again, the margin shorthand property is used to set the margins for all sides of the footer. The vertical sides are both given margin values of 0 (i.e., no extra whitespace at all), and the horizontal sides are both set to auto.

The footer is centered within the browser viewport because both its right and left margins automatically adjust their size to an equal share of the available horizontal space. To create available space in the first place, a width value other than the default of auto and less than the width of the footer’s containing block (the browser window, in this case) must be specified, so that the element appears centered.

Margins have one other interesting property that can at first be confusing, but quickly becomes indispensable. When the bottom margin of one element is directly next to the top margin of another with no intervening areas (i.e., there are no padding or border areas separating them), then the two margins combine to form a single margin equal to the size of the larger margin. This peculiar behavior, called collapsing margins, occurs only for vertical margins and never for horizontal ones.

This behavior is handy because it means you don’t have to specify a multitude of additional CSS rules in the common case where two block-level boxes follow one another in the document flow, such as a sequence of multiple consecutive paragraphs. In that case, setting a top and bottom margin of, say 1em, on each paragraph will result in exactly 1em of whitespace between each paragraph (not 2em). If vertical margins didn’t collapse, you’d instead have to specify something like 1em of bottom margin and zero top margin on every paragraph except the first in the series.

It can take a bit of time to get comfortable with the notion of declaring the sizes of what are essentially invisible areas of a page to define the layout of elements. This method of designing runs counter to the more natural feel achieved by directly manipulating the object itself. Nevertheless, you’ll find that if you “go with the flow” of a web page, you’ll end up creating designs that are far more flexible and far more maintainable.

Summary

This chapter covered an immense amount of technical material and a lot of theoretical ground. Don’t feel discouraged if you think you may need to return to this chapter to get a handle on everything we’ve discussed. Thanks to its flexibility, power, and the unfortunately spotty browser implementations, actually creating complex designs with CSS can be tricky. However, knowing the foundations will prove invaluable just a short way down the line.

In this chapter, we introduced the majority of foundational concepts that explain how CSS actually works inside the web browser, such as the cascade, inheritance, document flow, and the box model. We also introduced a great deal of practical information regarding how to use CSS, such as how to apply CSS styles to a web page by using external or embedded style sheets and individual inline styles. We also covered the syntax and terminology of CSS rules and distinguishing between properties, values, declarations, declaration blocks, selectors, and rules. Next, we explored many possible CSS selectors and observed how you can have incredible flexibility over how you apply styles to elements by chaining simple selectors together with combinators. Finally, we introduced a plethora of CSS properties, including shorthand properties, each of which changes the way an element is displayed visually.

Armed with this knowledge, you’ll next take a look at a real design and dissect it to discover how it was implemented. You’ll then use this experience to help you implement a simple design for Summer Smash’s website. Along the way, we’ll introduce you to some additional CSS concepts and properties that will give you yet another level of appreciation for the power and flexibility of web standards.

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

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