在这里,在我们的系列文章中的第三个选择器,我们讨论伪选择器 —— 这些不选择实际元素,而是元素的某些部分,或仅在某些上下文中的元素。它们有两种主要类型 - 伪类和伪元素。
伪类(Pseudo-class)
一个 CSS 伪类(pseudo-class) 是一个以冒号(:
)作为前缀的关键字,当你希望样式在特定状态下才被呈现到指定的元素时,你可以往元素的选择器后面加上对应的伪类(pseudo-class)。你可能希望某个元素在处于某种状态下呈现另一种样式,例如当鼠标悬停在元素上面时,或者当一个 checkbox 被禁用或被勾选时,又或者当一个元素是它在 DOM 树中父元素的第一个孩子元素时。
:active
:any
:checked
:default
:dir()
:disabled
:empty
:enabled
:first
:first-child
:first-of-type
:fullscreen
:focus
:hover
:indeterminate
:in-range
:invalid
:lang()
:last-child
:last-of-type
:left
:link
:not()
:nth-child()
:nth-last-child()
:nth-last-of-type()
:nth-of-type()
:only-child
:only-of-type
:optional
:out-of-range
:read-only
:read-write
:required
:right
:root
:scope
:target
:valid
:visited
我们不希望深入讲解每一个伪类(pseudo-class) —— 这并不在我们详细讲解的范围内,当然你可以在其它地方对它们进行深入了解。
一个伪类(Pseudo-class)的例子
现在,让我们来看一个简单的使用例子。首先是一个 HTML 片段:
<a href="https://developer.mozilla.org/" target="_blank">Mozilla Developer Network</a>
然后,一些 CSS 样式:
/* These styles will style our link in all states */ a { color: blue; font-weight: bold; } /* We want visited links to be the same color as non visited links */ a:visited { color: blue; } /* We highlight the link when it is hovered (mouse), activated or focused (keyboard) */ a:hover, a:active, a:focus { color: darkred; text-decoration: none; }
现在,我们可以跟修改了样式的链接愉快地玩耍了!
主动学习:一个条纹状的信息列表
又轮到你了——在这节主动学习中我们希望你为信息列表增加条纹状效果,然后添加一个伪类使得里面的链接在鼠标经过时显得不同。在这个练习中你只需要修改最后的三条规则。一些提示:
- 你应该已经知道怎样使用伪类实现悬停样式。
- 对于条纹状效果,你需要用到一个伪类,如
:nth-of-type()
,通过给那两个颜色规则添加稍微不同的伪类,使得列表的奇数行和偶数行有着不同的样式效果。来看看你有没有找到实现的方法!
如果你写错了,你可以使用 Reset 按钮进行重置。如果你实在不知道怎么实现,按 Show 按钮可以看到答案。
Playable code 5
<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;"><ul> <li><a href="#">United Kingdom</a></li> <li><a href="#">Germany</a></li> <li><a href="#">Finland</a></li> <li><a href="#">Russia</a></li> <li><a href="#">Spain</a></li> <li><a href="#">Poland</a></li> </ul></textarea> <h2>CSS Input</h2> <textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">ul { padding: 0; } li { padding: 3px; margin-bottom: 5px; list-style-type: none; } a { text-decoration: none; color: black; } { text-decoration: underline; color: red; } { background-color: #ccc; } { background-color: #eee; }</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 = 'ul {\n padding: 0;\n}\n\nli {\n padding: 3px;\n margin-bottom: 5px;\n list-style-type: none;\n}\n\na {\n text-decoration: none;\n color: black;\n}\n\na:hover {\n text-decoration: underline;\n color: red;\n}\n\nli:nth-of-type(2n) {\n background-color: #ccc;\n}\n\nli:nth-of-type(2n+1) {\n background-color: #eee;\n}'; drawOutput(); }); htmlInput.addEventListener("input", drawOutput); cssInput.addEventListener("input", drawOutput); window.addEventListener("load", drawOutput);
伪元素
伪元素(Pseudo-element)跟伪类很像,但它们又有不同的地方。它们都是关键字 —— 但这次伪元素前缀是两个冒号 (::
) —— 同样是添加到选择器后面达到指定某个元素的某个部分。
它们都拥有特别的行为和有趣的特性,但我们不会在这里对它们都进行深入探究。
一个伪元素(pseudo-element)例子
我们在这里仅展示一个简单的 CSS 例子,就是如何在所有超链接元素后面的增加一个箭头:
<ul> <li><a href="https://developer.mozilla.org/en-US/docs/Glossary/CSS">CSS</a> defined in the MDN glossary.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Glossary/HTML">HTML</a> defined in the MDN glossary.</li> </ul>
让我们加上 CSS 规则:
/* All elements with an attribute "href", which values start with "http", will be added an arrow after its content (to indicate it's an external link) */ [href^=http]::after { content: '⤴'; }
我们可以得到这样的效果:
主动学习:一个很棒棒的段落
下面是主动学习部分,我们有一个很棒棒的段落需要装饰!你需要做的事是给出两个规则集分别指定段落的第一行和第一个单词,可以使用伪元素 ::first-line
和 ::first-letter
得到需要的。元素需要的效果,是段落的第一行使用粗体字,它的第一个单词首字母大写并给它一种老式的感觉。
如果你写错了,你可以使用 Reset 按钮进行重置。如果你实在不知道怎么实现,按 Show 按钮可以看到答案。
Playable code 6
<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;"><p>This is my very important paragraph. I am a distinguished gentleman of such renown that my paragraph needs to be styled in a manner befitting my majesty. Bow before my splendour, dear students, and go forth and learn CSS!</p></textarea> <h2>CSS Input</h2> <textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"> { font-weight: bold; } { font-size: 3em; border: 1px solid black; background: red; display: block; float: left; padding: 2px; margin-right: 4px; }</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 = 'p::first-line {\n font-weight: bold;\n}\n\np::first-letter {\n font-size: 3em;\n border: 1px solid black;\n background: red;\n display: block;\n float: left;\n padding: 2px;\n margin-right: 4px;\n}'; drawOutput(); }); htmlInput.addEventListener("input", drawOutput); cssInput.addEventListener("input", drawOutput); window.addEventListener("load", drawOutput);
下一步
我们将会从选择符和多重选择器(Combinators and multiple selectors)结束我们对 CSS 选择器的学习。