When I first started to teach myself HTML and CSS in 2011 I developed a method of adding ids and classes to almost every element I wanted to control. It was effective, and perhaps the most backward compatible way of styling your HTML.

It is regarded as good practice that we should refrain from decorating our HTML with presentational hooks such as ids and classes in order keep our code clean and easy to maintain. I found that in my early days, it was down to the lack of exposure to what selectors are available to me with CSS that encouraged me to stick with what I knew.

So this is the focus of this article/tutorial. I aim to share with you the CSS selectors that got me going coding out websites in a more maintainable manner. Leaving me with clean, efficient, structure focused HTML.

From learning a little more about Web Standards I came to think this method was wrong, but that's not entirely true. There is no set method of coding out our websites and what is best practice for one, is poor practice for another. As browsers read our CSS selector from right to left, the quicker we specify the key selector, the less time the browser takes to isolate and stylise the element. This issue was of a higher priority when technology was a lot slower in processing our code. Today this idea holds less prominence but it's still worth the consideration when we take on new projects.

Decorating your markup with classes and ids and matching purely on those while avoiding all uses of sibling, descendant and child selectors will actually make a page perform significantly better in all browsers.

- Dave Hyatt May 6th, 2008 2:56pm

So when would using ids and classes be a good idea?

When you're building big sites. The kind of sites that every scrap of performance tuning you can put in could make the difference. Having the added markup in the HTML can enhance the rendering speed of your site. However, for most smaller and simpler projects there are to few instances where this kind of performance boosting would be of benefit. It is more likely to make our code harder to maintain with not much return on performance.

It's not a one size fits all. You will need to assess the task at hand and let that inform you as which which approach you should take. For further information on this subject I can recommend you read through some of what Chris Coyier and Harry Roberts have to say.

Note: It is assumed in this reference that you are structuring your HTML to Web Standards compliance. As to say that you're using elements available in HTML that were designed for specific purposes.

for example: ensuring your page headers are in the appropriate <h1> - <h6> tags and your paragraphs are contained within the <p> tag.

If this doesn't sound familiar to you I strongly recommend you head over to HTML Dog for some easy to follow tutorials on HTML markup conforming to web standards or to the official W3C list of HTML tags if you wanted a quick reference.

Still here? Great! Let's get started:

  • X (CSS1)

    Tag selector

    effect: Targets all elements of tag type X

    CSS

    p {

    color:#f72626;

    }

    HTML

    <p>As you can see, the text colour in this paragraph is red</p>

    <p>Text in this paragraph is also red</p>

    Result

    As you can see, the text colour in this paragraph is red

    Text in this paragraph is also red

    Browser support: Full Support

    Perhaps the most basic of selectors but perhaps a crucial one to address. The ability to select all the occurrences of one element. In this case we can use the paragraph tag selector to boost consistency and rhythm to the typography.

  • X Y (CSS1)

    Descendant combinator

    effect: Targets all elements of type Y that are a child of an X element

    CSS

    li a {

    color:#2f2;

    }

    HTML

    <ul>

    <li>I'm not a link</li>

    <li>I'm not a link either</li>

    <li><a href="#">I'm a link</a></li>

    </ul>

    Result

    Browser support: Full Support

    Another simple selector, the descendant combinator here allows us to control any anchor tags that are a child of the <li> list element. Particularly handy for styling navigational links.

  • X#idname (CSS1)

    ID selector

    effect: Targets elements with the matching id attribute

    CSS

    ul#nav li {

    display:inline;

    }

    HTML

    <ul id="nav">

    <li><a href="#">item one</a></li>

    <li><a href="#">item two</a></li>

    <li><a href="#">item three</a></li>

    </ul>

    <ul>

    <li>item one</li>

    <li>item two</li>

    <li>item three</li>

    </ul>

    Result

    • item one
    • item two
    • item three

    Browser support: Full Support

    There is no denying the usefulness of this selector. One of the oldest and most widely supported selectors. It unfortunately requires you to apply extra markup within the HTML to function.

  • X.classname (CSS1)

    Class selector

    effect: Targets elements with the matching class attribute

    CSS

    a.external-link {

    font-size:1.5em;

    }

    HTML

    <a href="#">link to somewhere internal</a>

    <a class="external-link" href="#">link to somewhere else</a>

    Browser support: Full Support

    Like the id selector, when used appropriately this selector is very useful. The advantage it has over the id attribute is that it can be used multiple times within the page. It too is also widely supported and quickest for browsers to isolate.

  • X[attribute="value"] (CSS2)

    Attribute selector

    effect: Targets elements with the matching attribute value

    CSS

    input[type="text"] {

    background-color:#e7e9a0;

    }

    HTML

    <form>

    Text input: <input type="text"><br />

    Password input: <input type="password">

    </form>

    Result

    Text input:
    Password input:

    Browser support: IE7+

    When your structuring your HTML keep an eye open for any element that require an attribute to function. If it does you can quite easily target the attribute rather than adding the additional class or id. I use this selector quite a lot in correlation with the ARIA landmark roles. Eliminating the need for ids for header, nav, footer and aside sections as well as adding extra contextual information for screen readers.

  • X + Y (CSS2)

    Adjacent selector

    effect: Targets any Y element that immediately follows an X element

    CSS

    h5 + p {

    font-weight:bold;

    }

    HTML

    <h5>Heading</h5>

    <p>This paragraph is bold! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel ligula in ante elementum ultricies sed eleifend quam. Donec volutpat fringilla egestas. Donec porta est eu nulla ultrices viverra eu ac justo. Phasellus felis purus, venenatis nec lobortis id, auctor a nisl. Phasellus id molestie felis.</p>

    <p>This paragraph isn't. Donec malesuada lorem non sem porttitor mollis. Aliquam at lacus quis eros lacinia auctor ac ac erat. Duis eget augue at sapien mollis commodo a at ante. In non ligula at lectus ullamcorper rutrum nec vitae nisl. Aliquam rhoncus turpis commodo odio imperdiet dignissim.</p>

    Result

    Heading

    This paragraph is bold! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel ligula in ante elementum ultricies sed eleifend quam. Donec volutpat fringilla egestas. Donec porta est eu nulla ultrices viverra eu ac justo. Phasellus felis purus, venenatis nec lobortis id, auctor a nisl. Phasellus id molestie felis.

    This paragraph isn't. Donec malesuada lorem non sem porttitor mollis. Aliquam at lacus quis eros lacinia auctor ac ac erat. Duis eget augue at sapien mollis commodo a at ante. In non ligula at lectus ullamcorper rutrum nec vitae nisl. Aliquam rhoncus turpis commodo odio imperdiet dignissim.

    Browser support: IE7+

    The adjacent selector is very useful at pinpointing elements without the need of additional hooks in the HTML markup. With it's wide support it provides as a great alternative to some CSS3 selectors. An example of this is found next with the first-child pseudo-class.

  • X:first-child (CSS2)

    (first) Child pseudo-class

    effect: Targets the first child element within it's parent element

    CSS

    ul li:first-child {

    border:1px solid #f00;

    }

    HTML

    <ul>

    <li>item one</li>

    <li>item two</li>

    <li>item three</li>

    </ul>

    Result

    • item one
    • item two
    • item three

    Browser support: IE7+

    please note: although the first-child features in CSS2.1 and is supported in Internet Explorer 7+. last-child and nth-child are CSS3 features and are not supported in Internet Explorer until version 9+

    With that in mind you can be clever using your selectors if backwards compatibility to IE7/8 is required of your project. For the above example, say you wanted a unique style for each of the three items you could do this:

    CSS

    li { /* all li elements */

    border:1px solid #00f;

    }

    li:first-child { /* first child */

    border:1px solid #f00;

    }

    li:first-child + li { /* second child */

    border:1px solid #0f0;

    }

  • X:last-child (CSS3)

    (last) Child pseudo-class

    effect: Targets the last child element within it's parent element

    CSS

    ul li:last-child {

    border:1px solid #0f0;

    }

    HTML

    <ul>

    <li>item one</li>

    <li>item two</li>

    <li>item three</li>

    </ul>

    Result

    • item one
    • item two
    • item three

    Browser support: IE9+

    Eventually we will be able to use this pseudo-class without the fear of IE browser support issues. Very simple to use and goes hand-in-hand with first-child and nth-child. Happy styling!

  • X:nth-child(n) (CSS3)

    Child pseudo-class

    effect: Targets the a child element specified within the brackets

    CSS

    ul li:nth-child(2) {

    border:1px solid #00f;

    }

    HTML

    <ul>

    <li>item one</li>

    <li>item two</li>

    <li>item three</li>

    </ul>

    Result

    • item one
    • item two
    • item three

    Browser support: IE9+, Firefox 3.5+ and no support in Opera

    Very effective in filling in the gaps between the first-child and last-child pseudo-classes. Worth getting used to, you're going to use this one a lot later!

  • X:nth-of-type(n) (CSS3)

    nth sibling pseudo-class

    effect: Targets the element who's order of appearance within it's parent element matches the specified number within the brackets

    CSS

    h5:nth-of-type(2) {

    border-bottom:2px solid #1b9f6f;

    }

    HTML

    <h5>Heading one</h5>

    <p>This is a paragraph Aliquam rhoncus turpis commodo odio imperdiet dignissim</p>

    <h5>Heading two</h5>

    <p>This is another paragraph Phasellus felis purus, venenatis nec lobortis id, auctor a nis.</p>

    Result

    Heading one

    This is a paragraph Aliquam rhoncus turpis commodo odio imperdiet dignissim

    Heading two

    This is another paragraph Phasellus felis purus, venenatis nec lobortis id, auctor a nis.

    Browser support: IE9+, Firefox 3.5+ and no support in Opera

    The nth-of-type pseudo-class is very handy at picking out tag the repeats throughout it's parent element. If you have a collection of uniquely styled headers or two lists that serve different functions within your document, why not give this selector a try? You won't regret it!

  • Bonus selector!

    ::selection (CSS3)

    Selection pseudo-class

    effect: Allows you to adjust how highlighted text is displayed on your page

    CSS

    ::-moz-selection {

    background-color:#dd983c;

    }

    ::selection {

    background-color:#dd983c;

    }

    HTML

    <p>Go on, give highlighting this section a go! It's a small touch but can give your webpages that last little touch of class. This is not used anywhere near enough. color, background, cursor, and outline.</p>

    <p>Mauris a augue vitae justo euismod malesuada sed in ligula. Donec dui lectus, interdum ac imperdiet nec, sollicitudin eget tortor. Vivamus laoreet vulputate varius. Vivamus eget orci et nulla sagittis condimentum sit amet et nulla. Sed quis massa dolor. Donec nisl nulla, congue et vestibulum vel, tincidunt sit amet ipsum.</p>

    Result

    Go on, give highlighting this section a go! It's a small touch but can give your webpages that last little touch of class. This is not used anywhere near enough. color, background, cursor, and outline.

    Mauris a augue vitae justo euismod malesuada sed in ligula. Donec dui lectus, interdum ac imperdiet nec, sollicitudin eget tortor. Vivamus laoreet vulputate varius. Vivamus eget orci et nulla sagittis condimentum sit amet et nulla. Sed quis massa dolor. Donec nisl nulla, congue et vestibulum vel, tincidunt sit amet ipsum.

    Browser support: IE9+, Firefox with -moz- prefix.

Summary:

Our choice of CSS selectors is quite vast and flexible. Regardless of your HTML structure, CSS has many options giving you ultimate freedom to select the tags you want with ease. You must always beware of your target audience and consider the technology they'll be using to access your site. I hope that by demonstrating some of what CSS has to offer you will be able to tackle any backward compatible challenge is thrown your way.

This article was written by Web Design student Tony Ball. The information and explanations within reflect my current understanding of the industry. Should my information not be entirely accurate please do get in contact with me. Thank you for reading, I hope you found this article helpful.