主题
CSS 高级(二)
本页对应 CSS 高级,共 8 段视频,约 1 小时 30 分。
学习目标
- 能说明
z-index仅对定位元素生效、默认值为auto、取整数且数值越大层级越高,并能通过设置不同z-index解决固定定位或相对定位盒子被遮挡的问题。 - 能对比
relative、absolute、fixed的脱标、模式转换和参照物差异,并能根据顶部固定、子绝父相等场景选择正确定位方式。 - 能使用
position: sticky配合top等偏移值实现吸顶效果,并能通过提高z-index解决粘性定位元素被后续定位元素遮挡的问题。 - 能使用 CSS 精灵图完成图标显示:创建与图标等大的盒子,设置精灵图背景,并通过负值
background-position定位到指定图标。 - 能实现鼠标经过更换精灵图:使用
:hover修改background-position,配合transition完成图标切换动画,并能说明位移过大时的切换表现。 - 能引入字体图标文件并使用
iconfont加图标类名显示图标,通过font-size、color调整样式,并完成学成在线箭头、放大镜图标的替换与绝对定位微调。
知识点
CSS精灵:为什么需要
CSS 精灵(CSS Sprites,也叫精灵图、雪碧图)是把网页中一些小的背景图整合到一张大图上,再用 background-position 定位显示其中某一块。这样做的核心原因是减少浏览器向服务器请求图片的次数:多张小图要请求多次,合成一张大图只需请求一次,浏览器还能利用缓存,从而减轻服务器压力、提高页面加载速度。

怎么想:盒子不动,动背景
使用精灵图时不要把盒子挪来挪去找图,而应固定盒子位置,移动背景图。盒子尺寸要与要显示的小图尺寸一致;背景图设为整张精灵图;再通过 background-position 把目标小图“拖”到盒子中。因为背景图通常要向左、向上移动,所以坐标多为负值。

怎么做:三步与测量
- 创建盒子,盒子宽高与小图一致。
- 设置盒子背景图为精灵图,并加
no-repeat。 - 用 PxCook(像素大厨)测量小图左上角坐标,把坐标取负值写入
background-position。
调试时可用像素大厨的坐标工具点目标小图左上角,得到如 5px 275px,实际写 -5px -275px。鼠标经过换图时,本质也是改 background-position;可加 transition 让背景位置平滑变化。
案例:写出自己的名字
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
display: inline-block;
margin: 0 15px;
background: url(./images/abcd.jpg) no-repeat;
}
.l {
width: 96px;
height: 112px;
background-color: pink;
background-position: -5px -275px;
}
.i {
width: 62px;
height: 107px;
background-position: -324px -141px;
}
.u {
width: 112px;
height: 112px;
background-position: -476px -421px;
}
span {
display: block;
width: 106px;
height: 118px;
background: url(./images/abcd.jpg) no-repeat;
/* 过渡 */
transition: .2s;
}
span:hover {
/* background-position: -118px -12px; */
background-position: -484px -10px;
/* width: 95px; */
/* background-position: -3px -137px; */
}
</style>
</head>
<body>
<div class="l"></div>
<div class="i"></div>
<div class="u"></div>
<span></span>
</body>
</html>精灵图易错点
盒子尺寸必须和小图一致,否则会露出旁边图案;坐标一般取负值;不要靠移动盒子来换图;hover 换图时坐标不要跨太远,否则过渡会“扫过”中间图案;精灵图适合简单小背景图,复杂渐变图不一定适合。
字体图标:为什么需要
字体图标“展示的是图标,本质是字体”,适合网页中简单的、颜色单一的小图标。它比图片灵活:可用 font-size 改大小、color 改颜色;体积小、渲染快、减少请求,兼容性也好。

怎么想:把图标当文字用
因为本质是字体,所以改大小用 font-size,改颜色用 color。使用时先引入字体样式表,再给标签加两个类名:iconfont 是基础样式,icon-xxx 是对应图标类名。
怎么做:下载与使用
进入 iconfont 图标库,登录后选“素材库 → 官方图标库”,选图标加入购物车,添加至项目,再下载至本地。解压后把字体文件和 iconfont.css 放到 fonts 文件夹,页面中 link 引入 iconfont.css。


html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./fonts/iconfont.css">
<style>
.iconfont {
font-size: 300px;
color: pink;
}
</style>
</head>
<body>
<!-- 必须2个类名,第一个类名iconfont -->
<i class="iconfont icon-shouji"></i>
<span class="iconfont icon-zhaoxiangji"></span>
</body>
</html>字体图标易错点与调试
必须写两个类名,第一个固定为 iconfont;引入的是 iconfont.css,不要引成演示用的 demo.css。若直接给 i 写 font-size 不生效,通常是 iconfont 类里的默认字号把它层叠掉了,应写到 .iconfont 或更具体选择器上。做学成在线放大镜时,可用绝对定位压住搜索框,父级加相对定位形成“子绝父相”;right 的正值表示离右边更远。不要给 .iconfont 统一加定位,以免影响页面中所有图标。
垂直对齐方式


为什么需要:图片、行内块元素和文字并排时,默认按基线对齐,图片底部常出现缝隙。
怎么想:vertical-align 用来控制行内元素、行内块元素与文字基线的对齐关系。
怎么做:给图片和行内块设置 vertical-align: middle;去除图片底部缝隙可给图片 display: block,或设置 vertical-align: middle 等非 baseline 值。
html
<style>
img { vertical-align: middle; }
span {
display: inline-block;
vertical-align: middle;
width: 50px;
height: 50px;
background-color: pink;
}
div { border: 2px solid red; }
</style>
<img src="./images/computer.png" alt=""> my name is 刘德华
<span></span> my name is 刘德华
<hr>
<div><img src="./images/1.webp" alt=""></div>易错点:vertical-align 对块级元素本身不生效;它不是 margin/padding,不能拿来随意移动大盒子。
过渡
为什么需要:hover、focus 状态切换如果瞬间变化,视觉上很生硬。
怎么想:谁本身要从状态 A 变到状态 B,就把 transition 加在谁身上,即“谁做过渡给谁加”。
怎么做:transition: all .3s;,再在 :hover 或 :focus 中改变尺寸、颜色等。转写稿中演示鼠标经过切换背景位置时,不加过渡会瞬间跳变,加上 transition: all .3s 后才慢慢滑过去;注意 .3s 的 s 不能漏。
css
.box {
width: 200px;
height: 200px;
background-color: pink;
transition: all .3s;
}
.box:hover {
height: 300px;
width: 300px;
background-color: green;
}
input {
width: 200px;
height: 30px;
transition: all .3s;
}
input:focus {
width: 300px;
background-color: pink;
}易错点:transition 不要只写在 :hover 里;时间必须带单位;all 方便,但生产里可写具体属性。
表单获得焦点选择器 focus
为什么需要:表单得到光标时需要提示用户当前正在输入。
怎么想:用 :focus 匹配获得焦点的表单元素,再配合过渡更自然。
怎么做:input:focus { width: 300px; background-color: pink; }。
易错点:focus 只对可聚焦元素明显生效;过渡仍要加在 input 本身。
透明度 opacity
为什么需要:做遮罩、半透明盒子时,需要控制透明效果。
怎么想:整个元素连内容都透明用 opacity;只让背景透明用 rgba。
怎么做:
css
body { background: url(./images/huawei.jpg); }
.box1 {
width: 200px;
height: 200px;
background-color: pink;
opacity: 0.2;
}
.box2 {
width: 200px;
height: 200px;
background-color: rgba(0, 0, 0, 0.3);
color: #fff;
}易错点:opacity: 0 是完全透明但仍占位置;opacity 会影响子内容,rgba 只影响背景色。
光标类型 cursor

为什么需要:鼠标样式能提示用户“可点击、可选择、可移动、被禁用”。
怎么想:根据交互语义选值:可点击用 pointer,文本用 text,移动用 move,禁用用 not-allowed。
怎么做:
css
div:nth-child(1) { cursor: default; }
div:nth-child(2) { cursor: pointer; }
div:nth-child(3) { cursor: text; }
div:nth-child(4) { cursor: move; }
div:nth-child(5) { cursor: not-allowed; }
button { cursor: pointer; }
易错点:button 默认不一定显示小手,常需 cursor: pointer;not-allowed 只是样式,不会真正阻止点击,还需 disabled 或 JS 控制。
表格样式:合并相邻边框

为什么需要:表格默认相邻单元格边框会叠加,出现“双边框”,不够整洁;斑马纹能提升可读性。
怎么想:先合并边框,再用 nth-child(even/odd) 给奇偶行加背景。
怎么做:
css
table {
width: 700px;
height: 400px;
margin: 0 auto;
text-align: center;
}
table, tr, td {
border: 1px solid pink;
border-collapse: collapse;
}
tr:nth-child(even) { background-color: #eee; }
tr:nth-child(odd) { background-color: #ddd; }易错点:border-collapse: collapse 写在 table 上;nth-child 从 1 开始计数,even/2n 是偶数行,odd/2n+1 是奇数行。
课件图示




代码示例
示例一:CSS 精灵(写出自己的名字)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
display: inline-block;
margin: 0 15px;
background: url(./images/abcd.jpg) no-repeat;
}
.l {
width: 96px;
height: 112px;
background-color: pink;
background-position: -5px -275px;
}
.i {
width: 62px;
height: 107px;
background-position: -324px -141px;
}
.u {
width: 112px;
height: 112px;
background-position: -476px -421px;
}
span {
display: block;
width: 106px;
height: 118px;
background: url(./images/abcd.jpg) no-repeat;
/* 过渡 */
transition: .2s;
}
span:hover {
/* background-position: -118px -12px; */
background-position: -484px -10px;
/* width: 95px; */
/* background-position: -3px -137px; */
}
</style>
</head>
<body>
<div class="l"></div>
<div class="i"></div>
<div class="u"></div>
<span></span>
</body>
</html>要点解释:
background: url(./images/abcd.jpg) no-repeat;把整张精灵图作为背景,no-repeat防止平铺,一张图就被多个盒子共用。- 盒子的
width/height必须与要取的那张小图尺寸完全一致(如.l为 96×112),否则会把相邻的字露出来。 background-position取负数:小图左上角在精灵图中的坐标是 (5, 275),向左上移动图片才能把该字移到盒子内,所以写成-5px -275px。- 易错点:坐标写成正数图片会往右下跑,盒子内就看不到目标字;漏写
no-repeat会把整张图铺满。 - 盒子的
margin、display: inline-block只影响盒子摆放,不影响背景图显示内容。 transition: .2s让span:hover切换background-position时产生平滑滚动效果。
示例二:字体图标的使用
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./fonts/iconfont.css">
<style>
.iconfont {
font-size: 300px;
color: pink;
}
</style>
</head>
<body>
<!-- 必须2个类名,第一个类名iconfont -->
<i class="iconfont icon-shouji"></i>
<span class="iconfont icon-zhaoxiangji"></span>
</body>
</html>要点解释:
- 第一步必须
<link rel="stylesheet" href="./fonts/iconfont.css">引入字体样式表,路径是iconfont.css,不是demo.css。 - 使用时必须写两个类名:第一个固定是
iconfont(字体名、基础样式),第二个icon-xxx决定显示哪个图标;漏掉iconfont图标就不会出来。 - 图标本质是字体,所以用
font-size改大小、color改颜色;想改大小直接写font-size: 300px即可,放多大都不会模糊。 - 易错点:直接给
i { font-size: ... }可能被iconfont类里的默认字号层叠掉(调试工具里会被划掉),所以统一写在.iconfont上或用类名覆盖。 - 标签用
i、span都可以,与标签无关,关键是那两个类名。
示例三:过渡 transition 与 focus 选择器
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: pink;
/* 谁做过渡给谁加 */
transition: all .3s;
}
.box:hover {
height: 300px;
width: 300px;
background-color: green;
}
input {
width: 200px;
height: 30px;
transition: all .3s;
}
/* 当表单得到光标的时候 */
input:focus {
width: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div class="box"></div>
<input type="text">
</body>
</html>要点解释:
transition: all .3s;是复合属性:过渡的属性 + 花费时间;时间必须带单位 s,写.3不生效。- 过渡要写在元素本身(
.box)上,不能写在:hover里,否则移出时没有过渡效果——口诀“谁做过渡给谁加”。 all表示两个状态中所有变化的属性都过渡(宽、高、背景色),也可以只写具体属性如transition: width .3s;。input:focus是表单获得光标时的状态选择器,配合transition可以实现输入框聚焦变宽的效果。- 易错点:
.3s漏写单位、把transition写在:hover中、属性名拼错(如transiton),都会导致动画失效。
常见错误
1. 写了 z-index 却没有任何效果
- 现象:给盒子设了
z-index: 999,仍然被下面的元素盖住。 - 原因:
z-index只对定位元素生效,盒子的position仍是static;或者比较对象不在同一层叠上下文里(父级已带z-index或opacity < 1等)。 - 修法:先给该元素补上
position(relative/absolute/fixed/sticky 任一);再顺着 DOM 往上检查父级是否创建了层叠上下文,有的话要到同级那一层去比大小。
2. 粘性定位“不粘”
- 现象:加了
position: sticky,滚动时元素照样跟着页面滚走。 - 原因:
sticky必须至少配合一个top / right / bottom / left阈值才生效,只写position等于没写。 - 修法:补
top: 0(或按需求给top: 100px等);同时检查祖先元素有没有overflow: hidden之类的裁剪,否则粘不住。
3. 精灵图盒子显示的不是想要的那个小图
- 现象:盒子只露出半截字母,或显示的是图左上角那个字符。
- 原因:
background-position没写 / 写成正值 / 盒子尺寸与小图尺寸不一致。 - 修法:先用取色/测量工具量出小图左上角坐标,取负值写入
background-position;盒子宽高严格等于小图宽高。
4. 给图标加定位,结果一排图标全跑位了
- 现象:只想移动放大镜,结果所有箭头、所有图标一起脱离原位。
- 原因:把
position、right、top这些样式写在了公共类(如.iconfont或.icon-xxx)上,命中了所有同类元素。 - 修法:给需要定位的那一个元素单独加专属类名(如
.magnifier),定位样式只写在专属类名上;公共类只放字体、字号、颜色这类通用样式。
5. 字体图标不显示(空白 / 小方块 / 问号)
- 现象:
<i class="iconfont icon-shouji"></i>页面什么都没有。 - 原因:① 没引入
iconfont.css,或路径写成demo.css;② 只写了icon-xxx,漏了基础类iconfont;③ 字体文件(.ttf/.woff等)没和 css 保持同目录结构。 - 修法:
<link>指向fonts/iconfont.css,检查 Network 面板里字体文件是否 200;标签上两个类名都写全。
6. 字体图标改 font-size 不生效(被划掉)
- 现象:DevTools 里自己写的
font-size: 300px有一条删除线。 - 原因:
.iconfont类里自带的font-size: 16px权重相同但位置更靠后,把自己的样式层叠掉了。 - 修法:提高选择器权重,如
.search .icon-zoom、i.iconfont或加!important(最后手段),把字号写在权重更高的选择器里。
7. 鼠标经过换精灵图时“嗖”地划过一串字符
- 现象:hover 时背景飞快地从 A 滑到很远的一个字母上,中间字符一闪而过。
- 原因:默认态与 hover 态的两个坐标在精灵图上相隔太远(跨了好几个字符),过渡过程把中间区域也走了一遍。
- 修法:hover 目标选紧邻的小图(如 A↔B),两图尺寸也保持一致;跨图幅的需求不要用过渡。
练习
练习 1|精灵图拼名字 给你一张 26 字母精灵图,用 3 个盒子拼出自己姓氏拼音(如 liu)。要求:盒子尺寸与字母完全一致、用 display: inline-block + margin 排布、三个字母在同一水平线上。做完后故意把某个盒子的 background-position 改成正值,观察现象并解释原因。
练习 2|图标 hover 切换 在练习 1 的精灵图上,做一个默认显示字母 A、鼠标经过变成字母 B 的盒子(尺寸 106×110)。加上 transition: .2s,对比“A↔B 相邻”和“A↔E 相隔较远”两种写法在过渡动画上的差异,并用一句话说明为什么。
练习 3|字体图标替换 打开学成在线首页,把列表里所有“箭头”小图标换成 iconfont 字体图标,把搜索框右侧的放大镜也换成字体图标。要求:箭头 hover 时通过 color 变色(不许用换图);放大镜用绝对定位压到 input 右侧,并且不影响箭头图标的位置。改完把 font-size 调大验证是否生效。
练习 4|层级综合 页面结构:顶部固定导航、内容区若干卡片、卡片内有一个绝对定位的“热销”角标、右侧一个粘性侧栏。滚动页面,用 z-index 保证导航始终压住所有卡片,同时角标不被卡片内容盖住。完成后回答:为什么角标不加 z-index 也可能被别的卡片压住?
练习 5|找 bug 下面这段代码有 3 处问题,找出并说明原因、给出修法:
css
.iconfont { position: absolute; right: 20px; }
.box { position: static; z-index: 99; }
.nav { position: sticky; }(提示:分别从“影响范围”“生效前提”“生效条件”三个角度想。)
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 层级z-index | 13:42 |
| 2 | 定位总结 | 02:49 |
| 3 | 粘性定位 | 08:13 |
| 4 | 精灵技术 | 20:49 |
| 5 | 鼠标经过更换精灵图 | 06:57 |
| 6 | 字体图标 | 22:39 |
| 7 | 给学成在线添加字体图标 | 06:55 |
| 8 | 学成在线放大镜效果 | 08:35 |
小结
z-index是“定位元素的专属权限”——先有定位,再谈层级;没定位的盒子写多少都白写。- 默认层级的比较看 DOM 书写顺序,跟样式表里的先后无关;后来者居上。
- 想让某个元素“压住所有人”,给一个大整数(如 999)是最省心的做法,但要保证它本身是定位元素。
- 三种定位的选型口诀:跟着页面滚用固定、盖在别的盒子上用绝对、绝对的父亲用相对、滚动到某个位置才吸顶用粘性。
- 精灵图的本质是“移动背景图”,所以坐标几乎永远是负数;盒子尺寸不动,动的只有
background-position。 - 写定位、写精灵图坐标时,公共类名只放通用样式,专属样式一律另起类名,这是避免“一改全崩”的关键习惯。
- 字体图标比图片图标强在可控:尺寸、颜色、阴影都能用 CSS 改,还能加过渡和动画,能用字体图标就别切图。
- 遇到“样式不生效”先看两件事:有没有写删除线(层叠问题)、元素有没有定位(前提问题),八成的坑都在这两处。