主题
小兔鲜儿(一)
本页对应 小兔鲜儿,共 8 段视频,约 1 小时 11 分。
学习目标
- 能够独立搭建热门品牌模块的通栏与版心结构,设置高度 468px、背景色 #F5,并复用头部结构完成标题区。
- 能够完成热门品牌头部右侧按钮结构:与标题为兄弟关系的
.btn容器、两个href="javascript:;"的链接及字体图标,并使用 Flex 横排、间距和绝对定位完成对齐。 - 能够实现热门品牌内容区:UL/LI/A/IMG 结构、5 个列表项、LI 固定尺寸 244×306,并保证图片与列表项尺寸一致。
- 能够搭建生鲜模块头部:版心内 HD/BD 结构,使用
flex: 1将标题区域撑满以挤压右侧内容,设置列表项间距,并完成鼠标经过变色且文字不抖动。 - 能够完成生鲜内容区域布局:左右分栏、左侧图片链接、右侧 UL 使用 Flex 换行实现两行两列,列表项固定尺寸 242×304。
- 能够使用透明边框占位解决 hover 加边框导致的抖动问题,并在鼠标经过时将边框颜色改为绿色。
知识点
结构:标题与按钮是兄弟关系
为什么需要:热门品牌头部左边是“热门品牌 + 副标题”,右边是左右箭头按钮。按钮要独立控制,不能塞进标题里,否则结构和样式都会互相干扰。
怎么想:在 .hd 里放两个并列子元素:h2 管标题,.btn 管两个箭头,二者是兄弟关系。
怎么做:按笔记写 h2 和 .btn,按钮用 a,并写 href="javascript:;",避免点击后跳到页面顶部。
易错点:不要写 href="#";不要把 .btn 放进 h2;span 是副标题,不要误写成主标题。
横排:用 flex 管两个箭头按钮
为什么需要:左右两个箭头要在一行,并且宽高、背景、间距统一。
怎么想:父级 .btn 用 display:flex,两个 a 自动成为一行;每个 a 固定 20×20,再用 margin-left:12px 拉开距离。
怎么做:给 .brand .btn a 设置宽高、背景 #e2e2e2、文字白色,并用 text-align:center 与 line-height:20px 让图标水平垂直居中。
易错点:a 默认是行内元素,若父级不是 flex,单独设宽高可能不生效,需要 display:block/inline-block;margin-left 会给第一个也加左边距,视觉可接受,精确可用 gap 或 :first-child。
定位:按钮贴右,父级相对定位
为什么需要:按钮要贴在头部右侧,又不能用外边距把标题和父盒子挤乱。
怎么想:让 .brand .hd 作为定位参照,.btn 绝对定位,right:0 贴右,top:85px 做视觉微调。
怎么做:.brand .hd { position:relative; },.brand .btn { position:absolute; top:85px; right:0; display:flex; }。
易错点:不要用 margin-top 调 .btn。转写稿调试时发现,.hd 没有固定高度,给子盒子加外边距会把父盒子撑大,甚至带着 h2 一起走;绝对定位脱离标准流,才不会影响标题。父级相对定位要限定在 .brand .hd,避免影响其他模块的 .hd。
高亮:右按钮用变量色,并处理层叠
为什么需要:右箭头要显示绿色高亮,左箭头保持灰色。
怎么想:两个按钮共用 .brand .btn a 的基础样式,再单独给 .btnright 换背景色 var(--lv)。
怎么做:写 .brand .btn .btnright { background-color: var(--lv); }。
易错点:转写稿中颜色一开始没生效,调试时不要猜,打开开发者工具选中元素:若没有黄色感叹号,说明选择器没写错,而是被上面的 .brand .btn a 层叠了;提高权重到 .brand .btn .btnright 即可覆盖。变量 --lv 要确保已定义。
完整代码与检查
以下保留本节笔记代码:
html
<!-- hd -->
<div class="hd">
<h2>热门品牌
<span>国际经典 品质认证</span>
</h2>
<!-- 按钮 button-->
<div class="btn">
<a href="javascript:;" class="btnleft">
<i class="iconfont icon-arrow-left-bold"></i>
</a>
<a href="javascript:;" class="btnright">
<i class="iconfont icon-arrow-right-bold"></i>
</a>
</div>
</div>css
/* brand里面的hd 加相对定位 */
.brand .hd {
position: relative;
}
.brand .btn {
position: absolute;
top: 85px;
right: 0;
display: flex;
}
.brand .btn a {
width: 20px;
height: 20px;
background-color: #e2e2e2;
margin-left: 12px;
text-align: center;
line-height: 20px;
color: #fff;
}
.brand .btn .btnright {
background-color: var(--lv);
}检查清单:.btn 与 h2 是否兄弟;a 是否写 javascript:;;.hd 是否相对定位;.btn 是否绝对定位并贴右;两个 a 是否横排;宽高、居中、间距、右按钮绿色是否生效。本节只完成头部右侧结构和样式,点击滚动属于后续 JavaScript 轮播逻辑。
本节把“热门品牌”拆成通栏盒子、版心、头部标题、左右按钮和图片列表五块来写。核心思路是:先搭大盒子,再套版心,最后填内容和调细节。
整体盒子与版心
为什么需要:热门品牌有整块浅灰底色,需要通栏;内容又要居中,所以必须“大盒子套版心”。
怎么想:先写 .brand 给高度和背景色,再在里放 .wrapper,不要一上来抠图片。
怎么做:.brand 高 468px、背景 #f5f5f5,并用 margin-top:50px 与上方拉开距离;.wrapper 负责版心。
易错点:大盒子套小盒子时,小盒子写 margin-top 可能发生外边距塌陷,把父盒子一起带下来;这时优先给父盒子或头部用 padding 挤开。
html
<!-- 热门品牌 brand -->
<div class="brand">
<div class="wrapper">
<!-- hd -->
<div class="hd">
<h2>热门品牌
<span>国际经典 品质认证</span>
</h2>
<!-- 按钮 button -->
<div class="btn">
<a href="javascript:;" class="btnleft">
<i class="iconfont icon-arrow-left-bold"></i>
</a>
<a href="javascript:;" class="btnright">
<i class="iconfont icon-arrow-right-bold"></i>
</a>
</div>
</div>
<!-- bd -->
<div class="bd">
<ul>
<li><a href="#"><img src="./uploads/hot1.png" alt="热门品牌1"></a></li>
<li><a href="#"><img src="./uploads/hot2.png" alt="热门品牌2"></a></li>
<li><a href="#"><img src="./uploads/hot3.png" alt="热门品牌3"></a></li>
<li><a href="#"><img src="./uploads/hot4.png" alt="热门品牌4"></a></li>
<li><a href="#"><img src="./uploads/hot5.png" alt="热门品牌5"></a></li>
</ul>
</div>
</div>
</div>头部标题与按钮结构
为什么需要:头部左边是标题,右边是轮播箭头,二者要在一行内分别靠左、靠右。
怎么想:复用前面模块的 .hd 结构,标题用 h2,说明文字放 span;按钮 .btn 与 h2 是兄弟关系。
怎么做:.hd 内先写标题,再写 .btn,里面放两个 a,每个 a 内放字体图标 i。
易错点:按钮链接不要写 href="#",否则点击会跳回顶部;写 javascript:;。按钮不要塞进 h2 里,避免结构混乱。
左右按钮样式与调试
为什么需要:两个箭头要并排、有大小、有底色,并且右侧按钮用主题绿色。
怎么想:两个 a 共用宽高和底色,父级 .btn 用 display:flex 让它们一行排列;右侧单独覆盖背景色。
怎么做:a 宽高 20px,背景 #e2e2e2,text-align:center、line-height:20px、文字白色;.btnright 用 var(--lv)。
易错点:颜色不生效时不要猜,先看选择器权重和层叠。笔记里 .brand .btn .btnright 比 .brand .btn a 更具体,能覆盖底色;a 默认是行内元素,靠父级 flex 后宽高才稳定生效。
按钮定位与头部微调
为什么需要:按钮要贴到头部右侧指定位置,又不能把标题和头部撑大。
怎么想:用定位让按钮脱离标准流,父级 .hd 加 position:relative,.btn 加 position:absolute。
怎么做:.brand .hd{position:relative},.brand .btn{position:absolute;top:80px;right:0;display:flex}。转写稿调试时试过 85px,最后按效果回到笔记的 80px。
易错点:不要用 margin-top 硬推按钮,按钮变高会把 .hd 撑大,标题也会跟着动;定位后记得给父级相对定位,否则会找错参照物。
内容区图片列表
为什么需要:下方是五张品牌图,需要统一尺寸,后续做轮播时让 ul 滚动。
怎么想:bd 里放 ul,ul 里放 li,li 里放 a 和 img;先固定每个 li 的大小。
怎么做:.brand .bd li{width:244px;height:306px},图片按该尺寸显示。
易错点:不要直接改所有 .bd li,要限定在 .brand .bd li,避免影响其他模块;图片尺寸不一致时先固定 li,再处理图片适配。
css
/* 热门品牌 */
.brand {
height: 468px;
background-color: #f5f5f5;
margin-top: 50px;
}
/* brand里面的hd 加相对定位 */
.brand .hd {
position: relative;
}
.brand .btn {
position: absolute;
top: 80px;
right: 0;
display: flex;
}
.brand .btn a {
width: 20px;
height: 20px;
background-color: #e2e2e2;
margin-left: 12px;
text-align: center;
line-height: 20px;
color: #fff;
}
.brand .btn .btnright {
background-color: var(--lv);
}
.brand .bd li {
width: 244px;
height: 306px;
}
先搭结构:标题区为什么这样分
生鲜标题区要同时放三样东西:模块标题“生鲜”、一排分类导航、右侧“查看全部”。所以不能只写一个 h2,而要有一个头部容器 hd 把三者组织起来。转写稿里反复强调“先把大盒子、版心写出来,再考虑里面的内容”,这里也是同样思路:外层 wrapper 负责版心,里面先放 hd,再填 h2、ul、a.all。
html
<!-- 生鲜模块 -->
<div class="wrapper">
<!-- 上侧 hd -->
<div class="hd">
<h2>生鲜</h2>
<ul>
<li><a href="#">热门</a></li>
<li><a href="#">蔬菜</a></li>
<li><a href="#">肉禽蛋</a></li>
<li><a href="#">水果</a></li>
<li><a href="#">海鲜</a></li>
<li><a href="#">零食</a></li>
<li><a href="#">饮料</a></li>
</ul>
<a href="#" class="all">
查看全部
<i class="iconfont icon-arrow-right-bold"></i>
</a>
</div>
</div>这里易错点是把 ul 或“查看全部”塞进 h2 里。它们应是 hd 下的兄弟关系:h2 是标题,ul 是导航,a.all 是操作入口。先保证结构清楚,后面才方便用 Flex 布局。
让导航横排:ul 先变成 Flex
li 默认是块级元素,会一行一个竖着排。笔记里先给出一句核心样式:
css
/* 生鲜 */
.hd ul {
display: flex;
}为什么需要它?因为分类项必须横向排列。怎么想?不要急着给每个 li 加浮动,直接把它们的父级 ul 设为 display:flex,让子项自动在一行上排列。怎么做?先写这一句,观察“热门、蔬菜、肉禽蛋……”是否横排。
易错点是:只给 ul 加 Flex 只能解决 li 横排;如果 h2、ul、“查看全部”仍然上下分行,还要检查 hd 这一层是否也具备 Flex 布局。转写稿中提到头部依赖 hd 的 Flex 能力,实际调试时可用检查工具看 hd 的 display 是否为 flex。
用 h2 { flex:1 } 把右侧内容挤过去
转写稿里最关键的一步,是没有用固定 margin-left 把导航推到右边,而是给“生鲜”标题加 flex:1。原因是分类文字可能多也可能少,写死距离后,内容一变布局就难看。思路是:h2 和右侧内容宽度由内容决定,中间剩余空间全部给 h2,它占满后,ul 和“查看全部”自然被挤到右侧。
为避免影响页面中其他 hd,转写稿中给生鲜模块加了 fresh 这一层区分,选择器写成:
css
.fresh .hd h2 {
flex: 1;
}易错点:flex:1 要加在 h2 上,不是加在 ul 上;选择器要限定在生鲜模块内,不要写成全局 .hd h2,否则其他模块头部也会被改变。若发现没生效,先用调试工具确认选择器是否命中、父级是否已经是 Flex 容器。
调间距和悬停:先占位,再换色
分类项之间需要距离,转写稿中给 li 加右侧外边距,约 13px;导航整体与“查看全部”之间再留出距离。链接本身要给左右 padding,这样鼠标悬停时背景色有可点击区域。悬停时只换背景色和文字色,不要让盒子尺寸突然变化。
css
.fresh .hd ul li {
margin-right: 13px;
}
.fresh .hd ul {
margin-right: 65px;
}
.fresh .hd ul a {
padding: 0 5px;
}
.fresh .hd ul a:hover {
background-color: #00b45a;
color: #fff;
}易错点:padding 应写在常态的 a 上,hover 里只改颜色;如果把 padding 只写在 hover 里,鼠标经过时文字会“抖”一下。调试距离时不要猜,直接打开检查工具看盒模型,确认是 margin 还是 padding 在起作用。这样生鲜标题区的结构、横排、右推和悬停反馈就完整了。
先看目标:生鲜头部要排成一行
生鲜模块的头部结构并不复杂:左侧是标题“生鲜”,中间是一组分类导航,右侧是“查看全部”。本节笔记截取的是 .hd 部分,外层通常还会有生鲜模块和版心容器,用来限制内容宽度。写之前先想清楚:标题、导航、查看全部三者要在同一行;导航内部的多个 li 也要在同一行;鼠标经过导航链接时要有绿色底色和白色文字。因此布局重点不是堆样式,而是先把 HTML 的兄弟关系和父子关系写对。
结构:h2、ul、a.all 是兄弟关系
笔记中的 HTML 如下,h2、ul、a.all 都放在 .hd 里面,它们是兄弟关系。这样后面才能用 flex 让三者排成一行。
html
<!-- 上侧 hd -->
<div class="hd">
<h2>生鲜</h2>
<ul>
<li><a href="#">热门</a></li>
<li><a href="#">蔬菜</a></li>
<li><a href="#">肉禽蛋</a></li>
<li><a href="#">水果</a></li>
<li><a href="#">海鲜</a></li>
<li><a href="#">零食</a></li>
<li><a href="#">饮料</a></li>
<li><a href="#">海鲜</a></li>
<li><a href="#">零食</a></li>
<li><a href="#">饮料</a></li>
</ul>
<a href="#" class="all">
查看全部
<i class="iconfont icon-arrow-right-bold"></i>
</a>
</div>为什么需要先确认结构?因为“查看全部”必须和 ul 平级,不能塞进 ul 或某个 li 里;否则 flex 的排列对象就变了。怎么想?把 .hd 看成一排三个子盒子:标题、导航、查看全部。怎么做?保持上面结构不动,样式统一加在 .hd 及其子元素上。
让 ul 和 li 一行显示
笔记 CSS 先处理导航:
css
/* 让生鲜模块里面的li 一行显示 */
.hd ul {
display: flex;
margin-right: 65px;
}
.hd ul li {
margin-right: 13px;
}
.hd ul li a {
padding: 0 5px;
}
/* 鼠标经过添加底色和文字颜色 */
.hd ul li a:hover {
background-color: var(--lv);
color: #fff;
}
.fresh .hd h2 {
flex: 1;
}.hd ul 加 display: flex,是为了让多个 li 横向排列;li 的 margin-right: 13px 是分类之间的间距;a 的 padding: 0 5px 是给文字左右留出空间,这样 hover 背景不会只贴着文字。易错点:不要只在 :hover 里加 padding,否则鼠标经过时盒子尺寸变化,文字会抖动。正确做法是默认状态先给 a 左右 padding,hover 只换背景色和文字颜色。
h2 用 flex:1 把右侧内容推过去
.fresh .hd h2 { flex: 1; } 是关键。为什么需要?因为标题字数少,导航和“查看全部”要根据内容宽度靠右,不能写死左边距。怎么想?.hd 本身是 flex 容器时,h2 设置 flex: 1 会占满剩余空间,于是 ul 和 .all 被推到右侧。怎么做?只对生鲜模块下的 h2 设置,避免影响其他模块的 .hd h2。易错点:不要给 h2 写死宽度,也不要用很大的 margin-left 硬挤,因为分类文字数量变化时布局会不自然。.hd ul 上的 margin-right: 65px 用来把导航和“查看全部”拉开距离。
调试顺序:先一行,再间距,最后 hover
实际写的时候按这个顺序检查:先看 .hd 是否一行,再看 ul 内 li 是否一行,然后调 li 间距和 ul 右边距,最后给 a 加 padding 和 hover。若发现“查看全部”掉下去,优先检查 .hd 是否 flex、h2 是否 flex:1;若 hover 时文字抖动,检查 a 默认是否已有左右 padding;若其他模块头部被影响,检查 flex:1 是否限定在 .fresh .hd h2 下。这样这一节生鲜头部就完成了。
课件图示(PPTX)



代码示例
1. 热门品牌:头部右侧按钮 + 内容区
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>热门品牌</title>
<style>
:root { --lv: #00be9c; } /* 占位:项目里用的是全局变量 --lv */
* { margin: 0; padding: 0; }
ul { list-style: none; }
a { text-decoration: none; }
.wrapper { width: 1240px; margin: 0 auto; }
/* 热门品牌:通栏大盒子 */
.brand {
height: 468px;
background-color: #f5f5f5;
margin-top: 50px;
}
/* brand里面的hd 加相对定位 */
.brand .hd {
position: relative;
padding-top: 40px; /* 用内边距把标题挤下来,具体值按设计稿 */
}
.brand .hd h2 { font-size: 28px; font-weight: 400; }
.brand .hd h2 span { font-size: 14px; color: #999; margin-left: 12px; }
.brand .btn {
position: absolute;
top: 85px;
right: 0;
display: flex; /* 让两个 a 在一行 */
}
.brand .btn a {
width: 20px;
height: 20px;
background-color: #e2e2e2;
margin-left: 12px;
text-align: center;
line-height: 20px;
color: #fff;
}
.brand .btn .btnright { background-color: var(--lv); }
/* 内容区 */
.brand .bd ul { display: flex; }
.brand .bd li {
width: 244px;
height: 306px;
}
.brand .bd li img { width: 100%; height: 100%; display: block; }
</style>
</head>
<body>
<!-- 热门品牌 brand -->
<div class="brand">
<div class="wrapper">
<!-- hd -->
<div class="hd">
<h2>热门品牌
<span>国际经典 品质认证</span>
</h2>
<!-- 按钮 button-->
<div class="btn">
<a href="javascript:;" class="btnleft">
<i class="iconfont icon-arrow-left-bold"></i>
</a>
<a href="javascript:;" class="btnright">
<i class="iconfont icon-arrow-right-bold"></i>
</a>
</div>
</div>
<!-- bd -->
<div class="bd">
<ul>
<li><a href="#"><img src="./uploads/hot1.png" alt=""></a></li>
<li><a href="#"><img src="./uploads/hot2.png" alt=""></a></li>
<li><a href="#"><img src="./uploads/hot3.png" alt=""></a></li>
<li><a href="#"><img src="./uploads/hot4.png" alt=""></a></li>
<li><a href="#"><img src="./uploads/hot5.png" alt=""></a></li>
</ul>
</div>
</div>
</div>
</body>
</html>要点:
.brand是通栏盒子(给高 +#f5f5f5),里面再套.wrapper版心,这是"通栏套版心"的标准写法。.hd必须加position: relative,否则.btn的position: absolute会去找更外层的定位祖先。- 按钮不能用
margin-top往下推:.btn在.hd里,margin/padding都会把.hd撑大,连带把h2顶下去;只有定位脱离标准流,才"爱咋调咋调",不影响别人。 - 标题下移用
padding-top,不要给子盒子margin-top——大盒子套小盒子时子盒子的margin-top会发生外边距塌陷,把父盒子一起带跑。 - 权重坑:
.brand .btnright(两个类)会被.brand .btn a(两个类+标签)层叠掉,所以必须写.brand .btn .btnright(三个类)。调不出来时先看调试工具里样式有没有被划掉。 - 按钮
a写href="javascript:;",写#点一下会跳回页面顶部。 .brand .bd li前面一定要带.brand,直接写.bd li会污染页面上其它模块。
2. 生鲜模块头部(h2 + 分类 ul + 查看全部)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>生鲜头部</title>
<style>
:root { --lv: #00be9c; }
* { margin: 0; padding: 0; }
ul { list-style: none; }
a { text-decoration: none; color: #333; }
.wrapper { width: 1240px; margin: 0 auto; }
/* 生鲜 */
.fresh .hd {
display: flex;
align-items: center;
padding-top: 40px;
}
.fresh .hd h2 {
flex: 1; /* 占满剩余空间,把 ul 和“查看全部”挤到右边 */
font-size: 28px;
font-weight: 400;
}
.hd ul { display: flex; margin-right: 65px; }
.hd ul li { margin-right: 13px; }
.hd ul li a { padding: 0 5px; }
/* 鼠标经过添加底色和文字颜色 */
.hd ul li a:hover { background-color: var(--lv); color: #fff; }
.fresh .all { font-size: 14px; color: #999; }
</style>
</head>
<body>
<!-- 生鲜模块 -->
<div class="fresh">
<div class="wrapper">
<!-- 上侧 hd -->
<div class="hd">
<h2>生鲜</h2>
<ul>
<li><a href="#">热门</a></li>
<li><a href="#">蔬菜</a></li>
<li><a href="#">肉禽蛋</a></li>
<li><a href="#">水果</a></li>
<li><a href="#">海鲜</a></li>
<li><a href="#">零食</a></li>
<li><a href="#">饮料</a></li>
</ul>
<a href="#" class="all">
查看全部
<i class="iconfont icon-arrow-right-bold"></i>
</a>
</div>
</div>
</div>
</body>
</html>要点:
.fresh .hd加display: flex,h2、ul、.all三个子元素才会排成一行;ul自己再加display: flex让li一行显示。- 中间那块"自动被挤到右边"靠的是
h2 { flex: 1 }一等份:两侧宽度由内容决定,剩下的全给h2,ul和"查看全部"就被顶到右边。不能写死margin-left,分类文字多了少了就错位。 - 间距:
li给margin-right: 13px拉开字间距,ul给margin-right: 65px和"查看全部"拉开。 a的padding: 0 5px必须一开始就给,只在:hover里加背景色。如果 hover 时才加 padding,文字会被"推一下",出现抖动。h2必须用.fresh .hd h2限定,直接改.hd h2会影响到上面其它模块的hd。
3. 生鲜模块内容区(左右布局 + 右侧两行两列)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>生鲜内容区</title>
<style>
:root { --lv: #00be9c; }
* { margin: 0; padding: 0; }
ul { list-style: none; }
a { text-decoration: none; }
.wrapper { width: 1240px; margin: 0 auto; }
/* 内容区域:分左右,所以不用 bd,另起 content */
.fresh .content {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.fresh .content .left {
width: 248px;
height: 610px;
background-color: pink; /* 占位,实际放图片 */
}
.fresh .content .left img { width: 100%; height: 100%; display: block; }
.fresh .content .right {
width: 968px;
height: 610px;
background-color: skyblue; /* 占位 */
}
.fresh .content .right ul {
display: flex;
flex-wrap: wrap; /* 强制换行 → 两行两列 */
}
.fresh .content .right ul li {
width: 242px;
height: 304px;
border: 2px solid transparent; /* 先占位,避免 hover 抖动 */
}
.fresh .content .right ul li:hover {
border-color: var(--lv);
}
</style>
</head>
<body>
<div class="fresh">
<div class="wrapper">
<div class="content">
<div class="left">
<a href="#"><img src="./uploads/fresh_left.png" alt=""></a>
</div>
<div class="right">
<ul>
<li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>要点:
- 这里结构是左右分,和上面的
.bd不一样,所以另起content盒子,别复用bd。 left/right是高频类名,选择器必须带上.fresh、.content限定:.fresh .content .left,否则会误伤页面其它地方。- 父盒子
display: flex+justify-content: space-between,左右两块自动贴两边。 - 右侧
ul只写display: flex是一行排开;要两行两列必须再加flex-wrap: wrap。 - 边框坑:
li的宽高按 hover 态量(242×304)。如果平时不给边框、:hover才加border,边框会占位把内容往里挤,出现"抖一下";正确做法是先给border: 2px solid transparent占位,hover 只改border-color。 - 图片建议加
display: block(或给img { width:100% }),否则img底部会多出几像素空隙。
常见错误
热门品牌标题区被整体带下来 / 上间距失效
现象:.brand .hd加margin-top后,整个.brand被一起带下或间距异常。
原因:大盒套小盒,子盒margin-top触发外边距塌陷。
修法:子盒改用父盒padding-top;需要整体下移时调.brand的margin-top。右侧左右按钮把标题区撑高、影响标题垂直位置
现象:给.btn加margin-top后,h2跟着移动或.hd高度变化。
原因:普通流盒子的margin/padding会参与父盒尺寸计算。
修法:.brand .hd设position: relative,.btn设position: absolute; top/right,不占文档流。.btnright背景色不生效
现象:写了.brand .btn .btnright { background-color: var(--lv); }但仍是灰色。
原因:被.brand .btn a的同等或更高层叠规则覆盖,或选择器权重不足。
修法:开发者工具看划掉规则;提高权重,如.brand .btn a.btnright或.brand .btn .btnright并确认书写顺序。点击左右箭头页面跳到顶部
现象:点按钮后页面瞬间回到顶部。
原因:a的href="#"触发锚点跳转。
修法:占位链接写href="javascript:;",后续接轮播逻辑。按钮里的
a不横排、尺寸不生效
现象:左右箭头竖排,或宽高设置无效。
原因:a是行内元素,父级未建立横向布局。
修法:父级.btn用display:flex;给a明确宽高、text-align、line-height。生鲜导航项 hover 时文字抖动
现象:鼠标移入后文字左右跳动。
原因:初始没给padding,hover 才加背景/内边距,盒模型尺寸变化。
修法:初始就给a固定padding: 0 5px;hover 只改background-color和color。生鲜右侧
li鼠标经过加边框时内容抖动
现象:hover 后li内图片/文字向内缩。
原因:初始无边框,hover 才加边框,边框占位改变盒模型。
修法:初始写透明边框border: 2px solid transparent;hover 只改border-color。生鲜右侧 8 个
li全挤在一行
现象:只写了一行,未形成两行两列。
原因:父级只设了display:flex,未允许换行。
修法:给ul加flex-wrap: wrap,并限定作用域如.fresh .content .right li。样式污染其他模块
现象:改.bd li或.hd ul li后,热门品牌、生鲜等模块互相影响。
原因:选择器范围过大,复用了公共类名。
修法:加最近模块父级限定,如.brand .bd li、.fresh .hd ul li。结构嵌套写错,
bd写进hd里
现象:内容区样式错乱、按钮定位异常、后续选择器全受影响。
原因:写 HTML 时未先闭合hd,复制结构后未检查层级。
修法:先闭合hd再写bd;复制模块后先折叠检查父子关系。
练习
热门品牌头部右侧按钮
要求:.hd内左侧标题、右侧两个箭头按钮;按钮横排、右对齐、a不跳顶部;左按钮灰底、右按钮主题绿;用绝对定位放到标题区右下侧。
验收:点击按钮页面不跳顶;.btn不影响h2位置;.btnright背景色生效。生鲜头部自适应一行
要求:h2 + ul + 查看全部同一行;h2占剩余空间,ul靠右;增加/删除若干li后,查看全部仍贴右且不重叠。
验收:不写死中间大段margin;增减导航项后布局仍稳定。生鲜导航 hover 防抖
要求:导航a初始就有左右内边距;hover 只改变背景色和文字颜色。
验收:鼠标移入移出文字不左右抖动,背景和文字颜色切换正常。生鲜内容右侧两行两列
要求:.right内ul > li共 8 项,两行两列;每个li固定宽高;hover 显示主题色边框。
验收:ul能换行;hover 前后内容不位移;样式不影响热门品牌li。层叠问题排查
要求:故意让.btnright背景色被.btn a覆盖,用开发者工具定位被划掉的规则,再通过提高权重或调整顺序修复。
验收:能指出是“层叠/权重”问题而非写错类名,并给出修复后的选择器。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 热门品牌模块头部开始 | 05:20 |
| 2 | 热门品牌模块头部右侧制作 | 07:56 |
| 3 | 热门品牌头部完成 | 13:19 |
| 4 | 热门品牌bd部分结束 | 04:13 |
| 5 | 生鲜模块头部开始 | 06:06 |
| 6 | 生鲜模块头部调整中间距离 | 09:49 |
| 7 | 生鲜模块内容区域布局 | 13:31 |
| 8 | 生鲜模块小li修改 | 10:53 |
小结
- 先搭模块大盒与版心,再补头部、内容区,结构层级正确优先于样式微调。
- 模块样式必须加父级作用域,避免
.hd、.bd、li、a等公共类互相污染。 - 不影响文档流的小控件优先用绝对定位;父级记得建立定位上下文。
- 一行内“左中右”自适应,优先用
flex:1吃掉剩余空间,不写死大间距。 - 交互态要预留占位:hover 改颜色可以,hover 才加
padding或border容易抖动。 - 调样式不生效时先看开发者工具:看层叠划掉、看继承来源、看选择器权重,不靠猜。
- 占位链接用
javascript:;,避免#造成页面跳顶。 - 模块完成后先折叠检查再复制,复制后立即改类名与作用域,减少结构性 bug。