Combining,Grouping & Attribute Selectors

Grouping CSS selectors boosts efficiency, productivity, organization, and in some cases, even load speed

I will take a closer look at the more advanced selectors, not all of which are yet fully supported in all major browsers. Support is getting better though, so learning about the selectors that are described is always time well spent.

When you group CSS selectors, you apply the same styles to several different elements without repeating the styles in your stylesheet. Instead of having two, three, or more CSS rules that do the same thing (set the colour of something to red, for example), you use a single CSS rule that accomplishes the same thing. The secret to this efficiency-boosting tactic is the comma.

Combinators - Grouping Selectors

Combinators are used to separate the two or more simple selectors that make up a combined selector. The available combinators are whitespace (any number of tab, space or other whitespace characters), >, and +. What each combinator does is described in the next few sections.

Descendant selectors

A descendant selector is made up of two or more simple selectors separated by whitespace. It matches elements that are descendants of an element that matches the first simple selector. For example, the selector in this rule would match all p elements that are descendants of a div element:

Each of the selectors that form a descendant selector can be a simple selector of any form. The selector in the following rule matches all p elements with a class name of info that are contained by an li element that is contained by a div element with the id myid.

div#myid li p.info { color:#f00; }

Descendant selectors allow you to target elements without giving them a class name or an id, which in turn helps keep your markup clean. Let’s assume you have a navigation list consisting of the following markup:

<ul id="nav">
	<li><a href="#">Link 1</a></li>
	<li><a href="#">Link 2</a></li>
	<li><a href="#">Link 3</a></li>
</ul>

To target only those list items and links that are contained within the navigation list you could use the following CSS:

#nav li { display:inline; }
#nav a { font-weight:bold; }

These rules will not match any other list items or links in the document. Compare that to giving a class name to each list item and link, and you’ll realise how much cleaner your markup can become when you use descendant selectors.

To group CSS selectors in a style sheet, use commas to separate multiple grouped selectors in the style. In this example, the style affects the p and div elements:

div, p { color: #FF0000; }

In this context, a comma means "and," so this selector applies to all paragraph elements and all division elements. If the comma were missing, the selector would instead apply to all paragraph elements that are a child of a division. That is a different kind of selector, so the comma is important.

You can group any form of selector with any other selector. This example groups a class selector with an ID selector:

p.red, #sub { color: #FF00003; }

This style applies to any paragraph with the class attribute of red and any element (because the kind is not specified) with an ID attribute of sub.

You can group any number of selectors, including selectors that are single words and compound selectors. This example includes four different selectors:

p, .red, #sub, div a:link { color: #FF0000; }

This CSS rule would apply to:

  • Any paragraph element

  • Any element with the class of red

  • Any element with an ID of sub

  • The link pseudo class of the anchor elements that are descendants of a division.

That last selector is a compound selector. As shown, it's easily combined with the other selectors in this CSS rule. The rule sets the color of #FF0000 (red) on these four selectors, which is preferable to writing four separate selectors to achieve the same result.

Any Selector Can Be Grouped

You can place any valid selector in a group, and all elements in the document that match all the grouped elements will have the same style based on that style property.

Some designers prefer to list the grouped elements on separate lines for legibility in the code. The appearance on the website and the load speed remains the same. For example, you can combine styles separated by commas into one style property in one line of code:

th, td, p.red, div#firstred { color: red; }

or you can list the styles on individual lines for clarity:

th,
td,
p.red,
div#firstred
{
color: red;
}

Child selectors

This rule will affect all strong elements that are children of a div element:

div > strong { color:#f00; }

Only strong elements that are direct descendants of div elements will be targeted by this rule. If there is any other element between the div and the strong elements in the document tree, the selector will not match. In the following example, only “Text one” will be affected by the above rule:

<div>
	<strong>Text one</strong>
	<p><strong>Text two</strong></p>
</div>

Adjacent sibling selectors

An adjacent sibling selector is made up of two simple selectors separated by a plus sign, “+”. Whitespace is allowed around the adjacent sibling combinator. The selector matches an element which is the next sibling to the first element. The elements must have the same parent and the first element must immediately precede the second element:

p + p { color:#f00; }

If applied to the following example, the above rule will only affect “Paragraph two”:

<div>
	<p>Paragraph one</p>
	<p>Paragraph two</p>
</div>

Grouping

I decided to mention grouping at this point, because one common mistake I see people making when they are learning CSS is related to grouping combined selectors.

To apply the same rules to elements matched by several different selectors you can group them into a comma-separated list instead of repeating the declarations for each selector. The mistake many make is to not list the full selectors. Assume that you have the following markup:

<div id="news">
	<h3>News</h3>
	<ul>
		<li>Item 1</li>
		<li>Item 2</li>
	</ul>
</div>

Now, say you want to apply the same amount of margin to level 3 headings and unordered lists, but only if they are in the div element whose id is “news”. Here is the wrong way:

div#news h3, ul {
	margin:0 2em;
	}

This will affect both h3 and ul elements in div#news. The problem is that it will target all ul elements in the document, not only those in div#news.

Here is the correct way of grouping the selectors in this case:

div#news h3,
div#news ul {
	margin:0 2em;
	}

So, when grouping selectors, remember to fully specify each selector.

Attribute selectors

Attribute selectors match elements based on the presence or value of attributes. There are four ways for an attribute selector to match:[att]Matches elements that have an att attribute, regardless of its value.[att=val]Matches elements that have an att attribute with a value of exactly “val”.[att~=val]Matches elements whose att attribute value is a space-separated list that contains “val”. In this case “val” cannot contain spaces.[att|=val]Matches elements whose att attribute value is a hyphen-separated list that begins with “val”. The main use for this is to match language sub-codes specified by the lang attribute (xml:lang in XHTML), e.g. “en”, “en-us”, “en-gb”, etc.

Some examples then. The selector in the following rule matches all p elements that have a title attribute, regardless of which value it has:

p[title] { color:#f00; }

In the following example, the selector matches all div elements that have a class attribute with the value error:

div[class=error] { color:#f00; }

In order to match all td elements whose headers attribute value contains “col1”, the following selector can be used:

td[headers~=col1] { color:#f00; }

And finally, the selector in the following example matches all p elements whose lang attribute starts with en:

p[lang|=en] { color:#f00; }

Multiple attribute selectors can be used in the same selector. This makes it possible to match against several different attributes for the same element. The following rule would apply to all blockquote elements that have a class attribute whose value is exactly “quote”, and a cite attribute (regardless of its value):

blockquote[class=quote][cite] { color:#f00; }

Why Group CSS Selectors?

Grouping CSS selectors helps minimize the size of your stylesheet so it loads faster . Style sheets are not the main culprits in slow loading; CSS files are text files, so even very long CSS sheets are tiny when compared to unoptimized images. Still, every bit of optimization helps, and if you can shave some size off your CSS and load the pages that much faster, that's a good thing.

Last updated