CSS CHAPTER 1 2018-12-19T12:22:27+00:00

CSS CHAPTER 1

Topics:- (A brief history of markup, Document types, DOCTYPE switching, and browser modes, Validation, Common selectors, The universal selector, Advanced selectors, The cascade and specificity, Inheritance, Applying styles to your document, Style guides, Box model recap, Positioning recap,Floating)

The human race is a naturally inquisitive species. We just love tinkering with things. We enjoy working things out ourselves, creating our own mental models about how we think things behave. We muddle through and only turn to the manual when something goes wrong or defies our expectations. One of the best ways to learn Cascading Style Sheets (CSS) is to jump right in and start tinkering. However, if you’re not careful you may end up misunderstanding an important concept or building in problems for later on.

When we use the term XHTML, we are referring to Extensible Hypertext Markup Language, and when we use the term (X)HTML, we are referring to both XHTML and HTML.

In this chapter you will learn about

The importance of a well-structured and meaningful document

Coding best practices

Common coding mistakes

Document types, DOCTYPE switching, and browser modes

Ways to target your styles

The cascade, specificity, and inheritance

The intricacies and peculiarities of the box model

How and why margins collapse

The difference between absolute and relative positioning

How floating and clearing work

Structuring your code

Most people don’t think about the foundations of a building. However, without solid foundations, the majority of the buildings around us wouldn’t exist. While this is about advanced CSS techniques, much of what we are going to do would not be possible (or would be very difficult) without a well-structured and valid (X)HTML document to work with. In this section you will learn why well-structured and meaningful (X)HTML is important in CSS development. You will also learn how you can add more meaning to your documents, and by doing so, make your job as a developer easier.

Use meaningful markup

The early Web was little more than a series of interlinked research documents using HTML to add basic formatting and structure. However, as the World Wide Web increased in popularity, HTML started being used for presentational purposes. Instead of using heading elements for page headlines, people would use a combination of font and bold tags to create the visual effect they wanted. Tables got co-opted as a layout tool rather than a way of displaying data, and people would use blockquotes to add whitespace rather than to indicate quotations. Very quickly the Web lost its meaning and became a jumble of font and table tags (see Figure 1-1).

Figure 1-1. The markup for the lead story from abcnews.com on August 14, 2000, uses tables for layout and large, bold text for headings. The code lacks structure and is difficult to understand.

HTML was intended to be a simple and understandable markup language. However, as web pages became more and more presentational, the code became almost impossible to understand. As such, complicated WYSIWYG (What You See Is What You Get) tools were needed to handle this mass of meaningless tags. Unfortunately, rather than making things simpler, these tools added their own complicated markup to the mix. By the turn of the millennium, the average web page was so complicated it was almost impossible to edit by hand for fear of breaking the code. Something needed to be done.

Then along came Cascading Style Sheets. With CSS it became possible to control how a page looked externally and to separate the presentational aspect of a document from its content. Presentational tags like the font tag could be ditched, and layout could be controlled using CSS instead of tables. Markup could be made simple again, and people began to develop a newfound interest in the underlying code.

Meaning started to creep back into documents. Browser default styles could be overridden so it became possible to mark something up as a heading without it being big, bold, and ugly. Lists could be created that didn’t display as a series of bullet points, and block-quotes could be used without the associated styling. Developers started to use (X)HTML elements because of what they meant rather than how they looked (see Figure 1-2).

Figure 1-2. The markup for the lead story on abcnews.com from earlier this year is well structured and easy to understand. While it does contain some presentational markup, the code is a significant improvement on the code in Figure 1-1.

Meaningful markup provides the developer with several important benefits. Meaningful pages are much easier to work with than presentational ones. For example, say you need to change a quotation on a page. If the quotation is marked up correctly, it is easy to scan through the code until you find the first blockquote element. However, if the quotation is just another paragraph element tag, it will be a lot harder to find.

As well as being easy for humans to understand, meaningful markup—otherwise known as semantic markup—can be understood by programs and other devices. Search engines, for instance, can recognize a headline because it is wrapped in h1 tags and assign more importance to it. Screenreader users can rely on headings as supplemental page navigation. Most importantly for the context, meaningful markup provides you with a simple way of targeting the elements you wish to style. It adds structure to a document and creates an underlying framework to build upon. You can style elements directly without needing to add other identifiers, and thus avoid unnecessary code bloat.

(X)HTML includes a rich variety of meaningful elements, such as

h1, h2, etc.

ul, ol, and dl

strong and em

blockquote and cite

abbr, acronym, and code

fieldset, legend, and label

caption, thead, tbody, and tfoot

As such, it is always a good idea to use an appropriate meaningful element where one exists.

IDs and class names

Meaningful elements provide an excellent foundation, but the list of available elements isn’t exhaustive. (X)HTML was created as a simple document markup language rather than an interface language. Because of this, dedicated elements for things such as content areas or navigation bars just don’t exist. You could create your own elements using XML, but for reasons too complicated to go into, it’s not very practical at this time.

The next best thing is to take existing elements and give them extra meaning with the addition of an ID or a class name. This adds additional structure to your document, and provides useful hooks for your styles. So you could take a simple list of links, and by giving it an ID of mainNav, create your own custom navigation element.

<ul id=”mainNav”>

<li><a href=”#”>Home</a></li>

<li><a href=”#”>About Us</a></li>

<li><a href=”#”>Contact</a></li>

</ul>

An ID name is used to identify an individual element on a page, such as the site navigation, and must be unique. IDs are useful for identifying persistent structural elements such as the main navigation or content areas. They are also useful for identifying one-off elements—a particular link or form element, for example.

Across a site, ID names should be applied to conceptually similar elements in order to avoid confusion. Technically, you could give both your contact form and your contact details the ID name of contact, assuming they were on separate pages. However, you would then need to style each element based on its context, which could be problematic. Instead, it would be much simpler to use distinct ID names such as contactForm and contactDetails. While a single ID name can only be applied to one element on a page, the same class name can be applied to any number of elements on a page. Classes are very useful for identifying types of content or similar items. For instance, you may have a news page that contains the date of each story. Rather than giving each date a separate ID, you could give all of them a class name of date.

When naming your IDs and classes, it is important that you keep the names as meaningful and “unpresentational” as possible. For instance, you could give your section navigation an ID of rightHandNav as that is where you want it to appear. However, if you later choose to position it on the left, your CSS and (X)HTML will go out of sync. Instead, it would make more sense to name the element subNav or secondaryNav. These names explain what the element is rather than how it is presented. The same is true of class names. Say you want all your error messages to be red. Rather than using the class name red, choose something more meaningful like error or feedback (see Figure 1-3).

Figure 1-3. Good and bad ID names

When writing class and ID names, you need to pay attention to case sensitivity. CSS is generally a case-insensitive language. However, the case-sensitivity of things that appear in the markup, such as class and ID names, depends on the case sensitivity of the markup language. If you are using XHTML, class and ID names are case sensitive, whereas with regular HTML they are case insensitive. The best way to handle this issue is simply to be consistent with your naming conventions. So, if you use camel case in your (X)HTML class names, carry this through to your CSS as well.

Due to the flexibility of classes, they can be very powerful. At the same time, they can be overused and even abused. Novice CSS authors often add classes to nearly everything in an attempt to get fine grained control over their styles. Early WYSIWYG editors also had the tendency to add classes each time a style was applied. Many developers picked up this bad habit when using generated code to learn CSS. This affliction is described as classitis and is, in some respects, as bad as using table-based layout because it adds meaningless code to your document.

<h3 class=”newsHead”>Zeldman.com turns 10</h3>

<p class=”newsText”>

Another milestone for Jeffrey as zeldman.com turns 10 today </p>

<p class=”newsText”><a href=”news.php” class=”newsLink”>More</a></p>

In the preceding example, each element is identified as being part of a news story by using an individual news-related class name. This has been done to allow news headlines and text to be styled differently from the rest of the page. However, you don’t need all these extra classes to target each individual element. Instead, you can identify the whole block as a news item by wrapping it in a division with a class name of news. You can then target news headlines or text by simply using the cascade.

<div class=”news”>

<h3>Zeldman.com turns 10</h3>

<p>Another milestone for Jeffrey as zeldman.com turns 10 today</p> <p><a href=”news.php”>More</a></p>

</div>

Divs and spans

One element that can help add structure to a document is a div element. Many people mistakenly believe that a div element has no semantic meaning. However, div actually stands for division and provides a way of dividing a document into meaningful areas. So by wrapping your main content area in a div and giving it an ID of mainContent, you are adding structure and meaning to your document. To keep unnecessary markup to a minimum, you should only use a div element if there is no existing element that will do the job. For instance, if you are using a list for your main navigation, there is no need to wrap it in a div.

<div id=”mainNav”>

<ul>

<li>Home</li>

<li>About Us</li>

<li>Contact</li>

</ul>

</div>

You can remove the div entirely and simply apply the ID to the list instead:

<ul id=”mainNav”>

<li>Home</li>

<li>About Us</li>

<li>Contact</li>

</ul>

Using too many divs is often described as divitus and is usually a sign that your code is poorly structured and overly complicated. Some people new to CSS will try to replicate their old table structure using divs. But this is just swapping one set of extraneous tags for another. Instead, divs should be used to group related items based on their meaning or function rather than their presentation or layout. Whereas divs can be used to group block-level elements, spans can be used to group or identify inline elements:

<h2>Where’s Durstan?</h2>

<p>Published on <span class=”date”>March 22nd, 2005</span>

by <span class=”author”>Andy Budd</span></p>

It’s generally less common to need to group or identify inline elements, so spans are seen less frequently than divs. Where you will see spans used are effects such as image replacement, which use them as extra hooks to hang additional styles on.

Although the goal is to keep your code as lean and meaningful as possible, sometimes you cannot avoid adding an extra nonsemantic div or span to display the page the way you want. If this is the case, don’t fret too much over it. We live in a transitional period and hopefully CSS 3 will give us much greater control of our documents. In the meantime, real-world needs often have to come before theory. The trick is knowing when you have to make a compromise and if you are doing it for the right reasons.

CSS comes in various versions, or “levels,” so it’s important to know which version to use. CSS 1 became a recommendation at the end of 1996 and contains very basic properties such as fonts, colors, and margins. CSS 2 built on this and added advanced concepts such as floating and positioning to the mix, as well as advanced selectors such as the child, adjacent sibling, and universal selectors. At the time of writing, CSS 2 was still the latest version of CSS, despite becoming a recommendation as long ago as 1998. Time moves very slowly at the World Wide Web Consortium (W3C), so while work on CSS 3 started before the turn of the millennium, the final release is still a long way off. To help speed development and browser implementation, CSS 3 has been broken down into modules that can be released and implemented independently. CSS 3 contains some exciting new additions, including a module for multicolumn layout. However, the selectors module is nearest completion and could possibly become a recommendation as early as 2006. Because of the expected length of time between the release of CSS 2 and CSS 3, work started in 2002 on CSS 2.1. This revision of CSS 2 intends to fix some errors and provide a much more accurate picture of CSS browser implementation. CSS 2.1 is slowly nearing completion but probably won’t be finished until late 2006. But it does provide a much more accurate representation of the current state of CSS and is the version I currently use.

Document types, DOCTYPE switching, and browser modes

A document type definition (DTD) is a set of machine-readable rules that define what is and isn’t allowed in a particular version of XML or (X)HTML. Browsers will use these rules when parsing a web page to check the validity of the page and act accordingly. Browsers know which DTD to use, and hence which version of (X)HTML you are using, by analyzing the page’s DOCTYPE declaration. A DOCTYPE declaration is a line or two of code at the start of your (X)HTML document that describes the particular DTD being used. In this example, the DTD being used is for XHTML 1.0 Strict:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

DOCTYPE declarations will typically, but not always, contain a URL to the specified DTD file. Browsers tend to not read these files, choosing instead to recognize common DOCTYPE declarations.

Validation

As well as being semantically marked up, an (X)HTML document needs to be written using valid code. If the code is invalid, browsers will try to interpret the markup themselves, sometimes getting it wrong. Worse still, if an XHTML document is being sent with the correct MIME type, browsers that understand XML simply won’t display an invalid page. Because browsers need to know which DTD to use in order to process the page correctly, a DOCTYPE declaration is required for the page to validate.

You can check to see if your (X)HTML is valid by using the W3C validator, a validator book-marklet, or a plug-in like the Firefox Developer Extension. Many (X)HTML editors now have validators built in, and you can even install a copy of the W3C validator locally on your computer. The validator will tell you if your page validates, and if not, why not. Validation is important because it can help you track down bugs in your code. As such, it is a good idea to get into the habit of validating early and often. However, validation isn’t an end unto itself, and many otherwise good pages fail to validate due to small errors such as unencoded ampersands, or because of legacy content. So although validation is important, in the real world, a degree of common sense is required.

Various code validation tools are available. You can validate your site online by going to http://validator.w3.org/ and entering your URL. However, if you are going to validate often—which is a good idea—typing your URL each time can become a little tedious. Instead, I use a handy validation bookmarklet, or favelet, which is a small piece of JavaScript that can be stored in the bookmarks or favorites folder in your browser. Clicking the bookmark will trigger the JavaScript action. In the case of the validator bookmarklet, it runs the page you are currently on through the W3C validator and displays the results. You can find the validator bookmarklet along with many other handy web development bookmarklets on my personal site at www.andybudd.com/bookmarklets/If you use Firefox, you can download and install a wide variety of plugins. Among the numerous validator plugins available, my personal favorite is the Web Developers Extension plugin. As well as allowing you to validate your (X)HTML and CSS, it enables you to do a wide variety of other useful tasks like outlining various (X)HTML elements, turning off stylesheets, and even editing styles in the browser. The Web Developers Extension can be downloaded from http://chrispederick.com/work/firefox/webdeveloper/ and is a must have for any CSS developer using Firefox. There is now also a developer toolbar for Internet Explorer 6 and above. You can download this toolbar from http://tinyurl.com/7mnyh. Although it is not as feature rich as the Firefox toolbar, it is still extremely useful.

As well as being important for validation, browsers have started to use DOCTYPE declarations for another purpose.

Browser modes

When browser manufacturers started to create standards-compliant browsers, they wanted to ensure backward compatibility. To accomplish this, they created two rendering modes: standards mode and quirks mode. In standards mode the browser renders a page according to the specifications, and in quirks mode pages are displayed in a looser, more backward-compatible fashion. Quirks mode typically emulates the behavior of older browsers such as Microsoft Internet Explorer 4 and Netscape Navigator 4 to prevent older sites from breaking.

The most obvious example of the difference between these modes revolves around the Internet Explorer on Windows proprietary box model. When Internet Explorer 6 debuted, the correct box model was used in standards mode, while the older, proprietary box model was used in quirks mode. To maintain backward compatibility with sites built for IE 5 and below, Opera 7 and above also uses IE’s faulty box model in quirks mode.

Other differences in rendering are subtler and specific to certain browsers. However, they include things like not requiring the # symbol for hex color values, assuming lengths with-out units in CSS are pixels, and increasing the font size by one step when using keywords. Mozilla and Safari have a third mode called “almost standards mode,” which is the same as standards mode, except for some subtle differences in the way tables are handled.

DOCTYPE switching

The browser chooses which rendering method to use based on the existence of a DOCTYPE declaration and the DTD being used. If an XHTML document contains a fully formed DOCTYPE, it will normally be rendered in standards mode. For an HTML 4.01 document, a DOCTYPE containing a strict DTD will usually cause the page to render in standards mode. A DOCTYPE containig a transitional DTD and URI will also cause the page to render in standards mode, while a transitional DTD without a URI willcause the page to render in quirks mode. A badly formed or nonexistent DOCTYPE will cause both HTML and XHTML documents to be rendered in quirks mode.

The effect of choosing a rendering mode based on the existence of a DOCTYPE is known as DOCTYPE switching, or DOCTYPE sniffing. Not all browsers follow these exact rules, but they give you a good idea of how DOCTYPE switching works. Eric Meyer has done some further research on this subject and has created a chart (http://meyerweb.com/ eric/dom/dtype/dtypegrid.html) that shows the various rendering modes different browsers use depending on the DOCTYPE declaration in use.

DOCTYPE switching is a hack used by browsers to distinguish legacy documents from more standards-compliant ones. Despite writing valid CSS, if you choose the wrong DOCTYPE, your pages will be rendered in quirks mode and behave in a buggy and unpredictable way. As such, it is important to include a fully formed DOCTYPE declaration on every page of your site and choose a strict DTD when using HTML.

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”

“http://www.w3.org/TR/html4/strict.dtd”>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

          “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

          <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”

             “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

Many HTML editors will automatically add a DOCTYPE declaration for you. If you are creating an XHTML document they may also add an XML declaration before the DOCTYPE declaration:

<?xml version=”1.0″ encoding=”utf-8″?>

An XML declaration is an optional declaration used by XML files to define things such as the version of XML being used and the type of character encoding. Unfortunately, IE 6 automatically switches to quirks mode if the DOCTYPE declaration is not the first element on a page. Therefore, unless you are serving your pages as XML documents, it is best to avoid using an XML declaration.

Getting your styles to hit the target

A valid and well-structured document provides the framework to which your styles are applied. To be able to style a particular (X)HTML element using CSS, you need to have some way of targeting that element. In CSS the part of a style rule that does this is called the selector.

Common selectors

The most common kinds of selectors are type and descendant selectors. Type selectors are used to target a particular type of element, such as a paragraph, an anchor, or a heading element. You do this by simply specifying the name of the element you wish to style. Type selectors are sometimes also referred to as element or simple selectors.

p {color: black;}

a {text-decoration: underline;}

h1 {font-weight: bold;}

Descendant selectors allow you to target the descendants of a particular element or group of elements. A descendant selector is indicated by a space between two other selectors. In this example, only anchor elements that are descendants of a list item will be styled, so anchors within a paragraph will be unaffected.

li a {text-decoration: none;}

These two types of selector are great for applying generic styles that apply across the board. To be more specific and target selected elements, you can use ID and class selectors. As the names suggest, these selectors will target elements with the corresponding ID or class name. ID selectors are identified using a hash character; class selectors are identified with a period. The first rule in this example will make the text in the introductory paragraph bold, and the second rule will make the date green:

#intro {font-weight: bold;}

.datePosted {color: green;}

<p id=”intro”>Some Text</p>

<p class=”datePosted”>24/3/2006</p>

Many CSS authors develop an overreliance on class and, to a lesser extent, ID selectors. If they want to style headlines one way in the main content area and another way in the secondary content area, there is the tendency to create two classes and apply a class to each headline. A much simpler approach is to use a combination of type, descendant, ID, and/or class selectors:

#mainContent h1 {font-size: 1.8em;}

#secondaryContent h1 {font-size: 1.2em;}

<div id=”mainContent”>

<h1>Welcome to my site</h1>

</div>

<div id=”secondaryContent”>

<h1>Latest news</h1>

</div>

This is a very simple and obvious example. However, you will be surprised how many elements you can successfully target using just the four selectors discussed so far. If you find yourself adding lots of extraneous classes to your document, it is probably a warning sign that your document is not well structured. Instead, think about how these elements differ from each other. Often you will find that the only difference is where they appear on the page. Rather than give these elements different classes, think about applying a class or an ID to one of their ancestors, and then targeting them using a descendant selector.

Pseudo-classes

There are instances where you may want to style an element based on something other than the structure of the document—for instance, the state of a form element or link. This can be done using a pseudo-class selector.

/* makes all unvisited links blue */

a:link {color:blue;

 /* makes all visited links green */

a:visited {color:green;}

 /* makes links red when hovered or activated */

a:hover, a:active {color:red;}

/* makes table rows red when hovered over */

 tr:hover {background-color: red;}

* makes input elements yellow when focus is applied */

input:focus {background-color:yellow;}

:link and :visited are known as link pseudo-classes and can only be applied to anchor elements. :hover, :active, and :focus are known as dynamic pseudo-classes and can theoretically be applied to any element. Unfortunately, only a few modern browsers such as Firefox support this functionality. IE 6 and below only pays attention to :active and :hover selectors if applied to an anchor link, and ignores :focus completely.

The universal selector

The universal selector is possibly one of the most powerful and least used of all the selectors. The universal selector acts like a wildcard, matching all the available elements. Like wildcards in other languages, the universal selector is denoted by an asterisk. The universal selector is normally used to style every element on a page. For instance, you can remove the default browser padding and margin on every element using the following rule:

* {

padding: 0;

margin: 0;

}

When combined with other selectors, the universal selector can be used to style all the descendants of a particular element, or skip a level of descendants. You will see how this can be put to practical effect a little later in this chapter.

Advanced selectors

CSS2 has a number of other useful selectors. Unfortunately, while modern browsers such as Firefox and Safari support these advanced selectors, IE 6 and below do not. Luckily, CSS was created with backward compatibility in mind. If a browser doesn’t understand a selector, it ignores the whole rule. That way, you can apply stylistic and usability embellishments in more modern browsers, and not worry about it causing problems in older browsers. Just remember to avoid using these more advanced selectors for anything critical to the functioning of your site.

Child and adjacent sibling selectors

The first of these advanced selectors is the child selector. Whereas a descendant selector will select all the descendants of an element, a child selector only targets the element’s immediate descendants, or “children.” In the following example, the list items in the outer list will be bold while list items in the nested list will remain unaffected:

#nav > li {font-weight: bold;}

<ul id=”nav”>

<li>Home</li>

<li>Services

<ul>

<li>Design</li>

<li>Development</li>

<li>Consultancy</li>

</ul>

</li>

<li>Contact Us </li>

</ul>

It is possible to “fake” a child selector that works in IE 6 and below by using the universal selector. To do this you first apply to all of the descendants the style you want the children to have. You then use the universal selector to override these styles on the children’s descendants. So to fake the previous child selector example you would do this:

#nav li {font-weight: bold;}

#nav li * {font-weight: normal;}

You may also want to style an element based on its proximity to another element. The adjacent sibling selector allows you to target an element that is preceded by another element that shares the same parent. Using the sibling selector, you could make the first paragraph following a top-level heading bold, while leaving other paragraphs unaffected:

h1 + p {font-weight: bold;}

<h1>Main Heading</h1>

<p>First Paragraph</p>

<p>Second Paragraph</p>

Attribute selectors

As the name suggests, the attribute selector allows you to target an element based on the existence of an attribute or the attribute’s value. This allows you to do some very interesting and powerful things. For example, when you hover over an element with a title attribute, most browsers will display a tooltip. You can use this behavior to expand the meaning of things such as abbreviations:

<abbr title=”Cascading Style Sheets”>CSS</abbr>

However, there is no way to tell that this extra information exists without hovering over the element. To get around this problem, you can use the attribute selector to style abbr elements with titles differently from other elements—in this case, by giving them a dotted bottom border. You can provide more contextual information by changing the cursor from a pointer to a question mark when the cursor hovers over the element, indicating that this  element is different from most.

abbr[title] {border-bottom: 1px dotted #999;}

abbr[title]:hover {cursor: help;}

In addition to styling an element based on the existence of an attribute, you can apply styles based on a particular value. For instance, sites that are linked to using a rel attrib-ute of nofollow gain no added ranking benefit from Google. The following rule displays an image next to such links, possibly as a way of showing disapproval of the target site:

a[rel=”nofollow”] {

background-image: url(nofollow.gif);

padding-right: 20px;

}

One clever way of using the attribute selector is to capitalize on the fact that IE 6 and below does not support it. You can then apply one style to IE and another style to more standards-compliant browsers. For instance, IE has problems displaying 1-pixel dotted borders, choosing to render them dashed instead. Using an attribute selector, you could choose to apply your dotted-border style only to browsers you know will render it correctly. This is done by targeting the class attribute rather than using a class selector.

.intro {border-style: solid;}

[class=”intro”] {border-style: dotted;}

Some attributes can have more than one value, separated by spaces. The attribute selector allows you to target an element based on one of those values. For instance, a group of developers have suggested using predefined keywords in the attribute of links to define the relationship one site owner has with another. You can use this information to apply an image to any links that contain the keyword friend in the rel attribute.

a[rel~=”friend”] {background-image: url(friend.gif);}

<a href=”http://www.hicksdesign.com/” rel=”friend met colleague” >

John Hicks

</a>

Using the rel attribute with friend values is known as the XHTML Friends Network, or XFN for short, and is one of several new “microformats” to have developed recently. You can find out more about XFN at http://gmpg.org/xfn/ and about the concept of microformats in general at http://microformats.org.

Once these advanced CSS 2 selectors are widely supported, the need to add extra divs or classes to your code will be greatly reduced.

The cascade and specificity

With even a moderately complicated stylesheet, it is likely that two or more rules will target the same element. CSS handles such conflicts through a process known as the cascade. The cascade works by assigning an importance to each rule. Author stylesheets are considered the most important, followed by user stylesheets, and finally the default stylesheets used by your browser or user agent. To give users more control, they can override any rule by specifying it as !important—even a rule flagged as !important by the author.

So the cascade works in the following order of importance:

User styles flagged as !important

Author styles flagged as !important

Author styles

User styles

Styles applied by the browser/user agent

Rules are then ordered by how specific the selector is. Rules with more specific selectors override those with less specific ones. If two rules are equally specific, the last one defined takes precedence.

Specificity

To calculate how specific a rule is, each type of selector is assigned a numeric value. The specificity of a rule is then calculated by adding up the value of each of its selectors. Unfortunately, specificity is not calculated in base 10 but a high, unspecified, base number. This is to ensure that a highly specific selector, such as an ID selector, is never overridden by lots of less specific selectors, such as type selectors. However, if you have fewer than 10 selectors in a specific selector, you can calculate specificity in base 10 for simplicity’s sake.

The specificity of a selector is broken down into four constituent levels: a, b, c, and d.

If the style is an inline style, then a = 1.

b = the total number of ID selectors.

c = the number of class, pseudo-class, and attribute selectors.

d = the number of type selectors and pseudo-element selectors.

Using these rules it is possible to calculate the specificity of any CSS selector. Table 1-1 shows a series of selectors, along with their associated specificity.

Table 1-1. Specificity example Selector

Selector Specificity Specificity in base 10
Style=”” 1,0,0,0  1000
#wrapper #content {} 0,2,0,0  200
#content .datePosted {} 0,1,1,0 110
div#content {} 0,1,0,1  101
#content {} 0,1,0,0  100
p.comment .dateposted {} 0,0,2,1 21
p.comment{} 0,0,1,1  11
div p {} 0,0,0,2  2
p {} 0,0,0,1  1

At first glance, all this talk of specificity and high but undefined based numbers may seem a little confusing, so here’s what you need to know. Essentially, a rule written in a style attribute will always be more specific than any other rule. A rule with an ID will be more specific than one without an ID, and a rule with a class selector will be more specific than a rule with just type selectors. Finally, if two rules have the same specificity, the last one defined prevails.

Using specificity in your stylesheets

Specificity is very useful when writing CSS as it allows you to set general styles for common elements and then override them for more specific elements. For instance, say you want most of the forms on your site to be 30em wide but your search form needs to be only 15em wide:

form {width: 30em;}

form#search {width: 15em;}

Whenever you want to create a new form you do not have to worry about changing anything in the CSS, as you know it will be styled correctly. However, on larger sites you will find more and more exceptions will start to creep in. Maybe you will have a login form that you want to be 20em wide or a larger application form that needs to be 40em wide. Each time you create a more specific style, you will probably need to override some of the general rules. This can lead to quite a bit of extra code. It can also start to get very complicated as one element may be picking up styles from a variety of places.

Adding a class or an ID to the body tag

One interesting way to use specificity is to apply a class or an ID to the body tag. By doing this, you can then override styles on a page-by-page or even a sitewide basis. For instance, if you wanted your homepage to have a different layout from the rest of your site, you could add a class name to the body element on your home page and use it to override your styles:

#content {

float: left;

}

.homepage #content {

float: right;

}

#nav {

float: right;

}

.homepage #nav {

float: left;

}

You will see later on how this technique can be used to highlight the current page a visitor is on in your site navigation.

Adding an ID to every page of your site gives users the ability to override your stylesheets with their own user stylesheets. Site-wide IDs, known colloquially as CSS signatures, tend to take the format id=”www-sitename-com”. At a simple level the users may want to override your font sizes or color scheme to make the site easier to read. They could do so by adding the following rule to their user stylesheet:

body#www-andybudd-com {

font-size: 200%

background-color: black;

color: white;

}

However, it doesn’t need to stop there. CSS signatures give your users the power to completely restyle your site. They could hide elements they don’t like, change the layout, or come up with a completely new design.

Inheritance

People often confuse inheritance with the cascade. Although they seem related at first glance, the two concepts are actually quite different. Luckily, inheritance is a much easier concept to grasp. Certain properties, such as color or font size, are inherited by the descendants of the elements those styles are applied to. For instance, if you were to give the body element a text color of black, all the descendants of the body element would also have black text. The same would be true of font sizes. If you gave the body a font size of 14 pixels, everything on the page should inherit that font size. I say should because IE for Windows and Netscape have problems inheriting font sizes in tables. To get around this, you will either have to specify that tables should inherit font sizes or set the font size on tables separately.

If you set the font size on the body, you will notice that this style is not picked up by any headings on the page. You may assume that headings do not inherit text size. But it is actually the browser default stylesheet setting the heading size. Any style applied directly to an element will always override an inherited style. This is because inherited styles have a null specificity.  Inheritance is very useful as it lets you avoid having to add the same style to every descendant of an element. If the property you are trying to set is an inherited property, you may as well apply it to the parent element. After all, what is the point of writing this:

p, div, h1, h2, h3, ul, ol, dl, li {color: black;}

when you can just write this:

body {color: black;}

Just as sensible use of the cascade can help simplify your CSS, good use of inheritance can help to reduce the number and complexity of the selectors in your code. It you have lots of elements inheriting various styles, though, determining where the styles originate can become confusing.

Planning, organizing, and maintaining your stylesheets

The larger, more complicated, and graphically rich your sites become, the harder your CSS is to manage. In this section, I will look at ways to help you manage your code, including splitting up your files into multiple stylesheets, grouping your styles into logical sections, and adding comments to make your code easier to read.

Applying styles to your document

You can add styles directly to the head of a document by placing them between style tags; however, this is not a very sensible way to apply styles to a document. If you want to create another page using the same styles, you would have to duplicate the CSS on the new page. If you then wanted to change a style, you would have to do it in two places rather than one. Luckily, CSS allows us to keep all our styles in one or more external stylesheets. There are two ways to attach external stylesheets to a web page. You can link to them or you can import them:

<link href=”/css/basic.css” rel=”stylesheet” type=”text/css” />

<style type=”text/css”>

<!–

@import url(“/css/advanced.css”);

–>

</style>

Older browsers such as Netscape 4 do not understand importing. Therefore, you can use import to hide complicated styles from older browsers, which they may not understand. Using this method you can even create one design for older browsers and another for more modern versions.

You do not have to confine importing to an (X)HTML document. You can also import one stylesheet from another stylesheet. This allows you to link to your basic stylesheet from the (X)HTML page and then import your more complicated styles into that stylesheet (see Figure 1-4):

@import url(/css/layout.css);

@import url(/css/typography.css);

@import url(/css/color.css);

Figure 1-4. Multiple stylesheets can be imported into a single stylesheet that is then linked to your HTML page.

This helps to remove some complexity from your (X)HTML documents and allows you to manage all your stylesheets in one place. Import rules need to be the first rules in a stylesheet or they may not work properly. Because imported stylesheets are considered to come before linked stylesheets, it’s important to remember that the rules in your linked stylesheets will be overriding your imported rules and not the other way around.

While it is theoretically possible to import one stylesheet into a stylesheet that is itself being imported, this type of daisy chaining or multilevel nesting is not well supported. As such, you should probably avoid nesting imports more than two levels deep. Very few people use Netscape 4 these days, so you probably do not need to worry too much about this browser. You could forget the simple linked stylesheet and import your styles instead. However, IE 5/6 for Windows have a strange quirk that affects pages using only the import rule. When an affected page loads, it is temporarily displayed unstyled, before the styles are finally rendered. The bug is called the “Flash of Unstyled Content” bug, or FOUC for short. Having a link or script element in the head of your document prevents this bug, so even if you are not too worried about supporting Netscape 4, it may still be worth linking to a basic stylesheet and then importing your styles from there.

Commenting your code

When writing your own stylesheets, you will have a good idea how they are structured, what problems you have encountered, and why things have been done a certain way. But if you come back to that stylesheet in 6 months, there is a good chance you will have forgotten much of this. Additionally, you may need to hand your CSS to somebody else for implementation, or another developer may have to edit your code in the future. It is therefore a good idea to comment your code.  Adding comments in CSS is very simple. A CSS comment starts with /* and ends with */. This type of commenting is known as C style commenting as it is the type of comment used in the C programming language. Comments can be single or multiline and can appear anywhere within the code.

          /* Body Styles */

          body {

            font-size: 67.5%; /* Set the font size */

          }

Adding structural comments

The first thing can be done when creating a new stylesheet is add a comment block at the top to describe what the stylesheet is for, the creation date or version number, who created it, and how to get in touch with them:

          /*–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

          Basic Style Sheet (for version 4 browsers)

version:1.1

Author:any Budd

email:info@andybudd.com

Website:http://www.andybudd.com

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/

This gives other developers a good overview of the file, allows them to see if it is current, and gives them a means of tracking down the original author if something doesn’t make sense.

I then break the stylesheet down into sensible chunks. I usually start with general rules such as typography, headlines, and links. Next I tackle the major sections of a page based on how they appear in the flow of the document. This will typically include a branding section, main content, secondary content, main nav, secondary nav, and a footer section. Lastly, I deal with general elements that appear intermittently throughout the site. These are usually things like box styles, form styles, and graphical buttons. Similar to the introductory comment, I use a large stylized comment header to help visually separate each section:

/* Typography

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/

Not everything naturally falls into a well-defined block, so some judgment is required. Keep in mind that the more you can break up and objectify your code, the easier it is to understand and the quicker you can find the rules you are looking for.

If your CSS files become very long, finding the style you want can be difficult. One way to speed things up is to add a flag to each of your comment headers. A flag is simply an extra character preceding your header text that does not naturally appear in your CSS files. A search for your flag followed by the first couple of letters in your comment header will take you right to the part of the file you’re looking for. So in this example, a search for “=typ” will take you straight to the typography section of your stylesheet:

/* =Typography

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/

Because many CSS files tend to have a similar structure, you can save time by creating your own precommented CSS templates to use on all your projects. You can save even more time by adding a few common rules that you use in all of your sites, to create a sort of prototype CSS file. That way, you will not have to reinvent the wheel each time you start a new project.

Note to self

Sometimes you may need to use a hack or workaround to solve a particular problem. In these cases it is a good idea to document the problem, the workaround you used, and, if available, a URL explaining the fix:

/*

Use the star selector hack to give IE a different font size http://www.info.com.ph/~etan/w3pantheon/style/starhtmlbug.html */

* html body {

font-size: 75%;

}

To make your comments more meaningful, you can use keywords to distinguish important comments. I use TODO as a reminder that something needs to be changed, fixed, or revisited later on; BUG to document a problem with the code or a particular browser; and KLUDGE to explain a nasty workaround:

/* :TODO: Remember to remove this rule before the site goes live */

/* :KLUDGE: I managed to fix this problem in IE by setting a small negative margin but it’s not pretty */

/* :BUG: Rule breaks in IE 5.2 Mac */

You could also use the keyword TRICKY to alert other developers about a particularly complicated piece of code. In programming terms, these keywords are called gotchas and can prove very helpful in the later stages of development.

Removing comments and optimizing your stylesheets

Comments can increase the size of your CSS files quite considerably. Therefore, you may want to strip comments from your live stylesheets. Many HTML/CSS and text editors have a search and replace option, making it pretty easy to remove comments from your code. Alternatively, you could use one of several online CSS optimizers such as the one found at www.cssoptimiser.com/. Not only does an optimizer remove comments but it also strips out whitespace, helping to shave off a few extra bytes from your code.

Some people have experimented with writing comments in PHP format and then serving their stylesheets up as PHP. The stylesheets will get sent to the PHP parser, which will strip out all the comments, before being sent to the browser. You can do this by setting the MIME type for CSS files in an .htaccess file:

addtype application/x-httpd-php .css

However, you need to make sure that your CSS files are being cached or this approach will slow down rather than increase the speed of your site. This can be done using PHP, but it does start to get complicated—therefore, it is probably best avoided unless you are confident that you know what you are doing. The best option is probably to enable server-side compression. If you are using an Apache server, talk to your hosts about installing mod_gzip or mod_deflate. Many modern browsers can handle files compressed with GZIP, and decompress them on the fly. These Apache modules will detect whether your browser can handle such files, and if it can, send a compressed version. Server-side compression can reduce your (X)HTML and CSS files by around 80 percent, reducing your bandwidth and making your pages much faster to download. If you don’t have access to these Apache modules, you still may be able to compress your files by following the tutorial.

Style guides

Most websites will have more than one person working on them, and larger sites can involve several teams all working on different aspects of the site. It is possible that programmers, content managers, and other front-end developers may need to understand how elements of your code and design function. Therefore, it is a very good idea to create a style guide.

A style guide is a document, web page, or microsite that explains how the code and visual design of a site are pieced together. A good style guide should start with an overview of the site structure, file structure, and naming conventions used. It should contain detailed information about the coding standards that designers, developers, and content editors need to adhere to in order to maintain the quality of the site. This could include things like the versions of XHTML/CSS to use, the chosen accessibility level, browser support details, and general coding best practices. The style guide should detail layout and stylistic elements such as the dimensions of various elements, the size of gutters, the color palette used, and the associated hex values. The style guide should also give details and examples of any special CSS styles used. For instance, if you were using a class to denote feedback, you would show what elements the class could be applied to and how those elements would look. Style guides are a great way of handing a project over to those responsible for maintaining or implementing the site. By setting down some simple guidelines, you can help ensure the site develops in a controlled way, and help lessen the fragmentation of your styles over time.

Organizing your stylesheets for easy maintenance

For a simple website, you can get away with using a single CSS file. With larger and more complicated sites, it can be a good idea to separate your styles for ease of maintenance. How you separate your styles is a matter of choice. I generally have one CSS file for the basic layout and another for typography and design embellishment. This way, once the layout is set, I rarely have to go back and change the layout stylesheet. This also protects my layout stylesheet from accidentally being altered and breaking.

You can abstract things further by creating a separate CSS file for color. Then, if you want to offer different color themes, it is easy to create a new color stylesheet. If you have lots of forms on your site, you may want to create a separate CSS file for all of your form styles. You can then link to that file only when it is needed, thus reducing the initial download overhead. If you have some pages on your site that are very distinct from the rest of your site, you may want to consider splitting these off into their own CSS files. For instance, if your homepage layout is very different from the rest of the site, you may want to create a separate CSS file just for the homepage. It’s worth bearing in mind that every CSS file means an extra call to the server. This can cause a performance hit, so some developers prefer to have one large CSS file rather than several smaller ones. The final choice really depends on the situation and is, to some degree, a matter of personal preference.

 

VISUAL FORMATTING MODEL RECAP

Three of the most important CSS concepts to grasp are floating, positioning, and the box model. These concepts control the way elements are arranged and displayed on a page, forming the basis of CSS layout. If you are used to controlling layout with tables, these concepts may seem strange at first. In fact, most people will have been developing sites using CSS for some time before they fully grasp the intricacies of the box model, the difference between absolute and relative positioning, and how floating and clearing actually work. Once you have a firm grasp of these concepts, developing sites using CSS becomes that much easier.

Box model recap

The box model is one of the cornerstones of CSS and dictates how elements are displayed and, to a certain extent, how they interact with each other. Every element on the page is considered to be a rectangular box made up of the element’s content, padding, border, and margin (see Figure 1-5).

Figure 1-5. Illustration of the box model

Padding is applied around the content area. If you add a background to an element, it will be applied to the area formed by the content and padding. As such, padding is often used to create a gutter around content so that it does not appear flush to the side of the background. Adding a border applies a line to the outside of the padded area. These lines come in various styles such as solid, dashed, or dotted. Outside the border is a margin. Margins are transparent and cannot be seen. They are generally used to control the spacing between elements. Padding, borders, and margins are optional and default to zero. However, many elements will be given margins and padding by the useragent stylesheet. You can override these browser styles by setting the element’s margin or padding back to zero. You can do this on a case-by-case basis or for every element by using the universal selector:

*{
margin: 0;

padding: 0;

}

In CSS, width and height refer to the width and height of the content area. Adding padding, borders, and margins will not affect the size of the content area but will increase the overall size of an element’s box. If you wanted a box with a 10-pixel margin and a 5-pixel padding on each side to be 100 pixels wide, you would need to set the width of the content to be 70 pixels (see Figure 1-6):

#myBox {

margin: 10px;

padding: 5px;

width: 70px;

}

Figure 1-6. The correct box model

Padding, borders, and margins can be applied to all sides of an element or individual sides. Margins can also be given a negative value and can be used in a variety of techniques.

IE/Win and the box model

Unfortunately, IE 5.x and IE 6 in quirks mode use their own, nonstandard box model. Instead of measuring just the width of the content, these browsers take the width property as the sum of the width of the content, padding, and borders. This actually makes a lot of sense because in the real world boxes have a fixed size and the padding goes on the inside. The more padding you add, the less room there would be for the content. However, despite the logic, the fact that these versions of IE disregard the specification can cause significant problems. For instance, in the previous example the total width of the box would only be 90 pixels in IE 5.x. This is because IE 5.x will consider the 5 pixels of padding on each side as part of the 70-pixel width, rather than in addition to it (see Figure 1-7).

Figure 1-7. Internet Explorer’s proprietary box model can cause elements to be smaller than intended.

Luckily, there are several ways you can tackle this issue. However, by far the best solution is to avoid the problem altogether. You can do this by never adding padding to an element with a defined width. Instead, try adding padding or margins to the element’s parent or children.

Margin collapsing

Margin collapsing is a relatively simple concept. In practice, however, it can cause a lot of confusion when you’re laying out a web page. Put simply, when two or more vertical margins meet, they will collapse to form a single margin. The height of this margin will equal the height of the larger of the two collapsed margins. When two elements are above one another, the bottom margin of the first element will collapse with the top margin of the second element (see Figure 1-8).

Figure 1-8. Example of an element’s top margin collapsing with the bottom margin of the preceding element

When one element is contained within another element, assuming there is no padding or border separating margins, their top and/or bottom margins will also collapse together (see Figure 1-9).

Figure 1-9. Example of an element’s top margin collapsing with the top margin of its parent element

It may seem strange at first, but margins can even collapse on themselves. Say you have an empty element with a margin, but no border or padding. In this situation the top margin is touching the bottom margin and they collapse together (see Figure 1-10).

Figure 1-10. Example of an element’s top margin collapsing with its bottom margin

If this margin is touching the margin of another element, it will itself collapse (see Figure 1-11).

Figure 1-11. Example of an empty element’s collapsed margin collapsing with another empty element’s margins

This is why a series of empty paragraph elements take up very little space, as all their margins collapse together to form a single small margin. Margin collapsing may seem strange at first, but it actually makes a lot of sense. Take a typical page of text made up of several paragraphs (see Figure 1-12). The space above the first paragraph will equal the paragraph’s top margin. Without margin collapsing, the space between all subsequent paragraphs will be the sum of their two adjoining top and bottom margins. This means that the space between paragraphs will be double the space at the top of the page. With margin collapsing, the top and bottom margins between each paragraph collapse, leaving the spacing the same everywhere.

Figure 1-12. Margins collapse to maintain consistent spacing between elements.

Margin collapsing only happens with the vertical margins of block boxes in the normal flow of the document. Margins between inline boxes, floated, or absolutely positioned boxes never collapse.

Positioning recap

Now that you are familiar with the box model, let’s take a look at the visual formatting and positioning models. Understanding the nuances of both of these models is vitally important as together they control how every element is arranged on a page.

The visual formatting model

People often refer to elements such as p, h1, or div as block-level elements. This means they are elements that are visually displayed as blocks of content, or “block boxes.” Conversely, elements such as strong and span are described as inline elements because their content is displayed within lines as “inline boxes.” It is possible to change the type of box generated by using the display property. This means you can make an inline element such as an anchor behave like a block-level element by setting its display property to block. It is also possible to cause an element to generate no box at all by setting its display property to none. The box, and thus all of its content, is no longer displayed and takes up no space in the document.

There are three basic positioning schemes in CSS: normal flow, floats, and absolute positioning. Unless specified, all boxes start life being positioned in the normal flow. As the name suggests, the position of an element’s box in the normal flow will be dictated by that element’s position in the (X)HTML. Block-level boxes will appear vertically one after the other; the vertical distance between boxes is calculated by the boxes’ vertical margins. Inline boxes are laid out in a line horizontally. Their horizontal spacing can be adjusted using horizontal padding, borders, and margins (see Figure 1-13). However, vertical padding, borders, and margins will have no effect on the height of an inline box. The horizontal box formed by a line is called a line box, and a line box will always be tall enough for all the line boxes it contains. There is another caveat, though—setting the line height can increase the height of this box.

Figure 1-13. Inline elements within a line box

In the same way that (X)HTML elements can be nested, boxes can contain other boxes. Most boxes are formed from explicitly defined elements. However, there is one situation where a block-level element is created even if it has not been explicitly defined. This occurs when you add some text at the start of a block-level element like a div. Even though you have not defined the text as a paragraph, it is treated as such:

<div>

some text

<p>Some more text</p>

</div>

In this situation, the box is described as an anonymous block box since it is not associated with a specifically defined element. A similar thing happens with the lines of text inside a block-level element. Say you have a paragraph that contains three lines of text. Each line of text forms an anonymous line box. You cannot style anonymous block or line boxes directly as there is nothing to hook on to. However, it is useful to understand that everything you see on your screen creates some form of box.

Relative positioning

Relative positioning is a fairly easy concept to grasp. If you relatively position an element, it will stay exactly where it is. You can then shift the element “relative” to its starting point by setting a vertical or horizontal position. If you set the top position to be 20 pixels, the box will appear 20 pixels below the top of its original position. Setting the left position to 20 pixels will create a 20-pixel space on the left of the element, moving the element to the right (see Figure 1-14).

#myBox {

position: relative;

left: 20px;

top: 20px;

}

Figure 1-14. Relatively positioning an element

With relative positioning, the element continues to occupy the original space, whether or not it is offset. As such, offsetting the element can cause it to overlap other boxes.

Absolute positioning

Relative positioning is actually considered part of the normal flow positioning model, as the position of the element is relative to its position in the normal flow. By contrast, absolute positioning takes the element out of the flow of the document, thus taking up no space. Other elements in the normal flow of the document will act as though the absolutely positioned element was never there (see Figure 1-15).

Figure 1-15. Absolutely positioning an element

An absolutely positioned element is positioned in relation to its nearest positioned ancestor. If the element has no positioned ancestors, it will be positioned in relation to the initial containing block. Depending on the user agent, this will either be the canvas or the HTML element. As with relatively positioned boxes, an absolutely positioned box can be offset from the top, bottom, left, or right of its containing block. This gives you a great deal of flexibility. You can literally position an element anywhere on the page.

The main problem people have with positioning is remembering which type of positioning is which. Relative positioning is “relative” to the element’s initial position in the flow of the document, whereas absolute positioning is “relative” to nearest positioned ancestor or, if one doesn’t exist, the initial container block.

Because absolutely positioned boxes are taken out of the flow of the document, they can overlap other elements on the page. You can control the stacking order of these boxes by setting a property called the z-index. The higher the z-index, the higher up the box appears in the stack. Positioning an absolutely positioned element in relation to its nearest positioned ancestor allows you to do some very interesting things. For instance, say you wanted to align a paragraph of text at the bottom right of a large box. You could simply give the container box a relative position and then absolutely position the paragraph in relation to this box:

#branding {

width: 700px;

height: 100px;

position: relative;

}

#branding .tel {

position: absolute;

right: 10px;

bottom: 10px;

text-align: right;

}

<div id=”branding”>

<p class=”tel”>Tel: 0845 838 6163</p>

</div>

Absolutely positioning a box in relation to a relatively positioned ancestor works well in most modern browsers. However, there is a bug in IE 5.5 and IE 6 on Windows. If you try to set the position of the absolutely positioned box relative to the right or bottom of the relatively positioned box, you need to make sure the relatively positioned box has some dimensions set. If not, IE will incorrectly position the box in relation to the canvas instead. The simple solution is to set the width and height of your relative box to avoid this problem.

Absolute positioning can be a useful tool when laying out a page, especially if it is done using relatively positioned ancestors. It is entirely possible to create a design solely using absolute positioning. For this to work, these elements need to have fixed dimensions so you can position them where you want without the risk of overlapping.Because absolutely positioned elements are taken out of the flow of the document, they have no effect on boxes in the normal flow. If you were to enlarge an absolutely positioned box by increasing the font size, for instance the surrounding boxes wouldn’t reflow. As such, any change in size can ruin your finely tuned layout by causing the absolutely positioned boxes to overlap.

Fixed positioning

Fixed positioning is a subcategory of absolute positioning. The difference is that a fixed element’s containing block is the viewport. This allows you to create floating elements that always stay at the same position in the window. An example of this can be seen at snook.ca (see Figure 1-16). The weblog comment form has been given a fixed position to keep it anchored at the same place on screen when the page is scrolled. This really helps improve usability and you don’t have to scroll all the way to the bottom of the page to leave a comment.

Figure 1-16. At snook.ca, the comment field on the right side of the screen uses a fixed position to stay at the same position in the viewport.

Unfortunately, IE 6 and below do not support fixed positioning. To get around this problem, Jonathan Snook uses JavaScript to replicate the effect in IE.

Floating

The last positioning model is the float model. A floated box can either be shifted to the left or the right until its outer edge touches the edge of its containing box, or another floated box. Because floated boxes aren’t in the normal flow of the document, block boxes in the regular flow of the document behave as if the floated box wasn’t there. As shown in Figure 1-17, when you float Box 1 to the right, it’s taken out of the flow of the document and moved to the right until its right edge touches the right edge of the containing block.

Figure 1-17. Example of an element being floated right

In Figure 1-18, when you float Box 1 to the left, it is taken out of the flow of the document and moved left until its left edge touches the left edge of the containing block. Because it is no longer in the flow, it takes up no space and actually sits on top of Box 2, obscuring it from view. If you float all three boxes to the left, Box 1 is shifted left until it touches its containing box, and the other two boxes are shifted left until they touch the preceding floated box.

Figure 1-18. Example of elements being floated left

If the containing block is too narrow for all of the floated elements to fit horizontally, the remaining floats will drop down until there is sufficient space (see Figure 1-19). If the floated elements have different heights, it is possible for floats to get “stuck” on other floats when they drop down.

Figure 1-19. If there is not enough available horizontal space, floated elements will drop down until there is.

Line boxes and clearing

Line boxes next to a floated box are shortened to make room for the floated box, and flow around the float. In fact, floats were created to allow text to flow around images (see Figure 1-20).

Figure 1-20. Line boxes shorten when next to a float.

To stop line boxes flowing around the outside of a floated box, you need to apply a clear to that box. The clear property can be left, right, both, or none, and indicates which side of the box should not be next to a floated box. To accomplish this, enough space is added above the cleared element’s top margin to push the element’s top border edge vertically down, past the float (see Figure 1-21).

Figure 1-21. Clearing an element’s top margin to create enough vertical space for the preceding float

As you’ve seen, floated elements are taken out of the flow of the document and have no effect on surrounding elements. However, clearing an element essentially clears a vertical space for all the preceding floated elements.

This can be a useful layout tool as it allows surrounding elements to make space for floated elements. This solves the problem we saw earlier with absolute positioning where changes in vertical height do not affect surrounding elements and can break your design.

Let’s have a look at floating and clearing in a little more detail. Say you have a picture that you want to float to the left of a block of text. You want this picture and text to be contained in another element with a background color and border. You would probably try something like this:

.news {

background-color: gray;

border: solid 1px black;

}

.news img {

float: left;

}

.news p {

float: right;

}

<div class=”news”>

<img src=”news-pic.jpg” />

<p>Some text</p>

</div>

However, because the floated elements are taken out of the flow of the document, the wrapper div takes up no space. How do you visually get the wrapper to enclose the floated element? You need to apply a clear somewhere inside that element (see Figure 1-22). Unfortunately, no existing element is available that we can clear so you need to add an empty element and clear that.

.news {

background-color: gray;

border: solid 1px black;

}

.news img {

float: left;

}

.news p {

float: right;

}

.clear {

clear: both;

}

<div class=”news”>

<img src=”news-pic.jpg” />

<p>Some text</p>

<div class=”clear”></div>

</div>

Figure 1-22. Because floats take up no space, they are not enclosed by container elements. The addition of an empty clearing element forces the container element to enclose the floats.

This gets the result we want, but at the expense of adding extraneous code to our markup. Often there will be an existing element you can apply the clear to, but sometimes you may have to bite the bullet and add meaningless markup for the purpose of layout.

Instead of clearing the floated text and image, you could choose to float the container div as well:

.news {

background-color: gray;

border: solid 1px black;

float: left;

}

.news img {

float: left;

}

.news p {

float: right;

}

<div class=”news”>

<img src=”news-pic.jpg” />

<p>Some text</p>

</div>

This creates the desired result. Unfortunately, the next element is now going to be affected by the float. To solve this problem, some people choose to float nearly everything in a layout and then clear those floats using an appropriate meaningful element, often the site footer. This helps reduce or eliminate the need for extraneous markup. However, floating can be complicated and some older browsers may choke on heavily floated layouts. As such, many people prefer to add that extra bit of markup.

Applying an overflow property of hidden or auto will automatically clear any contained floats without the addition of extra markup. This method is not appropriate in all situations, since setting the box’s overflow property will affect how it behaves. Lastly, some people have taken to clearing floats using CSS-generated content or JavaScript. The basic concept for both methods is the same. Rather than add a clearing element directly to the markup, you add it to the page dynamically. For both methods you need to indicate where the clearing element goes, and this is usually done with the addition of a class name:

<div class=”news clear”>

<img src=”news-pic.jpg” />

<p Some text</p>

</div>

Using the CSS method, you use the :after pseudo-class in combination with the content declaration to add new content at the end of the specified existing content. In this case I’m adding a full stop as it is a fairly small and unobtrusive character. You don’t want the new content to take up any vertical space or be displayed on the page, so you need to set height to 0 and visibility to hidden. Because cleared elements have space added to their top margin, the generated content needs to have its display property set to block. Once this is done, you can then clear your generated content:

.clear:after {

content: “.”;

height: 0;

visibility: hidden;

display: block;

clear: both;

}

classbocstart

This method works in most modern browsers but fails in Internet Explorer 6 and below. Various workarounds are available, many of which are documented at www.positioniseverything.net/easyclearing.html. The most common of these involves using the Holly Hack  to trick IE 5-6 into applying “Layout” and incorrectly clearing the floats.

.clear {

display: inline-block;

}

/* Holly Hack Targets IE Win only \*/

  • html .clear {height: 1%;}

.clear {display: block;} /* End Holly Hack */

However, due to its complexity this method may not be suitable for everybody.

Unlike the previous method, the JavaScript method works on all major browsers when scripting is turned on. However, if you use this method, you need to make sure that the content is still readable when scripting is turned off.

Summary

In this chapter you’ve seen how a well-structured and meaningful document can help provide a solid framework for applying your styles. You’ve learned about some of the more advanced CSS selectors and how CSS handles conflicting rules. You’ve also seen how well-structured and well-commented CSS files can make your life easier and increase your productivity. In this chapter you have learned about some of the peculiarities of the box model. You have seen how vertical adjacent margins collapse to form a single margin, and how IE 5.x on Windows interprets the width property differently from other browsers. You now understand the difference between absolute and relative positioning and how useful absolute positioning in a relative container can be. Lastly, you have seen how floats behave in various circumstances and learned that clearing works by increasing the cleared element’s top margin.Now that you are armed with this knowledge, let’s start putting it to good use. So open your favorite text editor, and let’s get coding.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.