本文版权归作者所有,未经授权,请勿转载! 本文节选自“语雀”私有付费专栏「前端一万小时|从零基础到轻松就业」原创:itsOli@前端一万小时
2. 伪元素和伪类的区别? 3.关于CSS选择器,以下说法正确的是?(不定项) ❌header.p是选择id为header的类型为p的所有后代。 ✅header>.p是选择标签为header内的class为p的直接子元素。 ✅#header.p是选择id为header同时它的class为p的元素。 ✅#header,p是选择id为header的元素以及选择所有的p标签。1. 伪类选择器有哪些?
?上方面试题“参考答案详解”,请点击文末“
前言:本篇行文顺序为,在第一部分介绍“ HTML 文档树结构”,在完全理解这个“树结构”的基础上,才可以很好地掌握文章下边紧接着的两个大选择器(组合选择器和伪类选择器)。
因为只有有了这个“结构树”,我们本篇讨论的“选择器”才能够起作用。
又是很大、很杂、很基础、很重要的知识点,属必掌握项。
1 HTML 文档树结构
通过之前对 HTML 相关知识的学习,我们知道,一个 HTML 文档是以各个元素间的层次结构为基础建立起来的,每个合法的文档都会生成一个结构树(如下例)。
在这个层次结构中,每一个元素都有一个自己的位子,并且每个元素相对于这个结构里的其他元素,它们彼此或是“父子关系”、或是“祖孙—后代关系”、或是“直接相邻关系”、或是“普通相邻关系”等。
如下例的 HTML 文档及所对应的 “结构树”:
html><html><head><metacharset="utf-8"><title>前端一万小时title>head><body><h1>《<em>前端一万小时em>》之:xxxh1><p><em>本知识学习用时:2 小时……em>p><p><strong><em>前言:em>strong>Oli是怎样写文章的……p><h2>1认识……h2><p>首先把<em>“定义”em>讲解清楚p><h2>2为什么……h2><ul><li>是什么<ol><li>what<ul><li>wli><li>wli><li>hli>ul>li><li>whyli><li><em>howem>li>ol>li><li>为什么li><li>怎么样li>ul><h2>3怎么样……h2><ol><li>whatli><li>whyli><li><em>howem>li>ol>body>html>
文档结构为:
1.1 父子关系元素
如果一个元素出现在文档层次结构中另一个元素的上一层,则称前者是后者的“父元素”,后者是前者的“子元素”。
1.2 祖孙—后代关系元素
如果一个元素在另一个元素的直接上一层,它们是“父子关系”,而如果一个元素到另一个元素的路径要经过两层或多层,这些元素则是“祖孙—后代关系”。
1.3 根元素
body 元素是浏览器默认显示的所有元素的祖先, html 元素则是整个文档的祖先(因此,html 元素又称“根元素”)。
2 组合选择器
2.1 多元素选择器
用法:为多个元素应用同一个样式;
格式:如给上例中元素 h1 和 h2 加样式,使之背景颜色为 yellow。
?源码及效果展示/nufakuwuyi/edit?html,css,output
background:yellow; }h1,h2{
❗️注意多个选择器之间必须有,
这个字符。
2.2 后代选择器
用法:使一些样式、规则只在某一些指定的有“祖孙—后代关系”的后代元素上适用,其他非指定的结构中不适用;
格式:如上例中只给元素 ul 的后代元素 em 加样式,使其文字被中横线划去、背景色为 yellow。
?源码及效果展示/juzoliteco/edit?html,css,output
}ulem{text-decoration:line-through;background:yellow;
❗️注意选择器之间用“空格”这个“结合符”隔开。
2.3 子元素选择器
用法:使一些样式、规则只在某一些指定的有直接“父子关系”的子元素上适用,其他非指定的结构中不适用;
格式:如上例中只给元素 p 的子元素 em 加样式,使其文字被中横线划去、背景色为 yellow。
?源码及效果展示/lukuconite/edit?html,css,output
}p>em{text-decoration:line-through;background:yellow;
❗️注意选择器之间用>
这个“结合符”隔开。
2.4 直接相邻元素选择器
用法:前提,两个元素有共同的父元素,且后一个元素“紧接”在前一个元素后边时,你想对后一个元素添加样式;
格式:如上例中只给“紧接”第一个 h2 元素的 p 元素加样式,其他 p 不变,使其文字被中横线划去、背景色为 yellow。
?源码及效果展示/pikaqufocu/edit?html,css,output
}h2+p{text-decoration:line-through;background:yellow;
❗️注意选择器用+
这个“结合符”隔开。
2.5 普通相邻元素选择器
用法:相对于“直接相邻元素选择器”而言,两个元素也必须有共同的父元素,但后一个元素不需要“紧接”在前一个元素后边,你也可以对后一个元素添加样式;
格式:如给上例中第一个 h2 元素后边的 h2 元素加样式,使其文字被中横线划去、背景色为 yellow。
?源码及效果展示/wobedivobo/edit?html,css,output
}h2~h2{text-decoration:line-through;background:yellow;
❗️注意选择器用~
这个“结合符”隔开。
3 伪类
3.1 为什么需要“伪类”?
首先再次复习:《② HTML 元素、属性详解》中关于“超链接 a 元素”的相关知识点。
“链接”在实际页面中出现的频率很高,人们想对“未访问的页面”和“已访问的页面”作样式上的区分,直观的方式就是在 HTML 文档里边对 a 元素作 class 属性添加,让这个 a 元素加入一个类:
<ahref="http://…"class="visited">这里是链接a>
然后通过“类选择器”对其加样式:
color=red; }a.visited{
但,显而易见,这种方式根本就不合乎实际操作,因为不可能每访问一个新页面就去修改一下链接的“类”。
于是,CSS 定义了两个只用于“超链接”的“静态伪类”,这些“伪类”不用在 HTML 文档中输入,可以直接对其添加样式。分别为:
指示这个“超链接”(即 a 元素里有一个 href 属性)未被访问;
:link
❗️注意书写格式上的“冒号”,这个冒号:
是“伪类”和“伪元素”的名片。且冒号与状态link
之间不能有空格!
指示这个“超链接”已被访问。
:visited
3.2 为什么需要“动态伪类”?
在上文中我们了解到 CSS 为适应需要,最先定义了两个“静态伪类”,但:link
和:visited
对文档样式的改变很有限,一般第一次显示过后就不会再起作用了。
而人们的需要则更多:链接“焦点 focus”时、在链接上“悬停 hover”时、“活动 active”状态时,都需要样式的区分。
于是,CSS 又定义了 3 个“动态伪类”,它们可以根据用户行为相应改变文档的外观。这些“伪类”,或者说所有“伪类”,都不用在 HTML 文档中输入,可以直接对其添加样式。分别为:指示这个元素拥有输入“焦点”——即可以接受键盘输入,或通过某种方式可以激活;
:focus
指示当鼠标停留在这个元素上时,外观可以作相应改变;
:hover
指示这个元素可以被用户输入“激活”。如,用户停留在一个超链接上,当点击鼠标时,这个链接就会“激活”。
:active
❗️注意:
CSS “伪类”不仅可以改变不同状态时的颜色,还可以应用任何需要的样式;
“动态伪类”与“静态伪类”不同,“动态伪类”可以应用于任何元素,不局限于“超链接”;
考虑到“继承、层叠”的原因(下一篇会详谈),“伪类”的顺序很重要,通常为:
:visited :focus :hover :active:link
4 伪类选择器
4.1 “静态、动态伪类选择器”合用实例
首先再次复习:《③ HTML 表单详解》,掌握表单元素。然后动手操作以下例子:
?源码和效果展示/xapiracefi/edit?html,css,output——请打开此链接,去操作一下,看看效果!HTML
<html> <head> <metacharset="utf-8"> <title>前端一万小时title> head> <body> <ahref="/Oli-Zhao"title="Oli的前端一万小时">我的博客地址a> <divclass="login"> <formaction="/getinfo"method="get"> <divclass="username"> <labelfor="username">姓名label> <inputid="username"type="text"name="username"value="Oli"> div> <divclass="password"> <labelfor="password">密码label> <inputid="password"type="password"name="password"placeholder="输入密码"> div> <divclass="sex"> <label>性别label> <inputtype="radio"name="sex"value="男"checked>男 <inputtype="radio"name="sex"value="女">女 div> form> div> body> html>html>
CSS
}a:visited{color:red; }input:focus{background:yellow;font-weight:bold; }a:hover{font-size:30px; }a:active{color:silver; }a:link{color:blue;
❗️注意:下一篇文章会详细阐述“链接”在随用户操作状态变化时,其样式是按怎样的顺序显示的。
4.2 用户界面元素伪类选择器(UI 元素伪类选择器)
在“表单”元素中,radio 和 checkbox 都具有“选中”和“未选中”状态,以下选择器可以定义这两种状态的样式。:checked
当我们用鼠标左键按住进行网页取词时,浏览器在默认情况下是“蓝底黑字”,如果我想要改变这个样式,我可以用以下选择器。
::selection
默认情况下,Web 表单元素皆“可用”,但其元素(文字输入框、密码框、单选框、复选框等)也可以有“不可用”的状态。那么下边的选择器可以分别对表单元素的这两种状态设置样式。
:enabled:disabled
默认情况下,Web 表单元素皆“可读写”,但其元素(输入框、文本域等)也可以有“只读”的状态。那么下边的选择器可以分别对表单元素的这两种状态设置样式。
:read-only:read-write
❗️注意选择器的格式!
代码实例:
?源码及效果展示/tetazoduxa/edit?html,css,output——请打开此链接,去操作一下,看看效果!HTML
<html> <head> <metacharset="utf-8"> <title>前端一万小时title> head> <body> <ahref="/Oli-Zhao"title="Oli的前端一万小时">我的博客地址a> <divclass="login"> <formaction="/getinfo"method="get"> <divclass="username"> <labelfor="username">姓名label> <inputid="username"type="text"name="username"value="Oli"> div> <divclass="password"> <labelfor="password">密码label> <inputid="password"type="password"name="password"placeholder="输入密码"> div> <divclass="sex"> <label>性别label> <inputtype="radio"name="sex"value="男"checked>男 <inputtype="radio"name="sex"value="女">女 div> <div> <labelfor="enabled">可用:label> <inputtype="text"name="enabled"> div> <div> <labelfor="disabled">不可用:label> <inputtype="text"name="disabled"disabled="disabled"> div> <div> <labelfor="enabled">读写:label> <inputtype="text"name="status"> div> <div> <labelfor="disabled">只读:label> <inputtype="text"name="status"readonly="readonly"> div> form> div> <p>Oli 努力做个“伟大的程序员”,他是个好人!p> body> html>html>
CSS
}a:visited{color:red; }input:focus{background:yellow;font-weight:bold; }a:hover{font-size:30px; }a:active{color:silver; }:checked{font-size:50px; }p::selection{background-color:orange;color:white; }input:enabled{outline:1pxdottedblack; }input:disabled{background-color:green; }input:read-write{outline:1pxdottedblack; }input:read-only{background-color:gray; }a:link{color:blue;
4.3 结构伪类选择器
❗️此大类选择器需要用实例讲解,篇幅较长,将后续另起一篇文章讲解。此篇仅作相关知识点列举。
(下文中 E 指 element 元素!)
4.3.1 第一类
E:first-child 2. 选择父元素的最后一个子元素。 E:last-child 3.选择父元素下第n个元素或奇偶元素,n的值为:数字/odd/even。 E:nth-child(n) 4. 选择父元素中唯一的子元素————该父元素只有一个子元素。 E:only-child1. 选择父元素的第一个子元素。
4.3.2 第二类
E:first-of-type 2. 选择同类型的最后一个同级兄弟元素。 E:last-of-type 3.选择同类型的第n个同级兄弟元素,n的值为:数字/odd/even。 E:nth-of-type(n) 4. 选择父元素中特定类型的唯一子元素————该父元素有多个子元素。 E:only-of-type1. 选择同类型的第一个同级兄弟元素。
4.3.3 第三类
:root 2. 选择某个元素之外的所有元素。 E:not(selector) 3. 选择一个不包含任何子元素的元素,需要注意的是,“文本节点”也可以被看成子元素。 E:empty 4.选取页面中的某个target元素。 E:target1.文档的“根元素”——html元素。
后记:终于完成了这篇,知识点很多,如果只是单纯看一遍收获会很小。代码的学习,需要我们动起手来,不停敲、不停试。跟机器打交道的好处就是,它一般来说不会骗你,对就是对,错就是错。
总之,感谢这个时代!
祝好,qdywxs ♥ you!
点击“