Skip to content

小兔鲜儿(一) ​

本页对应 小兔鲜儿,共 8 段视频,约 1 小时 15 分。

学习目标 ​

  • 能独立完成轮播图左右按钮的 HTML 结构与 CSS 布局,使用绝对定位、子绝父相、top: 50% 与 translateY(-50%) 实现垂直居中,并通过浏览器验证按钮位置正确。
  • 能使用并集选择器抽取左右按钮公共样式,分别设置左右按钮差异属性,并说明 left 与 right 同时存在时的层叠与结果冲突。
  • 能使用 ol/ul + li + flex 完成底部小圆点布局,设置尺寸、间距、圆角、半透明背景、鼠标小手及 active 高亮,并解决选择器权重导致的样式不生效问题。
  • 能使用 display: none/block 与 visibility: hidden/visible 实现元素显示隐藏,区分两者是否占位,并能用 banner:hover 后代选择器控制左右按钮显示与隐藏。
  • 能按规范搭建小兔鲜 PC 项目目录,正确放置 css、images、uploads、fonts 等素材,创建并引入初始化 CSS 与首页 CSS,完成页面基础结构。
  • 能编写并优化网页 TDK 三大标签,正确设置 title、description、keywords,并说明其在搜索引擎结果页中的作用与验证方式。

知识点 ​

先看效果与代码结构 ​

这一节要解决的是“元素怎么显示、怎么隐藏”。轮播图里左右箭头默认看不见,鼠标经过大盒子才出现;调试布局时又常要把某个盒子临时隐藏。这里有两个关键区别:隐藏后占不占位置。先保留本节代码:

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>
    .box1 {
      width: 200px;
      height: 200px;
      background-color: pink;
      /* 隐藏盒子: display 不占位置   none  block(常用)*/
      /* display: none; */
      /* 隐藏盒子 visibility 占位置  hidden  visible */
      visibility: hidden;
      /* visibility: visible; */
    }

    .box2 {
      /* 绝对定位 */
      /* position: absolute; */
      /* 记得加上边偏移 */
      /* top: 0; */
      width: 200px;
      height: 200px;
      background-color: purple;
    }
  </style>
</head>

<body>
  <div class="box1"></div>
  <div class="box2"></div>

</body>

</html>

显示与隐藏效果对比图

display:none 与 display:block:隐藏后不占位 ​

为什么需要:轮播图左右按钮初始要隐藏,鼠标经过再显示;有时布局里某个盒子暂时不需要,也不希望它继续占着一块空白。
怎么想:display:none 是让元素不显示,并且不占位置;恢复显示常用 display:block。转写稿里强调,block 本来有“转成块元素”的意思,但在这里我们主要借它表达“显示出来”,习惯上和 none 成对使用。
怎么做:把 .box1 里的 visibility:hidden 注释掉,打开 display:none。刷新后粉色盒子消失,紫色盒子会上移,因为粉色盒子不再占位。用调试工具检查还能看到 .box1 标签仍在,只是不参与显示。
易错点:display:none 后不占位,下面的盒子会补上来;不要把它和“占位隐藏”混为一谈。转写稿还调试了 .box2:只写 position:absolute 而不写边偏移,紫色盒子不会立刻压住粉色盒子;补上 top:0 后才移动到指定位置。也就是说,绝对定位要记得配边偏移。

visibility:hidden 与 visible:隐藏但保留位置 ​

为什么需要:有些场景希望元素看不见,但原来的布局位置还要保留,不能让别人挤上来。
怎么想:visibility:hidden 表示隐藏,但元素仍占位置;visibility:visible 表示恢复可见。
怎么做:当前笔记代码启用的就是 visibility:hidden。刷新后 .box1 看不见,但 .box2 不会上移,说明粉色盒子的位置还在。把 visibility 改成 visible,粉色盒子重新出现。
易错点:它和 display:none 最大区别就是占不占位置。转写稿也明确说,实际开发中更常用 display:none 和 display:block,visibility 相对少用;但面试或调试时要能说清两者区别。

用 :hover 控制左右按钮显示隐藏 ​

为什么需要:轮播图左右箭头默认隐藏,鼠标进入 banner 区域才显示,离开又隐藏。
怎么想:先分清“鼠标经过谁”和“谁显示”。转写稿的经验是:鼠标经过最大的盒子 banner,让 banner 里面的左右按钮显示,而不是让 banner 自己隐藏。
怎么做:可先给左右按钮写 display:none,再用后代选择器配合 :hover:

css
.prev,
.next {
  display: none;
}

.banner:hover .prev,
.banner:hover .next {
  display: block;
}

易错点:合并选择器时,逗号前后都要写完整。转写稿调试过错误写法 .banner:hover .prev, .next,这样逗号后的 .next 不受 :hover 约束,右侧按钮可能一直显示或被后面的样式层叠掉。正确写法是 .banner:hover .prev, .banner:hover .next。另外,转写稿里说的“病级选择器”应纠正为“并集选择器”,逗号表示“和”。

小结与调试习惯 ​

显示隐藏先问一句:隐藏后要不要占位置? 不占位置用 display:none,恢复常用 display:block;占位置用 visibility:hidden,恢复用 visible。写 :hover 时先明确“经过谁、谁变化”,选择器逗号要检查前后是否完整。调试时用检查工具看标签是否还在、下面盒子有没有上移,就能快速判断用的是哪一种隐藏。

先看项目目录:为什么需要 ​

做小兔鲜 PC 首页前,先把目录搭好,不是为了“好看”,而是为了后面写 HTML、CSS、图片和字体图标时知道东西放哪里。转写稿里先建 xtx-pc 大文件夹,再把素材里的 images、uploads、iconfont、css 复制进去,并在根目录准备 index.html。怎么想:先按“固定图片、上传图片、图标、样式、页面”五类分。怎么做:建立如下结构,并保留笔记图片。

小兔鲜PC项目目录结构

  • xtx-pc
    • images 文件夹:存放固定使用的图片素材,例如:logo、样式修饰图等等
    • uploads 文件夹:存放非固定使用的图片素材,例如:商品图、宣传图需要上传的图片
    • iconfont 文件夹:字体图标素材
    • css 文件夹:存放 CSS 文件(link 标签引入)
      • base.css:基础公共样式
      • common.css:各个网页相同模块的重复样式,例如:头部、底部
      • index.css:首页 CSS 样式
    • index.html:首页 HTML 文件

易错点:不要把商品图、宣传图混进 images;iconfont 是字体图标素材目录,不是普通图片目录;文件名和路径大小写要一致。

各文件夹怎么分工:为什么需要→怎么想→怎么做→易错点 ​

为什么需要:素材一多,如果全堆在根目录,后面找 logo、找商品图、找图标会很乱。怎么想:固定不变的装饰图放 images,需要上传或替换的商品图放 uploads,字体图标单独放 iconfont,CSS 统一放 css。怎么做:按笔记中的五类目录整理,index.html 放项目根目录。易错点:uploads 不是“上传功能代码”,而是存放非固定图片素材;common.css 放头部、底部等重复模块,不要把所有首页样式都塞进去。

CSS 为什么要分层:为什么需要→怎么想→怎么做→易错点 ​

为什么需要:基础样式、公共模块样式、首页样式混在一个文件里,后期改头部可能误伤首页。怎么想:base.css 做初始化,common.css 放各页面重复模块,index.css 只写首页。怎么做:在 css 文件夹中准备 base.css、common.css、index.css;转写稿里也演示了先放初始化 base.css,再新建 index.css。易错点:base.css 要最先引入,否则初始化可能覆盖后续样式;common.css 不是每个项目都必须有,但本节笔记明确要求保留。

引入样式表:为什么需要→怎么想→怎么做→易错点 ​

为什么需要:HTML 只写结构,颜色、布局、图标都要靠 CSS;不引入样式表,页面就是“裸标签”。怎么想:先引字体图标,再引初始化,再引公共样式,最后引首页样式。转写稿调试时先验证 base.css 和 index.css 是否生效,字体图标等用到再补;本节最终按笔记保留完整四行。怎么做:在 index.html 的 head 中写:

html
<!-- 引入字体图标css文件 -->
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <!-- 初始化的css文件 -->
  <link rel="stylesheet" href="./css/base.css">
  <!-- 引入公共样式 -->
  <link rel="stylesheet" href="./css/common.css">
  <!-- 引入index css 文件 -->
  <link rel="stylesheet" href="./css/index.css">

易错点:link 要放 head 里;href 路径别写错,常见是 ./css/...;顺序别把 index.css 放到 base.css 前面;改完保存后刷新浏览器验证。

调试与收尾:为什么需要→怎么想→怎么做→易错点 ​

为什么需要:目录和引入写完后必须验证,否则后面布局出错很难判断是结构问题还是样式没加载。怎么想:先看页面是否贴边、初始化是否生效,再看控制台或浏览器检查样式是否加载。转写稿里用“写 123、保存、打开页面看是否贴边”验证初始化成功。怎么做:保存 index.html,浏览器打开,确认 base.css、index.css 已生效;字体图标用到时再检查 iconfont.css 是否引入。易错点:不要只改文件不保存;不要漏掉 common.css;如果样式不生效,优先查路径、文件名、引入顺序。

SEO与TDK总览:先弄明白为什么要写 ​

为什么需要:做网站不只是“能打开”,还希望别人搜相关词时能看见我们。转写稿里说得很直白:SEO 就是搜索引擎优化,目标是提升网站在百度等搜索引擎中的排名。常见方法包括竞价排名(花钱)、把网页做成 html 后缀、标签语义化,以及在合适的地方使用合适的标签。

怎么想:前端不负责竞价排名,但要把页面结构写规范,并把 SEO 人员提供的文字准确写进网页头部。这里最核心的是 TDK:T 是 title(网页标题),D 是 description(网页描述),K 是 keywords(网页关键词)。

怎么做:先建立“头部要给搜索引擎读”的意识,再在 <head> 中写 title 和两个 meta 标签。

易错点:不要把 TDK 写进页面正文;不要以为 keywords 会直接显示给用户看;title 也不是页面里的 <h1>。

网页头部SEO三大标签示意图

title:网页标题不是随便起的 ​

为什么需要:title 是搜索结果里最显眼的标题。转写稿中课上用京东、小米查看源代码,发现正规网站都有 title;在百度搜索时,搜索结果第一行标题就对应页面 title。

怎么想:title 一般写成“网站名 + 短横线 + 网站亮点/特色”。笔记里的写法是“小兔鲜儿-新鲜、惠民、快捷!”,不是“小兔鲜儿首页制作”。

怎么做:在 <head> 里写 <title>,把 SEO 提供的标题原样放进去。

易错点:不要漏写;不要把“首页制作”这类开发备注当标题;不要和正文标题混为一谈。

description与keywords:给搜索引擎看的说明和关键词 ​

为什么需要:description 是网页描述,转写稿中说明它会在搜索结果摘要区域体现;keywords 是网页关键词,用来概括网站涉及的内容,如生鲜、服装、家电、电商、购物等。

怎么想:description 要写成一句完整、自然的介绍;keywords 用英文逗号分隔多个词。它们都通过 <meta> 的 name 和 content 来描述。

怎么做:保留笔记中的代码,写在 <head> 内:

html
<!-- meta:desc -->
<meta name="description" content="小兔鲜儿官网,致力于打造全球最大的食品、生鲜电商购物平台。">
<!-- meta:kw -->
<meta name="keywords" content="小兔鲜儿,食品,生鲜,服装,家电,电商,购物">
<title>小兔鲜儿-新鲜、惠民、快捷!</title>

易错点:description、keywords 是 meta 单标签,不要写成成对标签;name 和 content 不要拼错;关键词之间用英文逗号;不要堆砌无关关键词;三大标签都要放在 <head> 中。

调试与验证:用源代码和搜索页对照 ​

为什么需要:只看代码容易漏写,必须验证头部标签是否真的进入页面。

怎么想:转写稿中的调试思路是:打开京东、小米等正规网站,右击查看网页源代码,检查 title、description、keywords 是否存在;再结合百度搜索结果观察 title 和 description 的展示位置。

怎么做:写完小兔鲜儿页面后,在浏览器中查看源代码,确认 <head> 内出现三大标签;再刷新页面,标题栏应显示“小兔鲜儿-新鲜、惠民、快捷!”。

易错点:如果标题栏没变,先检查是否写在了 <head> 内、标签是否闭合、是否被注释掉。TDK 是网页头部的 SEO 基础,先写对,再谈优化。

说明与本节范围 ​

本节笔记主题是 Favicon 图标。需要说明的是:提供的转写稿主要记录轮播图左右按钮、显示隐藏、小兔鲜结构搭建等内容,并没有出现 Favicon 的推导或调试片段。为避免编造,下面只依据本节笔记扩写 Favicon 部分,不把无关的轮播图内容硬塞进来。

一、Favicon 是什么 ​

为什么需要:网页需要一个小图标来增加辨识度,这个图标会出现在浏览器标题栏附近,让用户更容易认出当前网站。

怎么想:先明确它的名字和用途——Favicon 就是网页图标,常见文件名是 favicon.ico。它不是页面正文内容,而是网站的标识性资源。

怎么做:认识笔记中的效果图:

网页标题栏中的 Favicon 图标

易错点:不要把 Favicon 当成页面里可见的普通图片来布局;它的主要作用是站点标识,不是内容图片。

二、图标文件放在哪里 ​

为什么需要:图标文件需要有明确、稳定的存放位置,页面引入时才好写路径。

怎么想:笔记明确说,图标文件 favicon.ico 一般存放到网站的根目录里面。先确定文件位置,再写引入代码,路径才不容易乱。

怎么做:按笔记要求,把 favicon.ico 放到网站根目录。示意如下:

favicon.ico 一般放在网站根目录

易错点:不要随意改文件名或放错目录;本节强调的文件名是 favicon.ico,位置是一般放到网站根目录。

三、HTML 中怎么引入 ​

为什么需要:只把图标文件放进目录还不够,还要通过 HTML 的 link 标签告诉浏览器去哪里找这个图标。

怎么想:笔记给出的写法已经包含关键信息:rel 说明图标关系,href 指向文件,type 说明类型。照笔记保留即可。

怎么做:使用下面这段代码:

html
<!-- link:favicon -->
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">

易错点:href 要和实际文件位置对应;本节代码中写的是 favicon.ico,对应前面说的根目录存放方式。不要漏写 rel、href、type 这些属性。

四、检查与常见问题 ​

为什么需要:Favicon 很小,写错后不一定有明显报错,所以需要按笔记逐项核对。

怎么想:先查文件是否存在、文件名是否为 favicon.ico,再查 HTML 中是否按笔记写了 link 代码,最后看浏览器标题栏附近是否出现图标。

怎么做:把文件放到根目录,保留笔记中的 link 代码不变,再刷新页面观察效果。

易错点:常见问题是文件名写错、路径写错、代码属性漏写,或者把图标文件放到了非预期目录。本节没有提供额外的调试命令,因此检查时以“文件名、根目录、link 代码”三处为主,不编造不存在的调试步骤。

五、本节小结 ​

Favicon 是网页图标,用来增加网站辨识度;文件一般是 favicon.ico,通常放在网站根目录;页面中用 link 标签引入。学习这一节最重要的是记住三件事:文件名、存放位置、引入代码。先按笔记把这三步做对,再谈效果检查,避免一上来就改代码或混入无关内容。

版心是干什么的 ​

版心可以理解为页面内容的“主容器”。大屏下如果内容铺满整个浏览器,文字会拉得很长、图片会乱跑,阅读和布局都不稳定。所以设计稿通常会规定一个固定内容宽度,让主体内容居中,两侧自然留白。这个固定宽度、水平居中的容器,就是版心。

怎么想:先看设计稿给的内容宽度,本节是 1240px;再写一个公共类 .wrapper,哪个区域需要居中,就给哪个区域加这个类。
怎么做:块级元素设置固定宽度,再用 margin: 0 auto 让左右外边距自动平分剩余空间。

css
/* 版心 */
.wrapper {
  margin: 0 auto;
  width: 1240px;
}

易错点:margin: 0 auto 只负责水平居中,不负责垂直居中;元素没有宽度时,auto 没有剩余空间可平分;行内元素要先转成块级或行内块;浮动、绝对定位元素不适用这种普通流居中方式。

为什么放在 common.css ​

版心不是某一个模块专用,而是多个页面、多个区域都会复用的公共规则。转写稿后面做轮播图、按钮、小圆点时,反复提到“把公共部分抽取出来,只写一次”,这就是公共样式的维护思路。把 .wrapper 放进 common.css,页面里统一加类即可,避免每个模块重复写 width 和 margin。

怎么做:项目里先引入初始化样式,再引入 common.css,最后引入具体页面样式。这样公共规则先生效,页面样式再做局部覆盖。
易错点:不要在每个模块里各写一套版心宽度;否则设计稿一改,就要到处改。公共类名也要避免和具体模块冲突。

颜色变量统一管理 ​

除了版心,本节还把常用颜色声明成 CSS 变量。这样灰色、绿色只维护一份,后面按钮、文字、边框使用时直接取变量,改色时不用全文件搜索替换。

css
/* 声明颜色变量 */
:root {
  /* 灰色变量 */
  --hui: #a1a1a1;
  /* 绿色 */
  --lv: #00BE9A;
}

怎么想::root 代表文档根元素,在这里定义的变量是全局可用的;变量名以 -- 开头,使用时写 var(--变量名)。
怎么做:例如 color: var(--hui);、background: var(--lv);。
易错点:变量名不要写中文;var() 里的变量名要和声明时完全一致;变量只是“值的别名”,不是新属性。

调试版心与公共样式 ​

版心不居中时,不要凭感觉改。转写稿里排查 active 颜色不生效时,是先打开调试工具看哪条规则覆盖,再通过提高选择器权重解决;版心也一样:先选中元素,看计算后的 width、display、margin,确认宽度是否真的是 1240px,左右 margin 是否被其他样式覆盖,元素是否被浮动或定位影响。

转写稿里常把 banner 说成“班”、把 active 说成“XT”,这里统一按代码名写,避免同音字误导。公共样式最怕“看起来写了但没生效”,所以调试顺序是:先看元素是否存在、是否有宽高,再看样式是否被覆盖,最后才改代码。

本节要做什么 ​

本节笔记用一个小页面演示 CSS 变量的两个核心动作:先在 :root 里声明变量,再在普通选择器里用 var() 使用变量。完整代码如下,建议先原样运行,再逐行修改观察效果。

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>
    /* 1. 声明变量 */
    :root {
      --myColor: blue;
    }

    /* 2. 使用变量 */
    .box {
      color: var(--myColor);
    }

    .box1 {
      background-color: var(--myColor);
    }

    .box2 {
      border: 1px solid var(--myColor);
    }
  </style>
</head>

<body>
  <div class="box">文字</div>
  <div class="box1">文字</div>
  <div class="box2">文字</div>
</body>

</html>

为什么需要 CSS 变量 ​

为什么需要: 当同一个颜色、间距、圆角在多个选择器里反复出现时,直接写死会导致改一处漏一处。CSS 变量把“值”集中到一个地方,使用时只引用变量名,后续改值即可统一生效。

怎么想: 把变量理解成“给某个 CSS 值起名字”。名字以 -- 开头,值可以是颜色、长度等;使用时通过 var(--名字) 取出来。

怎么做: 笔记中把 --myColor: blue; 放在 :root 中,因此它是全局可用的;.box、.box1、.box2 分别把该变量用于文字颜色、背景色、边框颜色。

易错点: 变量名必须以 -- 开头;使用时要写 var(--myColor),不能只写 --myColor;变量名区分大小写。

怎么想:先声明,再使用 ​

为什么需要: CSS 变量不是“写了名字就自动存在”,它必须先在某个作用域里声明,后面的规则才能取到值。转写稿里讲定位时反复强调“先告诉它是什么定位,再告诉它去哪,否则盒子不动”,迁移到变量这里就是:先声明变量,再使用变量,否则取不到值。

怎么想: 先确定变量放在哪一层。放在 :root 里,页面里大部分元素都能用;放在某个选择器里,则只对该选择器及其后代生效。

怎么做: 本节采用最稳妥的写法:统一在 :root 中声明,再在需要的地方用 var() 引用。

易错点: 不要把声明写进 body 的某条普通规则里却期待所有元素都能用;也不要把 :root 写成 .root,前者是根元素伪类,后者是类选择器,含义不同。

怎么做:声明与使用分离 ​

为什么需要: 把声明和使用分开,才能体现变量的价值。笔记中的声明只有一处,使用有三处,改 blue 为其他颜色时,三处会一起变化。

怎么想: 声明区只负责“定义值”,使用区只负责“引用值”。这样结构清晰,也方便调试。

怎么做: 按笔记保留三段使用:color、background-color、border。可以手动把 blue 改成 red,观察三个盒子是否同步变化。

易错点: border: 1px solid var(--myColor); 中 var() 是值的一部分,不要漏掉分号;如果变量拼错,浏览器不会报语法大错,而是该条声明失效,需要打开开发者工具检查。

调试过程与易错点 ​

为什么需要: 转写稿里多次通过开发者工具查看样式是否被覆盖,并纠正了“子爵富相”应为“子绝父相”、“病级选择器”应为“并集选择器”等同音字。变量调试同样要借助开发者工具,而不是只靠猜。

怎么想: 变量不生效时,按顺序查:变量是否声明、作用域是否覆盖、名字是否拼错、使用处是否写了 var()、该条 CSS 是否被后面的规则覆盖。

怎么做: 在浏览器中选中元素,查看计算样式;临时把 var(--myColor) 改成固定颜色,判断是变量问题还是整条规则问题。

易错点: 不要因为“颜色没变”就重复写多条相同规则;先确认变量是否取到值。若需要回退值,可使用 var(--myColor, red),但本节笔记未使用,初学阶段先掌握基本声明与引用即可。

小结 ​

本节要记住两句话:变量在 :root 中用 --名字: 值; 声明,在普通规则中用 var(--名字) 使用。先声明、后使用,改一处、统一生效。转写稿主要内容是轮播图按钮布局,并未讲解 CSS 变量,因此本节不把轮播图细节混入;只借用其中“先写必要条件再写结果”和“用开发者工具查覆盖”的调试意识。

代码示例 ​

示例一:显示和隐藏(display 与 visibility 的区别) ​

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>
    .box1 {
      width: 200px;
      height: 200px;
      background-color: pink;
      /* 隐藏盒子: display 不占位置   none  block(常用)*/
      /* display: none; */
      /* 隐藏盒子 visibility 占位置  hidden  visible */
      visibility: hidden;
      /* visibility: visible; */
    }

    .box2 {
      /* 绝对定位 */
      /* position: absolute; */
      /* 记得加上边偏移 */
      /* top: 0; */
      width: 200px;
      height: 200px;
      background-color: purple;
    }
  </style>
</head>

<body>
  <div class="box1"></div>
  <div class="box2"></div>
</body>

</html>

要点解释

  • display: none 隐藏元素,不占位置,后面的紫色盒子会顶上来;display: block 让它重新显示(顺便具备块元素特性,所以通常说“隐藏用 none、显示用 block”)。
  • visibility: hidden 隐藏元素但保留位置,紫色盒子不会上来;visibility: visible 恢复显示。
  • 实际开发(含后面 JS 控制)优先用 display 这一组,visibility 很少用。
  • 易错点:position: absolute 只写定位不写边偏移(top/left/bottom/right),盒子不会跑到任何地方,还待在原地等着——所以“加了绝对定位一定记得给偏移量”。这段代码里绝对定位相关行被注释掉了,可以取消注释对比观察。

示例二: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>
    /* 1. 声明变量 */
    :root {
      --myColor: blue;
    }

    /* 2. 使用变量 */
    .box {
      color: var(--myColor);
    }

    .box1 {
      background-color: var(--myColor);
    }

    .box2 {
      border: 1px solid var(--myColor);
    }
  </style>
</head>

<body>
  <div class="box">文字</div>
  <div class="box1">文字</div>
  <div class="box2">文字</div>
</body>

</html>

要点解释

  • 变量声明必须写在 :root 里(根元素),变量名以 -- 开头,如 --myColor: blue;。
  • 使用时必须用 var(--变量名) 包起来,直接写 --myColor 是不生效的。
  • 一个变量可以被颜色、背景色、边框等任意属性复用,改一处全站生效——这就是项目 common.css 里声明 --hui、--lv 的原因。
  • 易错点:变量名区分大小写,var() 里的名字和声明处必须一模一样;变量声明位置若不在 :root,只对那个选择器及其后代生效。

示例三:轮播图左右按钮 + 鼠标经过显示隐藏 ​

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>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    li {
      list-style: none;
    }

    .banner {
      /* 子绝父相:给父亲加相对定位 */
      position: relative;
      width: 1240px;
      height: 500px;
      margin: 100px auto;
      background-color: #ccc; /* 代替轮播图片 */
      overflow: hidden;
    }

    /* 左右按钮的公共部分:并集选择器抽取相同代码 */
    .prev,
    .next {
      position: absolute;
      top: 50%;
      /* 水平不动,沿 Y 轴上移自身高度的一半 */
      transform: translateY(-50%);
      width: 20px;
      height: 30px;
      background-color: rgba(0, 0, 0, .4);
      color: #fff;
      text-align: center;
      line-height: 30px;
      text-decoration: none;
      /* 刚开始隐藏,鼠标经过再显示 */
      display: none;
    }

    .prev {
      left: 0;
      border-radius: 0 15px 15px 0;
    }

    .next {
      right: 0;
      border-radius: 15px 0 0 15px;
    }

    /* 鼠标经过 banner,里面的左右按钮显示 */
    .banner:hover .prev,
    .banner:hover .next {
      display: block;
    }
  </style>
</head>

<body>
  <div class="banner">
    <a href="javascript:;" class="prev">&lt;</a>
    <a href="javascript:;" class="next">&gt;</a>
  </div>
</body>

</html>

要点解释

  • 空链接写 href="javascript:;",而不是 #:# 会跳回页面顶部,而左右按钮只是给 JS 做交互用,不需要跳转。
  • 按钮用 position: absolute 压住图片,父亲 .banner 必须加 position: relative(子绝父相),否则按钮会跑到视口上定位。
  • top: 50% + transform: translateY(-50%) 实现垂直居中;translate 里两个值必须用逗号隔开,只动 Y 轴用 translateY(-50%) 更简洁。
  • 圆角顺时针写:左侧按钮 0 15px 15px 0,右侧按钮反过来 15px 0 0 15px,半径取高度 30px 的一半 15px。
  • 半透明背景用 rgba(0,0,0,.4),纯黑三个 0 加上透明度。
  • 公共样式用并集选择器 .prev, .next 抽取一次,各自不同的(left / right、圆角)写在下面单独覆盖,减少重复代码。
  • 显示隐藏的易错点:鼠标经过的是 .banner,变的是它里面的按钮,所以要写后代关系 .banner:hover .prev。不能写成 .banner:hover, .next——逗号前是一个整体、逗号后是另一个整体,.next 前面就没有 hover 条件了,右侧按钮会一开始就显示不出来/一直显示。
  • 另一个易错点:千万不要写 .banner:hover { display: none; },那样整个轮播大盒子都没了,应该是让里面的“孩子”变化。

常见错误 ​

1. 写了 position: absolute 盒子却没动、也没压住别人

  • 现象:加了绝对定位,元素还在原位待着,页面上看不出变化。
  • 原因:只声明了定位方式,没给边偏移(top/left/right/bottom),浏览器不知道往哪放,就在原地等第二句。
  • 修法:绝对定位必须配边偏移,如 top: 50%; left: 0;;轮播底部圆点忘记写 bottom: 20px 就是这个问题。

2. 鼠标移入 banner 后只有左按钮出现,右按钮一直显示或一直不显示

  • 现象:想用一条并集选择器同时控制左右按钮,结果右侧按钮不按预期隐藏/显示。
  • 原因:写成 .banner:hover .prev, .next { display: block; },逗号后是一个独立完整的选择器,.next 前面没有 :hover 前缀,等于无条件常显。
  • 修法:逗号两侧都要写完整,.banner:hover .prev, .banner:hover .next;或拆成两条分别写。

3. 左右按钮抽公共样式后,右侧按钮跑到左边去了

  • 现象:把 left / right 一起提到并集选择器里,右侧按钮位置错误。
  • 原因:同一盒子同时有 left 和 right 时只执行 left(先左后右),样式不冲突但结果冲突。
  • 修法:position、width/height、background、border-radius 之类可提公共;left 与 right 必须各留在 .prev / .next 里。

4. 给 li 加 .active 高亮不生效

  • 现象:类名明明加上了,当前小圆点颜色不变。
  • 原因:被更高权重的 .banner ol li 覆盖,.active 单独写的权重不够。
  • 修法:带上父级限定提高权重,如 .banner ol li.active 或 .banner .active;用调试工具查看被谁划掉再动手。

5. 底部小圆点的样式串到轮播图片列表上

  • 现象:下面写了 ol li 的宽高背景,上面图片列表的 li 全变小方块/样式错乱。
  • 原因:banner 里已有 ul li、ol li 两组 li,选择器范围没限定死,后代选择器命中所有后代。
  • 修法:每处都带父级容器限定,如 .banner ol li、.banner ul li,不要写裸的 .banner li。

6. 点击左右按钮页面跳到顶部

  • 现象:点箭头整页滚回最上面。
  • 原因:href="#" 是空链接,默认行为是回到锚点顶部。
  • 修法:不需要跳转的交互按钮写 href="javascript:;"(原样照抄,不改其中字符)。

7. 用 visibility: hidden 隐藏后,后面的盒子没有上移

  • 现象:想隐藏一个块让下面的内容顶上来,结果原位留了个空洞。
  • 原因:visibility: hidden 保留占位,只是看不见。
  • 修法:需要让出位置用 display: none,恢复用 display: block;只有“保留布局位置地隐身”才用 visibility。

8. 字体图标不显示 / 显示成方块

  • 现象:按钮里只有一个方框或乱码。
  • 原因:漏引 iconfont.css,或类名只写了 icon-xxx 没带 iconfont,或误用了 unicode 方式。
  • 修法:<link> 引入 iconfont 的 css(放在 <style>/其他样式表之前),元素写 class="iconfont icon-xxx",并切到 Font class 方式复制。

练习 ​

  1. 按钮显隐:给轮播左右按钮加初始隐藏 + 鼠标移入 banner 显示、移出隐藏。要求用一条并集选择器同时控制两个按钮,并说明逗号两侧为什么都要带 :hover。

  2. 样式抽取:把左右按钮的公共样式用并集选择器抽出来,写出抽取后 .prev 与 .next 各自还需要保留哪几行,并解释 left / right 为什么不能提上去。

  3. 小圆点高亮:底部 5 个圆点,让第 3 个显示为高亮色。写出你的选择器,并说明如果只写 .active 会怎样、被谁覆盖。

  4. 两种隐藏对比:做上下两个 200×200 的盒子,分别用 display: none 和 visibility: hidden 隐藏第一个,截图/描述两种情况下第二个盒子的位置差异,并回答:后面用 JS 做轮播切换时你选哪一个,为什么。

  5. 页面头部补全:新建 xtx-pc 项目,写 index.html 头部:favicon、TDK 三大标签,并按正确顺序引入 iconfont.css、base.css、common.css、index.css,说明为什么顺序不能乱。

原视频对照 ​

#视频时长
1轮播图-左侧按钮开始12:29
2轮播图-左侧按钮结束05:29
3轮播图-右侧按钮10:30
4轮播图-底部小圆点写法13:22
5轮播图-显示和隐藏按钮11:34
6显示和隐藏07:10
7小兔鲜结构-搭建07:19
8TDK三大标签优化07:54

小结 ​

  1. 隐藏分两组:display: none / block 不占位、开发常用且是 JS 切换的主力;visibility: hidden / visible 保留占位,只用于“隐身不塌陷”的场景。
  2. 绝对定位是两步动作:声明 position: absolute 只是“身份”,必须补边偏移才会真正落位;同时记得给约束范围的父级加 position: relative(子绝父相)。
  3. 水平居中 left: 50% + translateX(-50%),垂直居中 top: 50% + translateY(-50%);translate 写两个值时第一个是 X、第二个是 Y,用逗号隔开,不能省参数。
  4. 相同代码用并集选择器抽取,只保留差异部分;但 left / right、top / bottom 这类“结果冲突”的属性必须分开写,同一盒子同时存在时只认前一个。
  5. 鼠标经过类效果先想清两件事:经过谁(写最大的容器)、谁变化(写容器里的目标子元素);并集选择器里逗号两侧都必须是完整选择器。
  6. 样式不生效先查权重,再查层叠顺序;提高权重最稳的做法是带上父级限定,而不是堆 !important。
  7. 项目起步顺序固定:建目录(images / uploads / iconfont / css / index.html)→ 放素材 → 按 iconfont → base → common → index 的顺序引入样式 → 写 TDK 与 favicon。
  8. 不需要跳转的交互按钮统一写 href="javascript:;",避免 # 造成的页面回顶。