CSS 的选择器:简单选择器/上下文选择器/伪类选择器
1. 简单选择器
1.1 标签选择器
根据元素标签名称进行匹配
标签选择器 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>标签选择器demo</title>
<style>
p {
color: lightpink;
font-size: 24px;
}
</style>
</head>
<body>
<p>今天学习CSS选择器</p>
</body>
</html>
demo 运行效果图:
1.2 组群选择器
同时选择多个不同类型的元素
组群选择器 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>标签选择器demo</title>
<style>
h1,
h2,
h3 {
color: lightsalmon;
}
</style>
</head>
<body>
<h1>我是一级标题</h1>
<h2>我是二级标题</h2>
<h3>我是三级标题</h3>
</body>
</html>
demo 运行效果图:
1.3 通配选择器
选择全部元素,不区分类型
通配选择器 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>标签选择器demo</title>
<style>
body {
padding: 10px;
}
.container {
padding: 10px;
}
/* 通配选择器 */
* {
outline: 1px solid red;
}
</style>
</head>
<body>
<div class="container">
<div class="item">第1个项目</div>
<div class="item">第2个项目</div>
<div class="item">第3个项目</div>
<div class="item">第4个项目</div>
<div class="item">第5个项目</div>
</div>
</body>
</html>
demo 运行效果图:
1.4 属性选择器/类选择器/id 选择器
- 属性选择器: 根据元素属性进行匹配
- 类选择器: 根据元素的 class 属性进行匹配
- id 选择器: 根据元素的 id 属性进行匹配
三种属性选择器 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>标签选择器demo</title>
<style>
/* 属性选择器 */
input[name="username"] {
background-color: lime;
}
/* id选择器 */
*#email {
background-color: yellow;
}
/* 类选择器 */
*.realname {
background-color: tomato;
}
</style>
</head>
<body>
<section>
<label for="">账号:</label>
<input type="text" name="username" />
</section>
<section>
<label for="">邮箱:</label>
<input type="text" id="email" />
</section>
<section>
<label for="">姓名:</label>
<input type="text" class="realname" />
</section>
</body>
</html>
demo 运行效果图:
" class="reference-link">
2. 上下文选择器
2.1 四种上下文选择器
序号 | 选择器 | 操作符 | 描述 | 举例 |
---|---|---|---|---|
1 | 后代选择器 | 空格 |
选择当前元素的所有后代元素 | div p , body * |
2 | 父子选择器 | > |
选择当前元素的所有子元素 | div > h2 |
3 | 同级相邻选择器 | + |
选择拥有共同父级且相邻的元素 | li.red + li |
4 | 同级所有选择器 | ~ |
选择拥有共同父级的后续所有元素 | li.red ~ li |
上下文选择器 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>标签选择器demo</title>
<style>
/* 后代选择器 */
/* 所有导航项背景色都会变成小麦色 */
.nav li {
background-color: wheat;
}
/* 父子选择器 */
/* 所有一级导航的外边距都会变成10px */
#nav > li {
margin: 10px 0;
}
/* 同级相邻选择器 */
/* 国内新闻的字体会变红 */
#international-news + li {
color: red;
}
/* 同级所有选择器 */
/* 排球,乒乓球,网球的字体会变绿 */
#football ~ li {
color: green;
}
</style>
</head>
<body>
<div class="nav">
<ul id="nav">
<li id="international-news">
<div>国际新闻</div>
</li>
<li>
<div>国内新闻</div>
</li>
<li>
<div>地方新闻</div>
</li>
<li>
<div>体育新闻</div>
<ul>
<li>
<div>篮球</div>
</li>
<li id="football">
<div>足球</div>
</li>
<li>
<div>排球</div>
</li>
<li>
<div>乒乓球</div>
</li>
<li>
<div>网球</div>
</li>
</ul>
</li>
<li>
<div>致富新闻</div>
</li>
</ul>
</div>
</body>
</html>
demo 运行效果图:
疑问:老师,为什么我用父子选择器/同级相邻选择器/统计所有选择器时,如果”体育新闻”所在的<li>
元素被选到,在它上面设置的样式,为什么也会影响到它的后代<li>
元素的样式?
3.1 结构伪类
3.1.1 不分组匹配
序号 | 选择器 | 描述 | 举例 |
---|---|---|---|
1 | :first-child |
匹配第一个子元素 | div :first-child |
2 | :last-child |
匹配最后一个子元素 | div :last-child |
3 | :only-child |
选择元素的唯一子元素 | div :only-child |
4 | :nth-child(n) |
匹配任意位置的子元素 | div :nth-child(n) |
5 | :nth-last-child(n) |
匹配倒数任意位置的子元素 | div :nth-last-child(n) |
结构伪类选择器-不分组匹配_demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>伪类选择器-结构伪类-不分组匹配demo</title>
<style>
.container {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 5px;
}
.item {
font-size: 2rem;
background-color: lightskyblue;
display: flex;
justify-content: center;
align-items: center;
}
/* 匹配第一个元素 */
/* 利用:first-child给20宫格最外部加边框 */
body > *:first-child {
border: 3px solid red;
}
/* 利用:first-child把第一个方块字体设置为红色 */
body *.item:first-child {
color: red;
}
/* 利用:last-child把最有一个方块字体设置为绿色 */
.container > .item:last-child {
color: green;
}
/* 利用:nth-child()把第二个方块的背景色设置为浅黄色 */
.container .item:nth-child(2) {
background-color: lightyellow;
}
/* 利用:nth-child()为前三个方块增加边框 */
.container .item:nth-child(-n + 3) {
border: 2px dashed green;
}
/* 利用:nth-child()把偶数方块的字体大小设置为15px */
.container :nth-child(even) {
font-size: 15px;
}
/* 利用:nth-child()把奇数方块的背景色设置为浅绿色 */
.container :nth-child(odd) {
background-color: lightgreen;
}
/* 利用:nth-last-child()为倒数第二个方块的字体加上下划线 */
.container :nth-last-child(2) {
text-decoration: underline;
}
/* 利用:nth-last-child()为第十六到第二十个方块加上圆角 */
.container :nth-last-child(-n + 5) {
border-radius: 20px;
}
</style>
</head>
<body>
<!-- 二十宫格 -->
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
<div class="item">16</div>
<div class="item">17</div>
<div class="item">18</div>
<div class="item">19</div>
<div class="item">20</div>
</div>
</body>
</html>
demo 运行效果图:
3.1.2 分组匹配
序号 | 选择器 | 描述 | 举例 |
---|---|---|---|
1 | :first-of-type |
匹配按类型分组后的第一个子元素 | div :first-of-type |
2 | :last-of-type |
匹配按类型分组后的最后一个子元素 | div :last-of-type |
3 | :only-of-type |
匹配按类型分组后的唯一子元素 | div :only-of-type |
4 | :nth-of-type() |
匹配按类型分组后的任意位置的子元素 | div :nth-of-type(n) |
5 | :nth-last-of-type() |
匹配按类型分组后倒数任意位置的子元素 | div :nth-last-of-type(n) |
分组匹配 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>伪类选择器-结构伪类-分组匹配demo</title>
<style>
.container {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 5px;
}
.item {
font-size: 2rem;
background-color: lightskyblue;
display: flex;
justify-content: center;
align-items: center;
}
/* 使用:first-of-type把span元素组的第一个方格的字体颜色设置为红色 */
.container > span:first-of-type {
color: red;
}
/* 使用:last-of-type把span元素组的最后一个方格的背景色设置为黄色 */
.container > .second-group:last-of-type {
background-color: yellow;
}
/* 使用:only-of-type把container的背景色设置为绿色(container的元素没有相同标签名的兄弟元素) */
body > *:only-of-type {
background-color: green;
}
/* 使用:nth-of-type()把span元素组的第二个方格背景色设置为小麦色 */
.container span:nth-of-type(2) {
background-color: wheat;
}
/* 使用:nth-of-type()把div元素组的偶数方格的字体设置为15px */
.container div:nth-of-type(even) {
font-size: 15px;
}
/* 使用:nth-of-type()把div元素组的奇数方格的背景色设置为浅绿色 */
.container div:nth-of-type(odd) {
background-color: lightgreen;
}
/* 使用:nth-last-child()把span元素组的前三个方格加上圆角 */
.container span:nth-of-type(-n + 3) {
border-radius: 10px;
}
/* 使用:nth-last-of-type()把div元素组的后三个方格的文字加下划线 */
.container div:nth-last-of-type(-n + 3) {
text-decoration: underline;
}
</style>
</head>
<body>
<!-- 二十宫格 -->
<div class="container">
<!-- 第一组 -->
<div class="item first-group">1</div>
<div class="item first-group">2</div>
<div class="item first-group">3</div>
<div class="item first-group">4</div>
<div class="item first-group">5</div>
<div class="item first-group">6</div>
<div class="item first-group">7</div>
<div class="item first-group">8</div>
<div class="item first-group">9</div>
<div class="item first-group">10</div>
<!-- 第二组 -->
<span class="item second-group">11</span>
<span class="item second-group">12</span>
<span class="item second-group">13</span>
<span class="item second-group">14</span>
<span class="item second-group">15</span>
<span class="item second-group">16</span>
<span class="item second-group">17</span>
<span class="item second-group">18</span>
<span class="item second-group">19</span>
<span class="item second-group">20</span>
</div>
<span>我是验证:only-of-type设置干扰项1</span><br />
<strong>我也会被:only-of-type变绿</strong><br />
<span>我是验证:only-of-type设置干扰项2</span>
</body>
</html>
demo 运行效果图:
- 疑问: 分组匹配是不是只能根据元素进行分组? 我尝试用类进行分组(标签都用
div
), 似乎并没有起作用.
3.3 表单伪类: 根据表单控件状态特征进行选择
序号 | 选择器 | 描述 |
---|---|---|
1 | :active |
向被激活的元素添加样式 |
2 | :focus |
向拥有键盘输入焦点的元素添加样式 |
3 | :hover |
当鼠标悬浮在元素上方时,向元素添加样式 |
4 | :link |
向未被访问的链接添加样式 |
5 | :visited |
向已被访问的链接添加样式 |
6 | :root |
根元素,通常是html |
7 | :empty |
选择没有任何子元素的元素(含文本节点) |
8 | :not() |
排除与选择器参数匹配的元素 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>伪类选择器-结构伪类-分组匹配demo</title>
<style>
section {
margin-bottom: 10px;
}
section > label:first-child {
display: inline-block;
width: 80px;
text-align: right;
margin-right: 10px;
}
input {
padding: 1px 5px;
}
/* 1.使用:active让所有控件被点按时背景色变成浅黄色 */
fieldset input:active,
fieldset textarea:active {
background-color: lightyellow;
}
/* 2.使用:focus让当前获取到焦点的控件字体变红 */
fieldset input:focus,
fieldset textarea:focus {
color: red;
outline: none;
}
/* 3.使用:hover使鼠标进入单选框时, 鼠标变成点击手势 */
input[type="radio"]:hover {
cursor: pointer;
}
/* 4.使用:link把未被访问的链接字体改为红色 */
a:link {
color: red;
}
/* 5.使用:visited把已访问过的链接字体改为绿色 */
a:visited {
color: green;
}
/* 6.使用:root把根元素(html元素)的背景色设置为亮绿色 */
/* fieldset:root {
background-color: lightgreen;
} */
/* 使用:empty把空文本域的背景色设置为浅粉色 */
fieldset textarea:empty {
background: lightpink;
}
/* 7.使用:not()把不是第一项和最后一项的section中的label的背景色设置为小麦色 */
fieldset
section:not(:first-of-type):not(:last-of-type)
label:first-of-type {
background-color: wheat;
}
/* 8.使用:checked把被选中的选项项字体加粗 */
fieldset input[type="radio"]:checked + label,
fieldset select > option:checked {
font-weight: bold;
}
/* 9.把必填项的input框的背景色变浅绿色 */
fieldset input:required {
background-color: lightgreen;
}
</style>
</head>
<body>
<fieldset>
<legend>用户注册</legend>
<section id="username-section">
<label for="username">用户名:</label>
<input
type="text"
name="username"
id="username"
required
autofocus
value="zhangsan"
placeholder="你的登录账号"
/>
</section>
<section>
<label for="email">邮箱:</label>
<input
type="email"
name="email"
id="email"
required
value="zhangsan@qq.com"
placeholder="你的邮箱"
/>
</section>
<section>
<label for="realname">姓名:</label>
<input
type="text"
name="realname"
id="realname"
required
value="张三"
placeholder="你的姓名"
/>
</section>
<section>
<label for="sex_0">性别:</label>
<input type="radio" name="sex" id="sex_2" value="2" /><label for="sex_2"
>保密</label
>
<input type="radio" name="sex" id="sex_0" value="0" checked /><label
for="sex_0"
>男</label
>
<input type="radio" name="sex" id="sex_1" value="1" /><label for="sex_1"
>女</label
>
</section>
<section>
<label for="introduce">自我介绍:</label>
<textarea name="introduce" id="introduce" cols="30" rows="5"></textarea>
</section>
<section>
<label for="from">来自:</label>
<select name="from" id="from">
<option value="南宁" selected>南宁</option>
<option value="柳州">柳州</option>
<option value="桂林">桂林</option>
</select>
</section>
</fieldset>
<p><a href="http://">我是未被点击的链接</a></p>
<p><a href="http://www.baidu.com">我是被点击过的链接</a></p>
</body>
</html>
demo 运行效果图:
疑问: 使用:root 设置<html>
元素的背景色, 似乎没有成功, 是不是<html>
元素的样式设置是有限制的, 并不是所有的样式都能设置?
4. 个人心得
- 这一节课真是内容满满, 使用选择器就像魔术师操纵控制各种道具一样.
- 个人的理解, 简单选择器是根据元素的标签和属性的角度去查找元素, 类似根据姓氏和信息去查找某些/类人. 如: 张姓(对比标签选择器), 家住南宁(对比属性选择器)的人; 李姓(对比标签选择器), 身份证号是 xxxx(对比 ID 选择器)的人等.
- 上下文选择器, 则从另外一个角度, 即从 HTML 文档标签树中各个标签节点的上下父子关系来定位要查找的元素. 类似家谱, 比如, 查找家谱中都叫我”爸爸”的人, 类似上下文选择器中的父子选择器; 查找家谱中, 我年龄最大的弟弟, 类似同级相邻选择器等.
- 伪类选择器, 结构伪类就是对简单选择器和上下文选择器筛选结果再做更精确的筛选. 而表单伪类就是利用表单控件属性对表单控件进行精确筛选.