主题
小兔鲜儿(二)
本页对应 小兔鲜儿,共 7 段视频,约 1 小时 9 分。
学习目标
- 能独立完成底部帮助模块的 DT/DD 结构样式,包括字号、间距、链接颜色、悬停下划线及字体图标定位。
- 能使用 Flex 布局将帮助模块各 DL 横向排列,并完成右侧二维码图片与说明文字的布局和尺寸控制。
- 能编写版权模块的 P、A、span 结构,实现链接分隔线、水平居中、行高、颜色及悬停变色效果。
- 能搭建首页 banner 的版心、UL、LI、A、IMG 结构,并设置高度、背景色和溢出隐藏。
- 能通过 Flex 与 UL 宽度百分比使轮播图片横向排列,并说明 overflow: hidden 的裁剪作用。
- 能使用绝对定位、伪元素、圆角、rgba 和 active 类完成小圆点布局及激活态效果,并设置鼠标指针样式。
知识点
结构:用 ul 作为轮播图轨道
为什么需要:banner 区域不是一张静态图,而是多张图组成轮播。后续要用 JS 切换图片时,最好把图片放在同一条“轨道”里,点击左右箭头或小圆点只移动轨道,而不是临时改每一张图的位置。
怎么想:一条轨道用 ul,每一张图用 li,图片外面包 a,这样图片本身可点击跳转。小圆点先不急着写,只留注释占位,避免结构一开始就混在一起。
怎么做:保留本节笔记结构,图片 alt 改成中文,方便说明图片内容:
html
<!-- 轮播图图片 -->
<ul>
<li><a href="#"><img src="./uploads/banner1.png" alt="轮播图图片"></a></li>
<li><a href="#"><img src="./uploads/banner1.png" alt="轮播图图片"></a></li>
<li><a href="#"><img src="./uploads/banner1.png" alt="轮播图图片"></a></li>
</ul>
<!-- 小圆点 -->易错点:不要把“小圆点”的 li 混进图片 ul 里;图片 alt 不要留空;src 路径要指向 uploads 下真实存在的图片。
横向排列:给 ul 加 flex
为什么需要:li 默认是块级元素,会一张一张竖着排。轮播图需要三张图横向组成一条轨道。
怎么想:让 li 在一行上,最直接的是给它们的父级 ul 加 display:flex。这样 ul 的子项会沿主轴横向排列。
怎么做:
css
.banner .wrapper>ul {
display: flex;
width: 300%;
/* width: 3720px; */
}易错点:只写 display:flex 还不够。转写稿里调试时发现,ul 默认宽度大约等于父级 .wrapper 的宽度,flex 会把三个 li 压进父宽里,图片会变窄。所以还要继续处理 ul 的宽度。
宽度推导:300% 与 3720px
为什么需要:轮播轨道要能同时容纳三张图。如果 ul 只有父级那么宽,flex 会压缩子项,三张图挤在一起,图片被拉扁或缩小。
怎么想:父级 .wrapper 是版心,转写稿中宽度约 1240px。三张图就需要约 1240 × 3 = 3720px 的轨道宽度。写成 width:300% 表示父级宽度的 3 倍;写成 3720px 是固定值写法。笔记里两种都保留,固定值被注释掉。
怎么做:优先用百分比,图片数量变化时更好改:
css
.banner .wrapper>ul {
display: flex;
width: 300%;
/* width: 3720px; */
}调试时可打开检查工具看 ul 的实际宽度。转写稿中验证到:写 300% 后,ul 实际宽度为 3720px,说明三张图有足够空间。
易错点:3720px 是按父级 1240px 算出来的,父级宽度变了就不能照抄;如果轮播图是 4 张,倍数要改成 400%;还要保证 li 或图片有明确宽度,否则仍可能被 flex 压缩。
溢出隐藏与验证
为什么需要:ul 比 .wrapper 宽,后面两张图会露到版心外面。轮播图默认只应看到当前一张。
怎么想:让有固定宽度的父级 .wrapper 把超出部分裁掉,而不是裁 .banner 通栏背景。转写稿调试时就是把 overflow:hidden 加在 .wrapper 上。
怎么做:在 .banner .wrapper 上设置溢出隐藏,刷新后只看到第一张图;检查工具里第二、第三个 li 仍然存在,只是被裁掉,后续学 JS 后再做切换动画。
易错点:overflow:hidden 不要加在通栏 .banner 上,否则可能裁不到版心内的轨道;也不要误以为第二、三张图被删了,它们只是被隐藏。
小圆点:先占位,后定位
为什么需要:小圆点用于指示当前图片,也方便后续点击切换。但它不是图片轨道本身,结构要分开。
怎么想:先把图片 ul 和宽度调好,再做小圆点容器。转写稿强调“先把圆点容器位置调好,再做里面的 li”,否则容易跑偏。
怎么做:本节只保留 <!-- 小圆点 --> 注释占位。后续可用 ol/ul + li 做圆点,父级 .wrapper 设相对定位,圆点容器绝对定位到 banner 底部。圆点可加鼠标小手,提示可点击。
易错点:不要一上来就写圆点 li 而打乱图片结构;圆点容器要相对 .wrapper 定位,不要相对整个页面定位。
先摆位置:小圆点为什么用绝对定位
为什么需要:banner 小圆点是轮播图的指示器,要盖在图片右下角,不能把图片往下挤,所以它应脱离文档流。
怎么想:转写稿强调“先把 circle 的位置调好,再做里面的 li,不要上来就做小 li,容易跑偏”。也就是先确定整组点的位置,再处理每个点。
怎么做:用 ol.circle 做整组容器,position: absolute; bottom: 10px; right: 10px; 定位到右下角。转写稿里还强调 circle 的父级(wrapper)要加 position: relative,否则绝对定位会找别的祖先当参照。笔记只截取了圆点样式,实际项目要检查父级定位。
易错点:父级没有定位,圆点会跑偏;先写 li 再调容器,位置很难对齐。
结构:用 ol + li 表示一组指示点
为什么需要:小圆点是一组有序指示项,用 ol > li 语义清楚,也方便用 active 标记当前张。
怎么想:三个点就是三个 li,当前点加 active,其余不加。
怎么做:笔记结构如下:
html
<!-- 小圆点 -->
<ol class="circle">
<li></li>
<li class="active"></li>
<li></li>
</ol>易错点:active 拼写要统一;不要每个 li 都加 active,否则当前项不突出。
横排与尺寸:flex 排点,padding 留出外圈
为什么需要:li 默认竖排,必须让它们在一行;同时每个点要有可点击区域和外圈留白。
怎么想:转写稿里“思ec考”就是 circle,“小粒/小利”就是 li,“拍令”就是 padding。外层 li 当作可点击区域,里面的白点用 ::after 画。
怎么做:.circle 加 display: flex;li 设 22px × 22px、padding: 4px、margin-left: 10px、border-radius: 50%;::after 设 14px × 14px 白点。注意 ::after 必须 display: block 才有宽高。
易错点:转写稿提到项目里通常是 box-sizing: border-box,这样 22px 含 padding,内容区正好 14px,白点居中;如果没有这个设置,22px + padding 会把盒子撑大,白点容易偏。第一个 li 也会吃到 margin-left,实际可用 :first-child 去掉左边距。
笔记 CSS 如下:
css
.banner .circle {
display: flex;
position: absolute;
bottom: 10px;
right: 10px;
}
.banner .circle li {
width: 22px;
height: 22px;
padding: 4px;
margin-left: 10px;
/* background-color: pink; */
border-radius: 50%;
/* 小手 */
cursor: pointer;
}
.banner .circle .active {
background-color: rgba(255, 255, 255, 0.5);
}
.banner .circle li::after {
content: "";
/* 转换块级才有大小 */
display: block;
width: 14px;
height: 14px;
background-color: #fff;
border-radius: 50%;
}激活态:active 只给外层加半透明底
为什么需要:当前轮播张要和其他点区分。
怎么想:转写稿里先试过用边框做外圈,但白色底会透出来,效果不好;最后改成“外层 li 给半透明背景,里面用 ::after 放纯白小点”。
怎么做:.active 加 background-color: rgba(255, 255, 255, 0.5)。非激活 li 背景透明,只看到白点;激活项露出半透明外圈。
易错点:不要把半透明背景加到 ::after 上,否则白点被盖住;rgba 的透明度别太高,否则外圈不明显。
调试与收尾
为什么需要:小圆点尺寸小,位置和层级容易看错。
怎么想:转写稿说先看 circle 有没有到右下角,再看 li 是否横排,最后看 ::after 白点大小。
怎么做:用浏览器检查工具选中 li 和伪元素,确认宽高、padding、定位;鼠标小手用 cursor: pointer。以后点击切换由 JS 控制,本节只完成样式。
易错点:::after 漏写 content: "" 不显示;漏写 display: block 宽高无效;父级没定位会跑偏。
先看目标:侧导航是盖在 banner 上的独立盒子
这一节做的是首页 banner 左侧的侧导航。转写稿里在讲 banner 时反复强调一个思路:侧边栏不要一上来就写,先把 banner 和轮播图的大盒子搭好,最后再加一个定位盒子“往这一盖”。原话里说“我不在位置,我才能盖住他们”,意思就是侧导航要用绝对定位脱离普通文档流,才能覆盖在 banner 上方。转写稿里的“通蓝”应理解为“通栏”,“版型/百型”应理解为“版心”,“rappper”应理解为 wrapper。本节笔记中的 .banner .subnav 正是这个覆盖层:position: absolute; left: 0; top: 0; width: 250px; height: 500px;。
HTML:用 ul > li > a 表达“一行分类 + 多个子链接”
为什么需要这样分组?因为侧导航每一行是一个一级分类,后面跟若干二级分类。用 li 表示一行,行内放多个 a,结构清楚,后面做行高、悬浮背景和右侧箭头都方便。怎么做:保留下面结构,不要把所有链接平铺成一个列表。
html
<!-- 侧边栏 -->
<div class="subnav">
<ul>
<li>
<a href="#">生鲜</a>
<a href="#">水果</a>
<a href="#">蔬菜</a>
</li>
<li>
<a href="#">美食</a>
<a href="#">面点</a>
<a href="#">干果</a>
</li>
<li>
<a href="#">餐厨</a>
<a href="#">数码产品</a>
</li>
<li>
<a href="#">电器</a>
<a href="#">床品</a>
<a href="#">四件套</a>
<a href="#">被枕</a>
</li>
<li>
<a href="#">居家</a>
<a href="#">奶粉</a>
<a href="#">玩具</a>
<a href="#">辅食</a>
</li>
<li>
<a href="#">洗护</a>
<a href="#">洗发</a>
<a href="#">洗护</a>
<a href="#">美妆</a>
</li>
<li>
<a href="#">孕婴</a>
<a href="#">奶粉</a>
<a href="#">玩具</a>
</li>
<li>
<a href="#">服饰</a>
<a href="#">女装</a>
<a href="#">男装</a>
</li>
<li>
<a href="#">杂货</a>
<a href="#">户外</a>
<a href="#">图书</a>
</li>
<li>
<a href="#">品牌</a>
<a href="#">品牌制造</a>
</li>
</ul>
</div>易错点:一行里的多个 a 默认会挨在一起,后面要靠 margin-right 或空格拉开;第一项字号更大,用 a:first-child 单独控制,不要给所有 a 都放大。
CSS:先定位外层,再修每一行
为什么先写外层?转写稿在小圆点部分说“先把这个父盒子调好位置,再去做里面的小圆点,要不然容易跑偏”。侧导航同理:先把 .subnav 固定到 banner 左上角,再调 li。怎么做:absolute 定位,宽 250、高 500,背景用半透明黑。注意 .banner 要有定位上下文,否则绝对定位可能参照更外层,这是常见调试点。
css
.banner .subnav {
position: absolute;
left: 0;
top: 0;
width: 250px;
height: 500px;
background-color: rgba(0, 0, 0, .42)
}
.banner .subnav li {
position: relative;
height: 50px;
padding-left: 29px;
line-height: 50px;
/* background-color: pink; */
}
.banner .subnav li::after {
/* 到iconfont.css 里面去复制 */
content: "\e687";
position: absolute;
top: 0px;
right: 29px;
color: #fff;
/* 声明字体图标的字体 */
font-family: iconfont;
}
.banner .subnav li:hover {
background-color: var(--lv);
}
.banner .subnav li a {
color: #fff;
font-size: 14px;
}
.banner .subnav li a:first-child {
font-size: 16px;
margin-right: 5px;
}行高、内边距和伪元素箭头
每个 li 高 50px,line-height: 50px 让文字垂直居中;padding-left: 29px 把文字从左侧推开。右侧箭头不是图片,而是字体图标:li::after 用 content: "\e687",并声明 font-family: iconfont。易错点:content 的编码必须和 iconfont.css 里一致;li 要 position: relative,伪元素才能用 right: 29px 定位到行右侧。var(--lv) 依赖前面已定义的绿色变量,没有定义时悬浮背景不会生效。
悬浮和链接样式
li:hover 给整行换背景,a 默认白色、14px;第一个 a 是主分类,改成 16px,并加 margin-right: 5px 和后面的子链接拉开。易错点:链接颜色要写在 a 上,不能只写在 li 上就以为一定生效;a:first-child 只选每行第一个 a,不要误写成 li:first-child。这样侧导航就完成了:外层定位盖住 banner,内部每行高度一致,右侧字体图标统一,悬浮有反馈。
课件图示(PPTX)


代码示例
1. banner 图片横排
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>banner 图片横排</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
.banner {
height: 500px;
background-color: #f5f5f5;
}
.banner .wrapper {
position: relative;
width: 1240px;
height: 500px;
margin: 0 auto;
overflow: hidden;
}
.banner .wrapper > ul {
display: flex;
width: 300%;
/* width: 3720px; */
}
.banner .wrapper > ul li {
width: 1240px;
}
.banner .wrapper > ul img {
display: block;
width: 100%;
height: 500px;
object-fit: cover;
}
</style>
</head>
<body>
<div class="banner">
<div class="wrapper">
<!-- 轮播图图片 -->
<ul>
<li><a href="#"><img src="./uploads/banner1.png" alt=""></a></li>
<li><a href="#"><img src="./uploads/banner1.png" alt=""></a></li>
<li><a href="#"><img src="./uploads/banner1.png" alt=""></a></li>
</ul>
</div>
</div>
</body>
</html>要点解释
.banner .wrapper > ul使用display:flex,让多个li横向排列。width: 300%表示ul是父级wrapper的 3 倍宽,用来放开 3 张轮播图;也可以写成3720px。wrapper必须设置overflow: hidden,否则超出的第 2、3 张图会露出来。li需要固定宽度,避免 flex 布局把图片压缩;图片再用width: 100%撑满li。
2. banner 小圆点
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>banner 小圆点</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ol {
list-style: none;
}
.banner {
height: 500px;
background-color: #333;
}
.banner .wrapper {
position: relative;
width: 1240px;
height: 500px;
margin: 0 auto;
background-color: #555;
}
.banner .circle {
display: flex;
position: absolute;
bottom: 10px;
right: 10px;
}
.banner .circle li {
width: 22px;
height: 22px;
padding: 4px;
margin-left: 10px;
border-radius: 50%;
cursor: pointer;
}
.banner .circle .active {
background-color: rgba(255, 255, 255, 0.5);
}
.banner .circle li::after {
content: "";
display: block;
width: 14px;
height: 14px;
background-color: #fff;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="banner">
<div class="wrapper">
<!-- 小圆点 -->
<ol class="circle">
<li></li>
<li class="active"></li>
<li></li>
</ol>
</div>
</div>
</body>
</html>要点解释
.circle使用绝对定位,必须保证父级.wrapper有position: relative,否则会相对页面定位。li::after必须写display: block,否则伪元素是行内元素,宽高不生效。li的padding: 4px配合内部14px白点,可以做出“大圈套小点”的效果;注意box-sizing会影响实际盒子尺寸。active类加在li上,用来显示当前小圆点的半透明底色。
3. banner 侧导航
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>banner 侧导航</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
:root {
--lv: #27ba9b;
}
.banner {
position: relative;
height: 500px;
background-color: #f5f5f5;
}
.banner .wrapper {
position: relative;
width: 1240px;
height: 500px;
margin: 0 auto;
background-color: #ddd;
}
.banner .subnav {
position: absolute;
left: 0;
top: 0;
width: 250px;
height: 500px;
background-color: rgba(0, 0, 0, .42);
}
.banner .subnav li {
position: relative;
height: 50px;
padding-left: 29px;
line-height: 50px;
/* background-color: pink; */
}
.banner .subnav li::after {
/* 到 iconfont.css 里面去复制 */
content: "\e687";
position: absolute;
top: 0;
right: 29px;
color: #fff;
/* 声明字体图标的字体 */
font-family: iconfont;
}
.banner .subnav li:hover {
background-color: var(--lv);
}
.banner .subnav li a {
color: #fff;
font-size: 14px;
text-decoration: none;
}
.banner .subnav li a:first-child {
font-size: 16px;
margin-right: 5px;
}
</style>
</head>
<body>
<div class="banner">
<div class="wrapper">
<!-- 侧边栏 -->
<div class="subnav">
<ul>
<li>
<a href="#">生鲜</a>
<a href="#">水果</a>
<a href="#">蔬菜</a>
</li>
<li>
<a href="#">美食</a>
<a href="#">面点</a>
<a href="#">干果</a>
</li>
<li>
<a href="#">餐厨</a>
<a href="#">数码产品</a>
</li>
<li>
<a href="#">电器</a>
<a href="#">床品</a>
<a href="#">四件套</a>
<a href="#">被枕</a>
</li>
<li>
<a href="#">居家</a>
<a href="#">奶粉</a>
<a href="#">玩具</a>
<a href="#">辅食</a>
</li>
<li>
<a href="#">洗护</a>
<a href="#">洗发</a>
<a href="#">洗护</a>
<a href="#">美妆</a>
</li>
<li>
<a href="#">孕婴</a>
<a href="#">奶粉</a>
<a href="#">玩具</a>
</li>
<li>
<a href="#">服饰</a>
<a href="#">女装</a>
<a href="#">男装</a>
</li>
<li>
<a href="#">杂货</a>
<a href="#">户外</a>
<a href="#">图书</a>
</li>
<li>
<a href="#">品牌</a>
<a href="#">品牌制造</a>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>要点解释
.subnav使用绝对定位,放在.wrapper内部,并给.wrapper设置position: relative,这样侧导航才会贴在版心左侧。li设置position: relative,是为了让li::after的right: 29px相对当前li定位。li::after使用content: "\e687"和font-family: iconfont显示字体图标;实际项目中必须引入对应的iconfont.css字体文件。:root中的--lv是示例主题色,笔记中使用var(--lv)控制 hover 背景色,实际项目按主题变量替换即可。
常见错误
现象:三张 banner 图横向排列后整体被压扁。
原因:ul仍在父级宽度内参与 flex 收缩,li/img被压缩。
修法:让ul宽度足够容纳全部图片,如width: 300%或按图片总宽写死;必要时给img固定宽高。现象:轮播超出部分露出第二、第三张图。
原因:只做了横向排列,没有裁剪溢出区域。
修法:给有明确宽度的容器(如.wrapper)加overflow: hidden,不要误加到无固定宽度的通栏容器上。现象:小圆点定位跑到 banner 外面或位置漂移。
原因:绝对定位元素找不到正确的定位父级。
修法:先给.wrapper设置position: relative,再给.circle设置position: absolute并调整bottom/right。现象:圆点用边框模拟半透明外圈时,内部白点不明显或外圈发白。
原因:边框与白色背景叠加,视觉层次被白底吃掉。
修法:改用“外层圆点 +::after内层白点”的结构,外层用rgba()背景表现半透明,内层单独设白底和圆角。现象:侧导航覆盖不住 banner,或 hover 背景错位。
原因:侧导航未相对 banner 定位,或li缺少相对定位上下文。
修法:.banner或.wrapper作为定位父级,.subnav绝对定位到左侧;箭头等伪元素相对li定位。现象:底部版权链接间距过大,点击空白区域也会触发链接。
原因:把左右间距直接加在a上,扩大了可点击范围。
修法:用a + span的结构,间距加在span上,只让文字区域保持链接交互。
练习
banner 横向排列修正:现有三张 banner 图被压成窄条,请分别用“固定
ul总宽”和“百分比宽度”两种方式修正,并说明各自适用场景。圆点组件重构:将当前圆点改为“外层半透明圆 +
::after白色内圆”的结构,补全active状态,并保证鼠标移入变小手。侧导航定位检查:给侧导航补一个最小可运行结构,要求它压在 banner 左侧、
li高度一致、hover 背景铺满整行、右侧箭头位置固定。底部版权模块改写:把一行版权链接改为
p > a + span + a + span ...结构,要求链接文字变色、竖线不变色、点击空白处不触发链接。自查清单演练:任选当前 banner 模块,列出 3 个你最容易出现的布局问题,并写出对应的浏览器检查步骤和修复代码片段。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 底部dl模块制作 | 05:30 |
| 2 | 底部帮助模块左侧完成 | 06:34 |
| 3 | 底部帮助模块右侧结束 | 11:38 |
| 4 | 底部版权模块结束 | 09:46 |
| 5 | 首页banner开始 | 09:33 |
| 6 | 首页banner轮播图效果制作 | 08:49 |
| 7 | 小圆点做法 | 17:43 |
小结
- banner 横向轮播的核心不是“让图片变小”,而是让承载图片的轨道足够宽,再裁剪可视区域。
- 绝对定位组件必须先确认定位父级,否则圆点、侧导航、箭头都会出现位置漂移。
- 圆点这类小组件优先考虑结构层次清晰的做法,边框模拟在白色背景下容易失效。
- 侧导航要与 banner 建立明确的层级和定位关系,hover 状态要作用在整行
li上。 - 底部版权链接要区分“文字可点击区域”和“视觉间隔区域”,避免扩大点击热区。
- 公共头部、底部样式与首页独有样式要分文件管理,避免后续页面互相污染。
- 调试图片不显示时,优先看控制台 404、路径大小写和文件名,再怀疑 CSS。