Our volunteers haven't translated this article into Tiếng Việt yet. Join us and help get the job done!
Attribute selectors are a special kind of selector that will match elements based on their attributes and attribute values. Their generic syntax consists of square brackets ([]
) containing an attribute name followed by an optional condition to match against the value of the attribute. Attribute selectors can be divided into two categories depending on the way they match attribute values: Presence and value attribute selectors and Substring value attribute selectors.
Presence and value attribute selectors
These attribute selectors try to match an exact attribute value:
[attr]
: This selector will select all elements with the attributeattr
, whatever its value.[attr=val]
: This selector will select all elements with the attributeattr
, but only if its value isval
.[attr~=val]
: This selector will select all elements with the attributeattr
, but only if the valueval
is one of a space-separated list of values contained inattr
's value, for example a single class in a space-separated list of classes.
Let's look at an example featuring the following HTML snippet:
Ingredients for my recipe: <i lang="fr-FR">Poulet basquaise</i> <ul> <li data-quantity="1kg" data-vegetable>Tomatoes</li> <li data-quantity="3" data-vegetable>Onions</li> <li data-quantity="3" data-vegetable>Garlic</li> <li data-quantity="700g" data-vegetable="not spicy like chili">Red pepper</li> <li data-quantity="2kg" data-meat>Chicken</li> <li data-quantity="optional 150g" data-meat>Bacon bits</li> <li data-quantity="optional 10ml" data-vegetable="liquid">Olive oil</li> <li data-quantity="25cl" data-vegetable="liquid">White wine</li> </ul>
And a simple style sheet:
/* All elements with the attribute "data-vegetable" are given green text */ [data-vegetable] { color: green } /* All elements with the attribute "data-vegetable" with the exact value "liquid" are given a golden background color */ [data-vegetable="liquid"] { background-color: goldenrod; } /* All elements with the attribute "data-vegetable", containing the value "spicy", even among others, are given a red background color */ [data-vegetable~="spicy"] { color: red; }
The result is as follows:
Substring value attribute selectors
Attribute selectors in this class are also known as "RegExp-like selectors", because they offer flexible matching in a similar fashion to regular expression (but to be clear, these selectors are not true regular expression):
[attr|=val]
: This selector will select all elements with the attributeattr
for which the value is exactlyval
or starts withval-
(careful, the dash here isn't a mistake, this is to handle language codes.)[attr^=val]
: This selector will select all elements with the attributeattr
for which the value starts withval
.[attr$=val]
: This selector will select all elements with the attributeattr
for which the value ends withval
.[attr*=val]
: This selector will select all elements with the attributeattr
for which the value contains the stringval
(unlike[attr~=val]
, this selector doesn't treat spaces as value separators but as part of the attribute value.)
Let's continue our previous example and add the following CSS rules:
Ingredients for my recipe: <i lang="fr-FR">Poulet basquaise</i> <ul> <li data-quantity="1kg" data-vegetable>Tomatoes</li> <li data-quantity="3" data-vegetable>Onions</li> <li data-quantity="3" data-vegetable>Garlic</li> <li data-quantity="700g" data-vegetable="not spicy like chili">Red pepper</li> <li data-quantity="2kg" data-meat>Chicken</li> <li data-quantity="optional 150g" data-meat>Bacon bits</li> <li data-quantity="optional 10ml" data-vegetable="liquid">Olive oil</li> <li data-quantity="25cl" data-vegetable="liquid">White wine</li> </ul>
/* Classic usage for language selection */ [lang|=fr] { font-weight: bold; } /* All elements with the attribute "data-vegetable" containing the value "not spicy" are turned back to green */ [data-vegetable*="not spicy"] { color: green; } /* All elements with the attribute "data-quantity", for which the value ends with "kg" */ [data-quantity$="kg"] { font-weight: bold; } /* All elements with the attribute "data-quantity", for which the value starts with "optional" */ [data-quantity^="optional"] { opacity: 0.5; }
With those new rules, we will get this:
Active learning: Styling football results
In this active learning, we'd like you to try your hand at adding attribute selectors to some rules to style a simple football results listing. There are three things to try to do here:
- The first three rules add a UK, German, and Spanish flag icon respectively to the left hand side of the list items. You need to fill in appropriate attribute selectors so that the teams are given their correct country flags, matched by language.
- Rules 4–6 add a background color to the list items to indicate whether the team has gone up in the league (green,
rgba(0,255,0,0.7)
), down (red,rgba(255,0,0,0.5)
), or stayed in the same place (blue,rgba(0,0,255,0.5)
.) Fill in the appropriate attribute selectors to match the correct colors to the correct teams, matched by theinc
,same
anddec
strings that appear in thedata-perf
attribute values. - Rules 7–8 make teams that are set to be promoted bold, and teams that are in danger of being relegated italic and gray. Fill in appropriate attribute selectors to match these styles to the correct teams, matched by the
pro
andrel
strings that appear in thedata-perf
attribute values.
If you make a mistake, you can always reset it using the Reset button. If you get really stuck, press the Show solution button to see a potential answer.
Playable code 4
<div class="body-wrapper" style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;"> <h2>HTML Input</h2> <textarea id="code" class="html-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"><ol> <li lang="en-GB" data-perf="inc-pro">Manchester United</li> <li lang="es" data-perf="same-pro">Barcelona</li> <li lang="de" data-perf="dec">Bayern Munich</li> <li lang="es" data-perf="same">Real Madrid</li> <li lang="de" data-perf="inc-rel">Borussia Dortmund</li> <li lang="en-GB" data-perf="dec-rel">Southampton FC</li> </ol></textarea> <h2>CSS Input</h2> <textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">li[] { background: url("https://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/en-GB.png") 5px center no-repeat; } li[] { background: url("https://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/de.png") 5px center no-repeat; } li[] { background: url("https://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/es.png") 5px center no-repeat; } li[] { background-color: rgba(0,255,0,0.7); } li[] { background-color: rgba(0,0,255,0.5); } li[] { background-color: rgba(255,0,0,0.7); } li[] { font-weight: bold; } li[] { font-style: italic; color: #666; } ol { padding: 0; } li { padding: 3px 3px 3px 34px; margin-bottom: 5px; list-style-position: inside; }</textarea> <h2>Output</h2> <div class="output" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;overflow:auto;"></div> <div class="controls"> <input id="reset" type="button" value="Reset" style="margin: 10px 10px 0 0;"> <input id="solution" type="button" value="Show solution" style="margin: 10px 0 0 10px;"> </div> </div>
var htmlInput = document.querySelector(".html-input"); var cssInput = document.querySelector(".css-input"); var reset = document.getElementById("reset"); var htmlCode = htmlInput.value; var cssCode = cssInput.value; var output = document.querySelector(".output"); var solution = document.getElementById("solution"); var styleElem = document.createElement('style'); var headElem = document.querySelector('head'); headElem.appendChild(styleElem); function drawOutput() { output.innerHTML = htmlInput.value; styleElem.textContent = cssInput.value; } reset.addEventListener("click", function() { htmlInput.value = htmlCode; cssInput.value = cssCode; drawOutput(); }); solution.addEventListener("click", function() { htmlInput.value = htmlCode; cssInput.value = 'li[lang="en-GB"] {\n background: url("https://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/en-GB.png") 5px center no-repeat;\n}\n\nli[lang="de"] {\n background: url("https://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/de.png") 5px center no-repeat;\n}\n\nli[lang="es"] {\n background: url("https://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/es.png") 5px center no-repeat;\n}\n\nli[data-perf*="inc"] {\n background-color: rgba(0,255,0,0.7);\n}\n\nli[data-perf*="same"] {\n background-color: rgba(0,0,255,0.5);\n}\n\nli[data-perf*="dec"] {\n background-color: rgba(255,0,0,0.7);\n}\n\nli[data-perf*="pro"] {\n font-weight: bold;\n}\n\nli[data-perf*="rel"] {\n font-style: italic;\n color: #666;\n}\n\nol {\n padding: 0;\n}\n\nli {\n padding: 3px 3px 3px 34px;\n margin-bottom: 5px;\n list-style-position: inside;\n}'; drawOutput(); }); htmlInput.addEventListener("input", drawOutput); cssInput.addEventListener("input", drawOutput); window.addEventListener("load", drawOutput);
Coming up next
Next we will move things up a gear, looking at Pseudo-classes and pseudo-elements.