🚀 为什么叫CSS?从名字理解「层叠样式表」的奥义
你有没有想过——
- 为什么CSS不叫「HTML美容仪」或者「网页颜料桶」? 🎨
- 「层叠」到底是什么意思?样式还能叠在一起?
- 为什么有时候写的CSS不生效?谁在背后「耍大牌」?
其实,CSS(Cascading Style Sheet) 这个名字暗藏玄机! 它不仅仅是个「样式工具」,更是一套精密运转的规则体系。
🎯 拆解CSS:名字里的三个关键秘密
1. Cascading(层叠)—— 样式是怎么「打架」的?
想象你在给网页「穿衣服」:
- 你写了
.button { color: red; },但页面上的按钮还是蓝色? - 你的同事也写了
#submit-btn { color: blue; },结果谁的样式生效了?
这就是「层叠」的威力—— CSS会按照优先级规则,像瀑布一样「冲刷」样式,最终决定谁「胜出」💥
(后面我们会揭秘优先级计算,让你彻底掌控样式战场!)
2. Style(样式)—— 不只是「颜色和字体」
很多人以为CSS就是改改颜色、调调间距…… 但它的真正能力远不止于此!
✅ 布局控制(Flexbox、Grid 让网页排版随心所欲)
✅ 动画交互(hover、transition 让元素动起来)
✅ 响应式适配(媒体查询让网页在手机/电脑上都完美显示)
CSS不是「颜料」,而是「网页的造型师」! ✂️
3. Sheet(表)—— 为什么是「表」而不是「代码」?
早期的CSS真的像一张「表」——
h1 { font-size: 24px; color: #333; }
p { line-height: 1.5; margin: 10px; }
这种「属性-值」的配对形式,就像字典一样清晰可查📖
从名字到本质:CSS的核心思想
| 关键词 | 含义 | 实际影响 |
|---|---|---|
| Cascading | 样式层叠 | 同种样式下,优先级决定最终效果 |
| Style | 视觉+交互 | 不只美化,还能控制布局和动画 |
| Sheet | 规则集合 | 结构化书写,易于维护和扩展 |
💡 思考题 如果你给同一个元素写了:
p { color: red; }
.text { color: blue; }
最终文字是什么颜色? (答案会在文中揭晓!)
🔥CSS的优先级&各种关系选择器
选择器
话不多说,我们直接上例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
你来填写
</style>
</head>
<body>
<div class="container">
<p>标题之前的p标签</p>
<h1>标题</h1>
<p>this is the first graph</p>
<p>this is the second graph</p>
<a href="#">link</a>
<span>this is a span</span>
<div class="inner">
<p>this is within</p>
</div>
</div>
</body>
</html>
以下是样式图:
如果说,我想把标题下的第一个p标签设置为红色,该怎么办呢?
那么大家就要用到相邻兄弟选择器+ 了:
h1+p {
color: red;
}
h1+p 意为:h1标签后的同级的第一个p标签,这是Selector的内容,之后给了它Key-Value:color:red,完成了这次任务。
那如果我想选择h1后面所有的兄弟p标签呢?
那就需要用到通用兄弟选择器~ 了:
h1~p{
color:blue;
}
再者,我们能不能把container中所有的p标签全部选择?
可以的兄弟,可以的,只需要用后代选择器 (空格) 就好了:
.container p{
text-decoration: underline;
}
我们看到,在这个html中,有一个graph是在inner中的,处于container的孙代,那么我们可不可以把它抛弃,除了它全部选择?
那么我们就要用子代选择器> :
.container>p{
font-weight: bold;
}
以上样式结合如下:
/* 兄弟选择器,只选一个相邻的同级的兄弟*/
h1+p{
color: red;
}
/*h1后面所有的兄弟*/
h1~p{
color:blue;
}
/*只选择了子代的p而没有孙代的p*/
.container>p{
font-weight: bold;
}
/*选择了container中所有的p*/
.container p{
text-decoration: underline;
}
那么你们猜猜最终展现结果会是怎么样呢?
结果如下:
为什么结果会是这样?
有的盆友们疑问了:我不是利用
h1+p{ color: red; }
将第一个p(this is the first graph)变为红色了吗?为什么现在变成了蓝色?
这就显示出了层叠的威力了:因为我们的选择器虽然都选中的是p标签,但是我们先选中的被后来选中的给覆盖掉了,因为它们选择的均是标签,所以在优先级上处于同一级,而代码执行时由上到下,先执行了让文本变红的CSS语句,又执行了让文本变蓝的CSS语句,所以最终呈现的是蓝色。
但如果给第一个p标签加上一个class或者id,再利用这俩选择器去选择,那么结果就不一样了。
优先级
要记住优先级,只需要记住一句话:越精细,说话越有份量
也就是控制的元素越精确,优先级越高
想象一下,CSS选择器的优先级就像一群人试图找到并「真实」同一个人(HTML元素),而 「精度」就像他们的寻人方式:
| 选择器 | 如何找人 | 精度(优先级) | 结果 |
|---|---|---|---|
*(全局选择器) | 在全国广播:“所有人注意!” | 最低(0,0,0) | 谁都能听到,但没人当回事,轻易被覆盖 |
.class(类选择器) | 在某小区贴告示:“穿红衣服的住户出来!” | 中等(0,1,0) | 能定位一群人,但可能误伤(多个元素用同一个class) |
#id(ID选择器) | 直接上门敲门:“502室的张三,开门!” | 高(1,0,0) | 精准定位唯一目标(ID全局唯一) |
<style>内联样式 | 当面揪住衣领:“就你,别跑!” | 最高(1,0,0,0) | 直接物理控制,优先级碾压一切 |
当然你不要以为直接物理控制就是最牛b的了,看下面这个例子:
<p style='color:red;'>Hello my friend</p>
p{
color:blue !important;
}
最终会是什么结果呢?
答案是blue!
因为!important已经不是物理真实你的程度了,是直接端着导弹喂你嘴里了,优先级最高!!!
所以,优先级排序如下:
!important>inline-style>id>class>label>*
😰伪类?伪人?
伪类是个什么东西?
伪类咱不知道是个啥,伪人咱还不知道吗,伪人不是人,那当然伪类也不是类,伪人可能不是好东西,但伪类是个好东西🤭,且听我慢慢讲来~
我们都知道 CSS规则由以下属性组成:
Selector 帮助我们选择我们想要的元素,而伪类的出现,让我们能够选择处于某种状态下的html元素。
例如::hover、:active、:focus、checked ......
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>伪类选择器</title>
<style>
</style>
</head>
<body>
<div class="container">
<h1>伪类选择器示例</h1>
<p>CSS伪类用于定义元素的特殊状态,如:hover :active</p>
<button>惦记我~</button>
</div>
</body>
</html>
:active
首先我们来通过例子理解一下伪类,以:active为例,如果我们想给button加一个在点击状态下按钮变色,文本变色的效果该怎么加呢?
如果按照我们通常的做法,我们只能通过选择器直接选择button,直接变色不符合我们的需求,在这种情况下我们选择的是按钮本身,而不是按钮被点击的状态,如果要选中按钮被点击的状态,就需要用到伪类了:
button:active{
background-color: red;
color: white;
}
在这里我们选择了所有的button标签(因为全局就这一个button),利用伪类选择了它被激活的状态,加了一些样式。
其他的一些伪类
接下来我们介绍一下其他的伪类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>伪类选择器</title>
<style>
/*一般用一个冒号,单独写用两个冒号*/
/*行为伪类 hover active selection*/
button:active{
background-color: red;
color: white;
}
p:hover{
background-color: yellow;
}
::selection{
background-color: blue;
color:white;
}
/*状态伪类 focus checked*/
input:focus{
border: 2px solid blue;
}
input:checked+label{
font-weight:bold;
}
/*input处于checked状态下,所选的label的字体加粗*/
/*结构伪类 nth-child*/
li:nth-child(even){
background-color: rgb(211, 211, 208);
}
li:nth-child(odd){
background-color: rgb(95, 95, 90);
}
/*条件伪类*/
li:not(:last-child){
margin-bottom: 10px;
}
/*选中第几个子元素,odd奇数 even偶数*/
</style>
</head>
<body>
<div class="container">
<h1>伪类选择器示例</h1>
<p>CSS伪类用于定义元素的特殊状态,如:hover :active</p>
<button>惦记我~</button>
<p>鼠标悬浮在这里</p>
<input autofocus type="text" placeholder="Please enter messages">
<input type="checkbox" name="check1" id="option1">
<label for="option1">1</label>
<input type="checkbox" name="check1" checked id="option2">
<label for="option2">2</label>
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ul>
<!-- autofocus自动聚焦,或者按tab从文件上面到下面依次聚焦,checkbox加了checked后默认选中 -->
</div>
</body>
</html>
:hover
如上述效果可见,:hover选择的是鼠标漂浮在某个元素上的效果,经常被用于按钮上,或实现放大或者发光的效果。
:focus
focus即为聚焦,让所选中的元素聚焦在哪里,你可以现在就按一按tab
::selection
即为选中,大家可以将光标放在p标签上尝试选中一段文本,看看效果
:checked
为checkbox的选中效果,上述可以利用其为label做样式变化:
input:checked+label{
font-weight:bold;
}
我们利用了input框的checked属性,锁定到了一个input的checked状态,再利用兄弟选择器选中了label,使其字体变粗,这就是伪类的实际应用。
为什么input框的输入没有被影响?
我们说了 伪类可以表示某个元素的某个状态,但是上面的输入框根本没有checked属性时,它自然就不会被选中影响咯~
:nth-child()
会被用来选中某些元素的子元素,比如上面的例子,如何理解呢?
nth 的意思就是第几个嘛
child 的意思就是孩子
那么连起来就是 第几个孩子,odd代表奇数,even代表偶数,()内可以填任意数字
面试题: nth-child() & nth-of-type()的区别
大家不知道什么是nth-of-type()并没有关系,我们可以通过下面的例子来说明一下: 完整的html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container p:nth-child(5){
background-color: yellow;
color:black;
}
.container#demo p:nth-of-type(2){
background-color: aqua;
color:black;
}
</style>
</head>
<body>
<div class="container" id="demo">
<h1>nth-child vs nth-of-type</h1>
<p>这是个段落</p>
<div>这是个div
<p>div内的p</p>
</div>
<p>第二个段落</p>
<p>第三个段落</p>
<div>这是第二个div</div>
</div>
</body>
</html>
这是效果图,但如果我们将
.container p:nth-child(5){
background-color: yellow;
color:black;
}
改为:
.container p:nth-child(3){
background-color: yellow;
color:black;
}
那么效果图就为:
这时候我们可以看出 .container p:nth-child(x)的含义为:选择container下的所有后代的第x个元素,而且这个元素必须是p标签,才会应用样式
接下来我们改变nth-of-type(x):
x=3:
x=1:
这时我们可以发现
.container#demo p:nth-of-type(x) 的原理是:选择id为demo的元素下的所有的第x个p元素,并改变其样式
总结不同
| 特性 | :nth-child(n) | :nth-of-type(n) |
|---|---|---|
| 选择依据 | 父元素的所有子元素中的第 n 个(无视标签类型) | 父元素的同类型子元素中的第 n 个 |
| 是否区分元素类型 | ❌ 不区分(任何标签都计入计数) | ✅ 区分(仅匹配指定标签类型的元素) |
| 语法示例 | li:nth-child(2) → 选择第 2 个子元素(需是 li) | li:nth-of-type(2) → 选择第 2 个 li 元素 |
| 匹配失败时的行为 | 如果第 n 个子元素不匹配选择器,则无效果 | 仅统计同类型元素,其他标签不影响计数 |
总结
CSS选择器就像一场相亲大会,各种元素在DOM树里眉来眼去。关系选择器就是它们的红娘,A B这种媒婆最不讲究,只要在家族谱系里能找到的都算数;A > B就比较势利眼了,必须是直系血亲才认;A + B活像个跟屁虫,非要紧挨着才肯配对;A ~ B倒是个海王,只要在同一个屋檐下的都算备胎。
伪类选择器简直就是元素的心情日记。:hover是"人家被鼠标调戏了啦",:active是"被按住了别乱动",:focus是"镜头对准我!"。最精分的是:checked,一会儿勾选一会儿取消,比渣男还善变。
至于:nth-child和:nth-of-type这对双胞胎,表面看着像,骨子里完全不同。:nth-child是个死脑筋,非要按出生顺序来,管你是男是女;:nth-of-type就聪明多了,知道把男孩女孩分开排队。就像相亲时,前者会把你的前任都算上,后者只会统计同类型的约会对象。
总结起来,CSS选择器就是一场大型社交现场:有的广撒网(后代选择器),有的挑三拣四(子选择器),有的爱凑热闹(相邻兄弟),还有的专门搞特殊(伪类)。而:nth-child和:nth-of-type这对活宝,一个像钢铁直男,一个像贴心闺蜜,用错了可是要闹笑话的!
大家一定要多加练习,好好做笔记才能掌握我们所学的内容!下期见!