Skip to content

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

课堂画面 2

课堂画面 3

课堂画面 4

课堂画面 5

课堂画面 6

代码示例 ​

示例 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 等处理。
  • 这个值兼容性相对特殊,实际项目里建议把带前缀和不带前缀的声明都写上,顺序上前缀版在前、标准版在后。

常见错误 ​

  1. 现象:改了 background-origin,以为背景显示范围也跟着变了。
    原因:把“定位原点”和“显示区域”混为一谈。
    修法:分别验证:origin 只看 position 的坐标零点,clip 只看背景可见边界,二者独立设置。

  2. 现象:background-clip: text 不生效,或整块背景消失。
    原因:Chrome 需要私有前缀,且文字颜色未透明时文字会挡住背景。
    修法:同时写 -webkit-background-clip: text 和标准写法,并设置 color: transparent。

  3. 现象:用 :target 切换图片时,首图一直显示,或点击后两张图叠在一起。
    原因:默认用 display:block 显示首图后,:target 无法撤销首图的显示;简单显示切换不互斥。
    修法:默认只保留一张显示,或用绝对定位让大图重叠,再让 :target 提升对应图片层级;也可改用 :checked 方案。

  4. 现象::checked 切换图片时,可以同时选中多张小图。
    原因:多个 radio 没有设置相同 name,不构成单选组。
    修法:统一 name,并确保 label for 与 input id 一一对应,需要默认项时加 checked。

  5. 现象:商品网格每行最后一个仍带右外边距,导致换行错位。
    原因:选择器排号或每行数量没对齐,或误把 nth-child 当成 nth-of-type 使用。
    修法:确认每行 4 个后使用 :nth-child(4n){margin-right:0},并检查兄弟结构是否混入其他元素。

  6. 现象:鼠标悬停加阴影和上移后,元素发生抖动或布局跳动。
    原因:用 margin、top 等改变文档流位置。
    修法:用相对定位 top:-2px 或 transform 做位移,阴影用 box-shadow,避免影响布局。

练习 ​

  1. 下载列表图标自动匹配:用属性选择器为 .downloads a[href$=".doc"]、.xls、.ppt 分别设置精灵图 background-position,要求使用 no-repeat、右侧定位和 padding-right 留出图标位置;新增同后缀条目时样式应自动匹配。

  2. :target 图片切换改造:实现 5 张大图与 5 个缩略图切换,要求默认显示第一张,点击任意缩略图只显示对应大图。写出关键选择器,并说明为什么不能简单依赖默认 display:block 的首图。

  3. :checked 图片切换改造:用 radio + label + img 重做上一题,要求默认选中第 3 张,点击缩略图单选切换,单选框隐藏。写出 name、id、for、:checked + 的关键写法。

  4. 商品网格悬停效果:16 个商品项,每行 4 个,容器宽 988,间距 20。要求用 :nth-child(4n) 去掉每行最后一项右外边距;鼠标悬停时加阴影并上移 2px,且不能引起布局抖动。

  5. 背景新增属性综合:给一个 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

小结 ​

  1. background-origin 管坐标原点,background-clip 管可见边界,二者独立,不能互相替代。
  2. 背景默认绘制到 border-box,repeat 时边框上出现背景图是正常现象,不是 clip 失效。
  3. background-clip:text 必须配合透明文字,并为 Chrome 保留私有前缀写法。
  4. :target 方案的关键是处理“默认首图”和“目标图”的互斥,简单显示切换容易叠图。
  5. :checked 方案更适合需要默认选中和单选互斥的场景,radio 的 name 与 label for 缺一不可。
  6. 用 :nth-child(4n) 去右间距前,先确认每行数量和兄弟结构,不要混用 nth-of-type。
  7. 悬停位移优先用定位或 transform,不要改 margin 造成布局抖动;阴影统一用 box-shadow。
  8. 属性选择器做文件类型图标时,要检查后缀大小写、路径和实际 href,新增条目才能稳定自动匹配。