属性选择器是一种特殊类型的选择器,它根据元素的 属性和属性值来匹配元素。它们的通用语法由方括号([]
) 组成,其中包含属性名称,后跟可选条件以匹配属性的值。 属性选择器可以根据其匹配属性值的方式分为两类: 存在和值属性选择器和子串值属性选择器。
存在和值(Presence and value)属性选择器
这些属性选择器尝试匹配精确的属性值:
[attr]
:该选择器选择包含 attr 属性的所有元素,不论 attr 的值为何。[attr=val]
:该选择器仅选择 attr 属性被赋值为 val 的所有元素。[attr~=val]
:该选择器仅选择 attr 属性的值(以空格间隔出多个值)中有包含 val 值的所有元素,比如位于被空格分隔的多个类(class)中的一个类。
让我们看一个以下面的HTML代码片段为例:
我的食谱配料: <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>
和一个简单的样式表:
/* 具有"data-vegetable"属性的所有元素, 将被给予绿色的文本颜色 */ [data-vegetable] { color: green } /* 具有"data-vegetable"属性且属性值刚好是"liquid"的所有元素, 将被给予金色背景颜色 */ [data-vegetable="liquid"] { background-color: goldenrod; } /* 具有"data-vegetable"属性且属性值包含"spicy"的所有元素, 即使某元素的该属性还包含其他属性值, 都会被给予红色的文本颜色 */ [data-vegetable~="spicy"] { color: red; }
结果如下:
子串值(Substring value)属性选择器
这种情况的属性选择器也被称为“伪正则选择器”,因为它们提供类似 regular expression 的灵活匹配方式(但请注意,这些选择器并不是真正的正则表达式):
[attr|=val]
: 选择attr属性的值以val(包括val)或val-开头的元素(-用来处理语言编码)。[attr^=val]
: 选择attr属性的值以val开头(包括val)的元素。[attr$=val]
: 选择attr属性的值以val结尾(包括val)的元素。[attr*=val]
: 选择attr属性的值中包含字符串val的元素。
让我们继续我们前面的例子,并添加以下CSS规则:
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>
/* 语言选择的经典用法 */ [lang|=fr] { font-weight: bold; } /* 具有"data-vegetable"属性含有值"not spicy"的所有元素,都变回绿色 */ [data-vegetable*="not spicy"] { color: green; } /* 具有"data-quantity"属性其值以"kg"结尾的所有元素*/ [data-quantity$="kg"] { font-weight: bold; } /* 具有属性"data-quantity"其值以"optional"开头的所有元素 */ [data-quantity^="optional"] { opacity: 0.5; }
/* 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; }
With those new rules, we will get this:
主动学习:给足球比赛结果添加样式
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("http://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/en-GB.png") 5px center no-repeat; } li[] { background: url("http://mdn.github.io/learning-area/css/introduction-to-css/css-selectors/de.png") 5px center no-repeat; } li[] { background: url("http://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("http://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("http://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("http://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);
接下来是
Next we will move things up a gear, looking at Pseudo-classes and pseudo-elements.