Rediscovering attribute selectors
In this article I'll explain how to use CSS 2.1 attribute selectors to stylize a web document. The core syntax of attribute selectors is explained below.
Table of contents
- Syntax of attribute selectors
- The markup
- Global styles
- The header
- Main content and sidebar
- Form elements
- The footer
- Download examples
Syntax of attribute selectors
Attribute selectors match elements with four different patterns:
[attribute]Matches the element when it has the
attributeattribute, whatever the value of the attribute. For example, the following CSS code:p[class] {color: green}
will match the following (X)HTML element:
<p class="foo">Lorem ipsum</p>
[attribute="value"]Matches the element when its
attributeattribute value is exactlyvalue. For example, the following CSS code:p[class="foo"] {color: green}
will match the following (X)HTML element:
<p class="foo">Lorem ipsum</p>
[attribute~="value"]Matches the element when its
attributeattribute value is a space separated list of words, one of which is exactlyvalue. For example, the following CSS code:p[class~="foo"] {color: green}
will match the following (X)HTML element:
<p class="foo bar baz">Lorem ipsum</p>
The words in the value must not contain spaces, since they are separated by spaces.
[attribute|="value"]Matches the element when its
attributeattribute value is a hyphen-separated list of words, beginning withvalue. For example, the following CSS code:p[class|="foo"] {color: green}
will match the following (X)HTML element:
<p class="foo-bar-baz">Lorem ipsum</p>
The match always start at the beginning of the attribute value.
The markup
We start with the following markup:
Listing 1. The markup of the page
<div id="page"><div id="header"><div id="img-header"><h1><a href="#">Racing Thoughts</a></h1><div class="description">Just another WordPress weblog</div></div></div><hr /><div id="content" class="narrow-column"><div class="post" id="post-3"><h2><a href="#" rel="bookmark" title="Permanent Link to Lorem ipsum dolor">Lorem ipsum dolor</a></h2><small>August 15th, 2008</small><div class="entry"><p>...</p></div>...omission...</div></div><div id="sidebar"><ul><li><form method="get" id="searchform" action="#"><label class="hidden" for="s">Search for:</label><div><input value="" name="s" id="s" type="text" /><input id="searchsubmit" value="Search" type="submit" /></div></form></li>...omission...</ul>...omission...</div><hr /><div id="footer"><p>Racing Thoughts is proudly powered by <a href="#">WordPress</a> <br /><a href="#">Entries (RSS)</a> and <a href="#">Comments (RSS)</a>.</p></div></div>
We're not interested in the basic styles given to this first example, so we'll skip them and focus only on the sections where attribute selectors are actually used.
Global styles
Let's start with stylizing the global wrapper, #page.
Listing 2. Global styles
div[id="page"] {font-size: 120%;margin: 0;width: 100%;}
View the example - View the screenshot
We've just increased a bit the base font size of the page, while adding a width declaration in order to prevent Internet Explorer 7 from applying its wrong behavior.
The header
We're going now to stylize the header. The styles are the following:
Listing 3. The header
div[id="header"] {width: 100%;height: 5em;min-height: 80px;background: #fff url("../img/banner.png") no-repeat 0 0;position: relative;}div[id|="img"] {position: absolute;left: 200px;top: 0;}div[class="description"] {text-align: right;font: italic 120%/normal Georgia, serif;margin-top: -5px;}
View the example - View the screenshot
The second rule is interesting. Since the container of the title has an ID value made up of
two hyphen-separated words (img-header), this rule match the element. Remember that
the word selected is always the first in the list.
Main content and sidebar
For the main content and the sidebar we'll use more complex patterns.
Listing 4. Main content and sidebar
div[id="content"][class|="narrow"] {margin: 0;float: left;width: 65%;padding: 0 5%;}div[class="post"][id="post-3"] {padding: 1em;border: 1px solid #c0c0c0;margin: 1em 0;}div[class="post"] a[title~="Permanent"] {color: #800;text-transform: uppercase;border-left: 1px solid #000;display: block;text-indent: 0.2em;}div[id="sidebar"] {float: right;width: 25%;}
View the example - View the screenshot
As you can see, attribute selectors can be combined to create more complex patterns. A complex pattern matches
an element when all the attribute selectors in the chain match the element. For example, the second rule matches
its target element only if this element has two IDs with post and post-3 as values, respectively.
Form elements
Attribute selectors are really useful when dealing with form elements, as shown below.
Listing 5. Form elements
form[method="get"] {margin: 0;padding: 0.5em;border: 1px solid #c0c0c0;}input[type="text"] {width: 100px;border: 1px solid #000;background: #fff;font: 1em Arial, sans-serif;}input[type="submit"] {font: 1em Arial, sans-serif;background: #666;color: #fff;font-weight: bold;border: 1px solid #c0c0c0;}
View the example - View the screenshot
Through attribute selectors we can stylize a form element based on the presence of a particular value in its
method or action attributes. So if we have two different forms on a page, we can give them different
styles, for example by matching the value of its action attribute. Moreover, attribute selectors can give different
styles to input elements by matching the value of their type attribute in order to keep form controls
separated.
The footer
The styles for the footer are really simple.
Listing 6. The footer
div[id="footer"] {clear: both;margin: 0;height: 5em;background: #fff url("../img/footer.png") no-repeat 0 0;}
View the example - View the screenshot
The final layout is depicted in the following image.
