主题
CSS3 新增背景属性(Day13 1/4)
本页对应 Day13_CSS3,共 7 段视频,约 1 小时 4 分。
学习目标
- 能够使用属性选择器(
[attr]、[attr=value]、^=、$=、*=)为下载列表按文件后缀匹配图标,并微调背景图位置。 - 能够使用
:target伪类结合锚点、绝对定位和z-index实现点击缩略图切换大图,并处理默认显示与层叠问题。 - 能够使用
:checked伪类结合radio、label和相邻兄弟选择器实现点击切换图片,并设置默认选中项。 - 能够使用
:hover、相对定位和box-shadow实现鼠标悬停图片上移与阴影效果,并使用:nth-child(4n)去除每行末项右外边距。 - 能够使用
background-origin设置背景定位原点,使用background-clip设置背景显示区域,并处理text值的私有前缀与透明文字效果。
知识点
选择器总复习:先建分类,再记细节
为什么需要:CSS3选择器数量多,死记容易混;按“基本、层级、属性、伪类、伪元素”分类,才能快速定位该用谁。
怎么想:层级选择器只找后面的兄弟;属性选择器重点掌握“包含属性名、等于、开头、结尾、包含值”五类;伪类里动态、目标、UI、结构、否定要分清;伪元素注意::before/::after必须写content。
怎么做:把高频选择器整理成表,并用案例验证。结构伪类中child系列是所有兄弟一起排,of-type系列是同标签兄弟各排各的;nth-*可写数字、odd/even、2n、4n等。
易错点:相邻兄弟必须紧挨着;nth-child与nth-of-type不要混;权重上类、伪类、属性选择器同级,!important能强制提高但不宜滥用。
属性选择器练习:让下载列表自动匹配图标
为什么需要:下载列表里文件格式不同,若每个链接手写图标类,新增文件就要改CSS。用属性选择器按href结尾自动匹配更省维护。
怎么想:先给每个a加背景图、禁止重复、靠右定位,再用padding-right给图标留位置;不同后缀只调background-position-y。
怎么做:
css
.downloads a{
background-image:url("./images/a.png");
background-repeat:no-repeat;
background-position-x:right;
padding-right:20px;
}
.downloads a[href$=".doc"]{ background-position-y:2px; }
.downloads a[href$=".xls"]{ background-position-y:-73px; }
.downloads a[href$=".ppt"]{ background-position-y:-48px; }调试时用开发者工具量精灵图坐标,先估再微调;新增.xls链接会自动套用Excel图标。
易错点:不要给a设固定宽度,否则图标会跑到整行右边而不是紧跟文字;$=表示“以……结尾”,别和*=“包含”混用。
target伪类切换图片:用锚点控制显示
为什么需要:点击小图切换大图,若用JS要写事件;纯CSS可用:target配合锚点实现。
怎么想:每张大图有唯一id,小图超链接的href="#image01"指向它;点击后URL锚点变化,对应大图成为:target。多张大图用绝对定位叠在一起,谁提高层级谁显示。
怎么做:
css
.large{ height:454px; position:relative; }
.large img{ position:absolute; left:0; top:0; }
.large img:target{ z-index:1; }转写稿调试时发现:若默认用display:block显示第一张,再点别的图,第一张无法隐藏。于是改为绝对定位重合,默认最后一张在最上面,:target只提高z-index。
易错点:父容器要定高,否则绝对定位子元素脱离文档流会塌;:target依赖URL锚点,首次打开无锚点时要设计默认显示图。
checked伪类切换图片:单选框+label更灵活
为什么需要::target能切换,但默认显示哪张不够灵活;用单选按钮的:checked状态可默认任意一张。
怎么想:每个大图前放一个radio,小图用label绑定对应id;所有大图先隐藏,选中单选框后的图片显示。
怎么做:
css
.large img{ display:none; }
.large input:checked + img{ display:block; }
.large input{ display:none; }调试时发现单选框没互斥,原因是漏写相同name;补上后点第二个,第一个自动取消。给第一个input加checked即可默认显示第一张。
易错点:label的for必须等于input的id;+只能选紧邻的兄弟,HTML顺序不能乱;隐藏input别用错选择器。
鼠标悬停阴影:结构伪类去边距+阴影上移
为什么需要:商品/图片列表悬停要有反馈,阴影和轻微上移能增强层次。
怎么想:每行4个,间距20px;若每个都加右外边距,第4个会换行。用:nth-child(4n)把4、8、12、16的右间距归零。
怎么做:
css
.item:nth-child(4n){ margin-right:0; }
.item:hover{
position:relative;
top:-2px;
box-shadow:0 15px 30px rgba(0,0,0,.1);
}易错点:top负值要配合position:relative;阴影参数顺序别乱,颜色可写长度前或后;4n是4的倍数,不是“第4个”。
背景图像原点与显示区域:origin、clip、text
为什么需要:背景图默认从内边距左上角开始并显示到边框以内;要精确控制起点和裁剪范围,需要background-origin与background-clip。
怎么想:origin管“坐标原点在哪”,clip管“哪些区域显示背景”,二者独立。text可让背景只显示在文字上。
怎么做:
css
.box{
background-image:url("./images/bg03.png");
background-repeat:no-repeat;
background-origin:border-box; /* padding-box / content-box */
background-clip:content-box; /* border-box / padding-box / text */
}
.text-box{
font-size:300px;
color:transparent;
background-image:url("./images/bg04.png");
-webkit-background-clip:text;
background-clip:text;
}易错点:origin默认padding-box,clip默认border-box;text在Chrome/Edge需私有前缀,且文字必须透明;不要因值名相同就把background-origin和box-shadow的border-box混为一谈。
本节笔记没有图片,原代码块保留如下,作为复习地图:
text
1. CSS3 选择器
1.1 基本选择器(6个)
1.2 层级选择器(4个)
后代元素、子元素、相邻兄弟、通用兄弟
1.3 属性选择器(5个)
[attr] [attr="val"] [attr^="val"] [attr$="val"] [attr*="val"]
1.4 伪类选择器(23个)
① 动态伪类(5个)
:link :visited :hover :active :focus
② 目标伪类(1个)
:target
③ 语言伪类(1个)
:lang()
④ UI元素伪类(表单伪类)(3个)
:enabled :disabled :checked
⑤ 结构伪类(12个)
child系列
of-type系列
:root :empty
⑤ 否定伪类(1个)
:not(选择器)
1.5 伪元素选择器
::first-letter ::first-line ::before ::after ::placeholder ::selection
1.6 权重
ID > 类、伪类、属性 > 标签名、伪元素
2. 新增的盒子相关样式
① display
② box-sizing: content-box/border-box
③ box-shadow
④ opacity
⑤ 粘连定位 position: sticky选择器总览:先建立分类意识
为什么需要:选择器太多,死记容易混;先按“基本、层级、属性、伪类、伪元素、权重”分类,才能知道遇到需求该往哪一类找。怎么想:转写稿反复强调“五大类”,并把交集、并集归入基本选择器;伪类再分6个子类,共23个。怎么做:复习时先背分类,再背每类代表选择器。易错点:不要把伪类和伪元素混为一谈;伪类用单冒号,伪元素用双冒号;⑤在笔记中出现两次,否定伪类要单独记。
基本选择器与层级选择器
为什么需要:基本选择器负责“选谁”,层级选择器负责“按结构关系选谁”。怎么想:基本选择器6个中含交集、并集;层级4个是后代、子元素、相邻兄弟、通用兄弟。怎么做:后代用空格,子元素用>,相邻兄弟用+,通用兄弟用~。易错点:转写稿特别提醒,相邻兄弟和通用兄弟都只找后面的兄弟,前面的不找;相邻兄弟还必须“挨着”,不挨着就不符合关系条件。
属性选择器:五个符号别弄混
为什么需要:当元素没有合适类名、但属性有规律时,属性选择器能直接按属性选。怎么想:五个分别是“有该属性、等于、以某值开头、以某值结尾、值中包含”。怎么做:如[attr]、[attr="val"]、[attr^="val"]、[attr$="val"]、[attr*="val"]。转写稿的下载列表案例就是按后缀匹配:Word、Excel、PPT分别用href$=".doc"、href$=".xls"、href$=".ppt"。调试时先给a加背景图,no-repeat,background-position-x: right,再用padding-right给图标留位置;纵坐标用background-position-y微调,转写稿说“别纠结2还是3,试出来即可”。易错点:^是开头,$是结尾,*是包含,符号不要反。
伪类选择器:23个按组记
为什么需要:伪类能表达状态和结构,很多交互不写JS也能做。怎么想:动态5个::link、:visited、:hover、:active、:focus;目标1个:target;语言1个:lang();UI表单3个:enabled、:disabled、:checked;结构12个分child系列、of-type系列和:root、:empty;否定1个:not()。怎么做:结构伪类中,child系列是“所有兄弟一起排号”,of-type系列是“同标签兄弟各排各的”;nth系列可写具体序号、odd/even、2n、2n+1等。转写稿的:target切换图片:大图绝对定位重叠,默认显示最后一张,点击锚点后给对应大图提高层级;:checked切换图片:用radio + label + img,input:checked + img显示,默认给第一个radio加checked,最后隐藏radio。易错点::focus主要落在表单控件;:target依赖URL锚点;:enabled是默认状态,只有设了disabled才符合:disabled;:not()里放选择器,别写成复杂嵌套。
伪元素与权重
为什么需要:伪元素能选“字、行、前后动态内容、占位符、选中文字”,权重决定样式覆盖。怎么想:伪元素6个:::first-letter、::first-line、::before、::after、::placeholder、::selection。::before/::after必须写content,否则不好使。权重顺序:ID > 类/伪类/属性 > 标签名/伪元素;!important可把某属性权重无限提高,但转写稿说不建议大量使用。怎么做:覆盖失败时先看权重,再看是否有人加了!important。易错点:属性选择器和类、伪类同级;伪元素算标签级;不要一见!important就滥用。
新增盒子相关样式
为什么需要:CSS3让盒子的显示、宽高计算、阴影、透明和定位更灵活。怎么想:display扩展值主要是让W3C逻辑自洽,实际项目未必大量用;box-sizing改变宽高设置规则;box-shadow做阴影;opacity做整体透明;position: sticky做粘连定位。怎么做:box-sizing默认content-box,宽高是内容宽高;改border-box后宽高是总宽高,内容和内边距、边框往里挤,转写稿推荐使用。box-shadow长度可写2到4个:x偏移、y偏移、模糊值、外延值,颜色和inset可前可后;常用是x、y、模糊加颜色。opacity是元素整体不透明度,和rgba只影响某个颜色不同。sticky仍用position,只是新增值。易错点:box-shadow外延值少用;opacity会影响子元素;box-sizing的content-box/border-box不要和背景原点里的同名值混为一谈。
先回顾:旧标准里的五个背景子属性
本节笔记先把旧标准已有的背景属性列出来:
css
background-color
background-image
background-repeat
background-position
background-attachment为什么需要先回顾? 因为 CSS3 不是把背景属性推倒重来,而是在原有背景体系上继续加子属性。转写稿里也先问“有哪些来着”,然后才引出新增内容。只有先分清哪些是旧属性,后面才不会把 background-origin、background-clip 误认为替代品。
怎么想? 可以把背景控制拆成几条线:颜色、图片地址、重复方式、位置、固定方式。旧标准已经能完成“放一张图、设位置、设重复、设固定”这些事;CSS3 新增的是更细的控制维度,比如“位置从哪个盒子算起”“背景显示到哪个区域为止”。
怎么做? 写背景时仍可使用这些子属性,也可以使用复合属性 background。转写稿提到,新增子属性后复合属性也做了调整,但本节重点先看新增子属性。
易错点: 不要把 background-attachment 和定位混为一谈;也不要把新增的 background-origin 当成“改背景位置”的唯一办法。单纯改位置,很多时候仍然用 background-position 就够了。
background-origin:背景图定位的原点
为什么需要? 转写稿里提出一个关键问题:调整背景图位置时,坐标原点到底在哪儿?是内容区左上角、内边距左上角,还是边框左上角?如果不明确原点,background-position 的数值就容易被误读。background-origin 就是用来设置背景图像定位原点的。
怎么想? 一个元素从里到外可理解为内容区、内边距、边框。默认情况下,背景图定位原点不是内容区左上角,而是内边距左上角,也就是 padding-box。改成 border-box,原点跑到边框左上角;改成 content-box,原点跑到内容区左上角。
怎么做? 转写稿中的示例思路是:给一个 div 设置宽高、内边距、虚线边框和文字,再引入背景图,先 no-repeat,观察默认原点,再改 background-origin:
css
div {
width: 600px;
height: 400px;
padding: 30px;
border: 6px dashed #900;
background-image: url("./images/bg03.png");
background-repeat: no-repeat;
background-position: 0 0;
background-origin: padding-box; /* 默认值 */
}调试时依次改成:
css
background-origin: border-box;
background-origin: content-box;转写稿中能看到:默认图从内边距左上角开始;改 border-box 后原点在边框上;改 content-box 后原点在内容区。若把 background-position 改成 1em 1em,图会从新的原点再偏移,重复时也基于当前位置继续重复。
易错点: background-origin 只改“原点”,不改“显示范围”;它的值和 box-sizing 里的 border-box、content-box 用词相似,但含义不是一回事,不能直接联想成同一功能。
background-clip:背景图显示区域
为什么需要? 默认背景图会显示到边框及边框以内。若只想让它出现在内边距以内、内容区以内,甚至只显示在文字上,就需要裁剪显示区域。转写稿把 clip 解释为“修剪、裁剪”,但更准确的理解是“设置背景图像的显示区域”。
怎么想? 要把 origin 和 clip 分开:origin 管坐标从哪儿算,clip 管哪些区域能显示。转写稿特别强调“原点是原点,显示范围是显示范围,两者互相独立”。只改 clip,背景图位置不会自动挪动,只是四周被裁掉。
怎么做? 默认值是 border-box,即边框及以内;可改为 padding-box(内边距及以内)、content-box(内容区及以内)。示例:
css
div {
background-clip: padding-box;
/* 或 content-box */
}text 值可以让背景只显示在文字上,但转写稿中的调试过程要注意:Chrome 需要私有前缀,文字还要设成透明,否则黑色文字会挡住背景。
css
.text-box {
font-size: 300px;
font-weight: bold;
text-align: center;
line-height: 500px;
color: transparent;
background-image: url("./images/bg04.png");
background-position: center;
-webkit-background-clip: text;
background-clip: text;
}转写稿中先不加前缀,刷新没变化;加 -webkit-background-clip: text 并把文字颜色改成透明后,才看到背景图只落在文字形状里。为了兼容火狐,转写稿建议同时写带前缀和不带前缀的声明。
易错点: background-clip: text 兼容性要留意,Chrome 及 Chromium 内核浏览器通常要加 -webkit- 前缀;文字不透明时看不到“文字裁剪”的效果;不要把它和 background-origin 混用成一个概念。
复合属性与多背景图的提醒
转写稿提到,CSS3 新增子属性后,复合属性 background 也做了一些调整,并且还提到“多背景图”。但本节转写稿主要展开的是 background-origin 和 background-clip,多背景图没有继续展开。学习时先把这两个新增子属性吃透:写复合属性时要知道新增子属性可以单独覆盖;看到“多背景图”先记住它是背景体系扩展的一部分,不要在没有示例的情况下硬套。
课堂画面






代码示例
示例 1:background-origin —— 背景图像定位原点
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>background-origin 背景图像定位原点</title>
<style>
body { font-family: "Microsoft YaHei", sans-serif; }
.box {
width: 600px;
height: 400px;
padding: 30px; /* 内边距,方便看清“原点”在哪 */
border: 6px dashed #900; /* 边框,方便看清“原点”在哪 */
margin-bottom: 30px;
color: #333;
background-image: url("./images/bg03.jpg"); /* 换成自己的图片即可 */
background-repeat: no-repeat;
background-position: 16px 16px; /* 用一个字的大小看得最明显 */
/* background-origin 默认值就是 padding-box */
}
.box.padding-box { background-origin: padding-box; } /* 默认:内边距左上角 */
.box.border-box { background-origin: border-box; } /* 边框左上角 */
.box.content-box { background-origin: content-box; } /* 内容区左上角 */
</style>
</head>
<body>
<div class="box padding-box">padding-box(默认值):原点在“内边距”左上角</div>
<div class="box border-box">border-box:原点在“边框”左上角</div>
<div class="box content-box">content-box:原点在“内容区”左上角</div>
</body>
</html>关键行与易错点
padding: 30px; border: 6px dashed #900;必须加上,否则三个值的差别肉眼看不出来——原点在内边距、边框、内容区三者是三个不同的位置。background-origin的默认值是padding-box,不是border-box,也不是content-box。background-position: 16px 16px;是相对“原点”计算的:改了origin,同样的 16px 会跑到不同位置,这正是这个属性的意义。- 一旦打开
background-repeat,你会发现边框上也有背景图,那是重复出来的(向上向左也会重复),不是原点在边框上。 - 易混点:
background-origin里的border-box / content-box和box-sizing里的同名值完全不是一个意思,别联想。 - 多数场景下只调位置用
background-position就够了,background-origin通常要和其他背景属性配合使用。
示例 2:background-clip —— 背景图像显示区域
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>background-clip 背景图像显示区域</title>
<style>
body { font-family: "Microsoft YaHei", sans-serif; }
.box {
width: 600px;
height: 400px;
padding: 30px;
border: 6px dashed #900;
margin-bottom: 30px;
background-image: url("./images/bg03.jpg");
background-repeat: repeat; /* 打开重复,能更清楚看到“被裁掉”的范围 */
background-origin: padding-box; /* 原点保持默认 */
/* background-clip 默认值就是 border-box */
}
.box.border-box { background-clip: border-box; } /* 默认:边框及以内 */
.box.padding-box { background-clip: padding-box; } /* 内边距及以内,边框上没有 */
.box.content-box { background-clip: content-box; } /* 只有内容区 */
</style>
</head>
<body>
<div class="box border-box">border-box(默认值):边框及边框以内都显示</div>
<div class="box padding-box">padding-box:内边距及以内,边框被裁掉</div>
<div class="box content-box">content-box:只显示在内容区</div>
</body>
</html>关键行与易错点
background-clip的默认值是border-box(注意:clip的默认值不是padding-box,而origin的默认值是padding-box,两个属性的默认值不一样,最容易记混)。- 显示范围再小也不会超出元素本身,外边距上永远不会有背景。
origin和clip是互相独立的两个属性:只改clip时,背景图的位置不会移动,只是四周被裁掉;只改origin时,显示范围不变,只是起点移动了。- 改
clip后,原本看到的背景图会整体“缩小到可见区域”,它不会重新排列或缩放。 - 属性值顺序可以随意写在复合属性
background中,但初学时建议用单独子属性,避免歧义。
示例 3:background-clip: text —— 背景图填充文字
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>background-clip: text 背景图填充文字</title>
<style>
body { margin: 0; font-family: "Microsoft YaHei", sans-serif; }
.text-box {
font-size: 300px; /* 字必须够大,背景图才“够铺” */
font-weight: bold; /* 粗体,效果更明显 */
text-align: center;
line-height: 500px;
background-image: url("./images/bg04.jpg");
background-position: center;
color: transparent; /* 文字必须透明,否则黑字会挡住背景 */
-webkit-background-clip: text; /* Chrome / Edge / Opera 等内核需要私有前缀 */
background-clip: text; /* Firefox / Safari 不需要前缀 */
}
</style>
</head>
<body>
<div class="text-box">高小乐</div>
</body>
</html>关键行与易错点
color: transparent;是关键一步,不写透明就看不到效果——黑色文字会把背景图挡住,看起来“没生效”。-webkit-background-clip: text;这一行必须写,Chrome / Edge 等内核浏览器不认不带前缀的background-clip: text;同时再写一行不带前缀的留给 Firefox / Safari,两行都要保留。font-size要足够大(这里 300px),背景图才能覆盖出可见的文字形状;line-height配合撑开高度。- 效果是浏览器帮你“裁”出来的,不需要额外的
overflow、mask等处理。 - 这个值兼容性相对特殊,实际项目里建议把带前缀和不带前缀的声明都写上,顺序上前缀版在前、标准版在后。
常见错误
现象:改了
background-origin,以为背景显示范围也跟着变了。
原因:把“定位原点”和“显示区域”混为一谈。
修法:分别验证:origin只看position的坐标零点,clip只看背景可见边界,二者独立设置。现象:
background-clip: text不生效,或整块背景消失。
原因:Chrome 需要私有前缀,且文字颜色未透明时文字会挡住背景。
修法:同时写-webkit-background-clip: text和标准写法,并设置color: transparent。现象:用
:target切换图片时,首图一直显示,或点击后两张图叠在一起。
原因:默认用display:block显示首图后,:target无法撤销首图的显示;简单显示切换不互斥。
修法:默认只保留一张显示,或用绝对定位让大图重叠,再让:target提升对应图片层级;也可改用:checked方案。现象:
:checked切换图片时,可以同时选中多张小图。
原因:多个radio没有设置相同name,不构成单选组。
修法:统一name,并确保label for与input id一一对应,需要默认项时加checked。现象:商品网格每行最后一个仍带右外边距,导致换行错位。
原因:选择器排号或每行数量没对齐,或误把nth-child当成nth-of-type使用。
修法:确认每行 4 个后使用:nth-child(4n){margin-right:0},并检查兄弟结构是否混入其他元素。现象:鼠标悬停加阴影和上移后,元素发生抖动或布局跳动。
原因:用margin、top等改变文档流位置。
修法:用相对定位top:-2px或transform做位移,阴影用box-shadow,避免影响布局。
练习
下载列表图标自动匹配:用属性选择器为
.downloads a[href$=".doc"]、.xls、.ppt分别设置精灵图background-position,要求使用no-repeat、右侧定位和padding-right留出图标位置;新增同后缀条目时样式应自动匹配。:target图片切换改造:实现 5 张大图与 5 个缩略图切换,要求默认显示第一张,点击任意缩略图只显示对应大图。写出关键选择器,并说明为什么不能简单依赖默认display:block的首图。:checked图片切换改造:用radio + label + img重做上一题,要求默认选中第 3 张,点击缩略图单选切换,单选框隐藏。写出name、id、for、:checked +的关键写法。商品网格悬停效果:16 个商品项,每行 4 个,容器宽 988,间距 20。要求用
:nth-child(4n)去掉每行最后一项右外边距;鼠标悬停时加阴影并上移 2px,且不能引起布局抖动。背景新增属性综合:给一个
600×400、padding:30px、border:6px dashed的盒子设置背景图,分别把background-origin设为content-box、background-clip设为padding-box,说明background-position:16px 16px时原点与可见区域分别在哪;另做一个background-clip:text标题,兼容 Chrome 与 Firefox。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 回顾 | 11:55 |
| 2 | 作业讲解-属性选择器练习 | 10:09 |
| 3 | 作业讲解-点击切换图片-target伪类实现 | 11:10 |
| 4 | 作业讲解-点击切换图片-checked伪类实现 | 07:31 |
| 5 | 作业讲解-鼠标悬停显示阴影 | 06:26 |
| 6 | 修改背景图像定位的原点 | 07:35 |
| 7 | 背景图像的显示区域 | 10:03 |
小结
background-origin管坐标原点,background-clip管可见边界,二者独立,不能互相替代。- 背景默认绘制到
border-box,repeat时边框上出现背景图是正常现象,不是clip失效。 background-clip:text必须配合透明文字,并为 Chrome 保留私有前缀写法。:target方案的关键是处理“默认首图”和“目标图”的互斥,简单显示切换容易叠图。:checked方案更适合需要默认选中和单选互斥的场景,radio的name与label for缺一不可。- 用
:nth-child(4n)去右间距前,先确认每行数量和兄弟结构,不要混用nth-of-type。 - 悬停位移优先用定位或
transform,不要改margin造成布局抖动;阴影统一用box-shadow。 - 属性选择器做文件类型图标时,要检查后缀大小写、路径和实际
href,新增条目才能稳定自动匹配。