Attribute selectors offer more options than selectors for HTML tags, IDs, and classes.
As with all selectors, you can combine them to create powerful and specific selectors.
Contents
- Review of Attributes Seen So Far
- Attribute
- Exact Value
- Exact Match a Single Value
- Partial Match at Start of Value #1
- Partial Match at Start of Value #2
- Partial Match at End of Value
- Partial Match Anywhere in Value
- Case Sensitivity
- Closing Thoughts
- References
Review of Attributes Seen So Far
Attributes are additional information included inside HTML tags. So far, we have seen 9 of them (each item links to their first use in this tutorial series):
Example use is shown below:
<div id="main">
<p class="important todo scale">
Some paragraph text.
</p>
</div>
<a href="http://example.com"
target="_blank"
download="file.txt">
This is a link.
</a>
<img src="/img/picture.jpg"
alt="Description of the image">
<ol reversed
start="101">
<li>Item 1</li>
<li>Item 2</li>
</ol>
Attribute
You can select elements by the attributes they contain by writing the attribute between square braces:
/*
select all HTML elements containing the
'reversed' attribute
*/
[reversed] {
/* specificity = 0:1:0 */
}
/*
select all HTML elements containing the
'id' attribute
*/
[id] {
/* specificity = 0:1:0 */
}
Exact Value
You can select by specifying the exact attribute and its value. The value must be in quotes:
[id="footer"] {
/* specificity = 0:1:0 */
}
[class="red box"]{
/* specificity = 0:1:0 */
}
[start="101"] {
/* specificity = 0:1:0 */
}
Exact Match a Single Value
If you have attributes with multiple values (classes are a good example), you can select based on one of the values by placing a tilde (~) before the equals sign:
The selector above will select the following HTML elements because they all contain box:
<p class="red box">This is a selected paragraph.</p>
<p class="box blue">This one too.</p>
<p class="red green box blue">This too!</p>
The attribute values must be separated by spaces:
<!--
Validly separated attribute values
-->
<p class="red box a b c"></p>
<!--
incorrectly separated attribute values
-->
<p class="red,box,a,b,c"></p>
<p class="a, b, c"></p>
You can only match one attribute value:
/*
THIS NEVER MATCHES ANYTHING
Even if you have an element like this:
<p class="a red box blue">
*/
[class~="red box"] {
}
Partial Match at Start of Value #1
You can match the beginning of a value string by using the vertical-bar before the equals sign (|=). The match must be followed by a hyphen:
The selector above will match the following:
The selector above will not match any of the following:
<!--
cf is not followed by a hyphen
-->
<div class="cf"></div>
<!--
cf is not at the start of the value string
-->
<div class="red cf- box"></div>
This is an extremely specific behaviour that was originally introduced for dealing with language codes.1
Partial Match at Start of Value #2
This is the more common way to match the start of an attribute value string.
You can match the beginning of a value string by using the caret before the equals sign (^=):
The selector above will match the following:
<div class="cfabc"></div>
<div class="cf"></div>
<div class="cf-"></div>
<div class="cf-d blue box"></div>
The selector above will not match any of the following:
It should be obvious that you can make the ^= equivalent to the |= by simply appending a hyphen to your string:
Partial Match at End of Value
You can match the end of a value string by using the dollar symbol before the equals sign ($=):
The selector above will match the following:
The selector above will not match any of the following:
<!--
nt is not at the end of the value string
-->
<div class="red nt box"></div>
<div class="plants"</div>
Partial Match Anywhere in Value
You can match the value anywhere in a string by using the asterisk symbol before the equals sign (*=):
The selector above will match the following:
The selector above will not match any of the following:
<!--
nt is not is not found in any value string
-->
<div class="red flat box"></div>
<div class="explains"</div>
Case Sensitivity
If you want to match values without regard to upper and lower case, you append i to the end of the attribute selector:
The selector above will match any of the following:2
<div class="red"></div>
<div class="RED"></div>
<div class="Red"></div>
<div class="rED"></div>
<div class="rEd"></div>
<div class="ReD"></div>
<div class="REd"></div>
<div class="reD"></div>
It is a good idea to be consistent in your use of case to avoid situations where you might need to use case insensitive matching.
Closing Thoughts
- Attribute selectors provide 7 different ways to match attributes and their values.
- [attribute] – select only by attribute name
- [attribute=“value”] – select by attribute name and exact value
- [attribute~=“value”] – select by attribute name and exact match one value in the value string
- [attribute|=“val”] – select by attribute name and exact match at the beginning of the value string which must then be followed by a hyphen
- [attribute^=“val”] – select by attribute name and exact match match at the beginning of the value string
- [attribute$=“lue”] – select by attribute name and exact match at the end of the value string
- [attribute*=“value”] – select by attribute name and exact match anywhere in the value string
- You can combine attribute selectors with other selectors and combinators:
/* only selects ordered lists that contain the attribute reversed and the attribute list */ ol[reversed][start] { /* specificity 0:2:1 */ } /* selects elements contained within objects having an ID of #main if those elements contain an attribute of target */ #main [target="_blank"] { /* specificity = 1:1:0 */ }
- You could colour code links to visually show if they refer this site or an external site:
- You could colour code links to visually show if a link uses a secure or unsecured connection:
- Given the following HTML code:
There is no functional difference between these pairs of selectors:
- Given the following HTML code:
These pairs of selectors behave differently:
/* selects only if the class is exactly "box" */ [class="box"] { } /* selects if the class contains "box" */ .box { } p[class="box"] { } p.box { }
You might be tempted to rewrite the attribute selector as:
But that selector will match not only box, but also: matchbox, bitbox, and any other class with box in it.
The correct substitution would be:
- Analyzing 4632 CSS rules3 from the home pages of 5 different websites4 revealed the following attribute selector distribution:5
- 2.5% of the rules use attribute selectors
- 85.2% of the attribute selectors use an exact match ([attribute=“value”])
- 11.3% of the attribute selectors match the attribute ([attribute])
- 3.5% of the attribute selectors do a partial on the start of the value ([attribute^=“val”])
- No other attribute selector types were used
- To see some real world selector examples using attribute selectors, consider the following from the WordPress 2016 Theme:6
/* Style a link (<a>) only if: (1) the value of href begins with "mailto:" (2) it is somewhere inside a block with a class of .social-navigation :before is a pseudo-element which will be covered in a later tutorial. Pseudo-elements add 0:1:0 to specificity specificity = 0:3:1 */ .social-navigation a[href^="mailto:"]:before { content: "\f410"; } /* Style a link (<a>) only if: (1) the value of href ends with "/feed/:" (2) it is somewhere inside a block with a class of .social-navigation :before is a pseudo-element which will be covered in a later tutorial. Pseudo-elements add 0:1:0 to specificity specificity = 0:3:1 */ .social-navigation a[href$="/feed/"]:before { content: "\f413"; } /* Style <img> tags only if: (1) they have a class name containing "wp-image-" (2) they are somewhere inside a block with a class of .wp-caption specificity = 0:2:1 */ .wp-caption img[class*="wp-image-"] { display: block; margin: 0; }
References
- This will be covered in a future tutorial. Essentially, language tags allow on to specify the primary language and a subset of that language. For example: en specifies the English language, en-ca specifies Canadian English, en-nz specifies New Zealand English, etc.↩
- This does not work with all browsers. It does not work with Internet Explorer, Microsoft Edge version 18 or lower, Android Browser (Android version 4.4 or earlier). A good site to check if a particular HTML or CSS feature is supported is Can I Use.↩
- Yes, it is a lot of rules.↩
- I pulled the CSS from the main landing pages of the following:
- BBC,
- Engadget,
- The Verge,
- Wikipedia,
- WordPress
- Take these numbers as a rough guide to their relative use.↩
- There is plenty in the CSS Styling that you haven’t seen – but they will be covered in future tutorials.↩