Skip to content

小兔鲜儿(三) ​

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

学习目标 ​

  1. 能使用 H1 包裹 A 标签完成 logo 结构,并通过背景图、尺寸设置及文字隐藏方案实现可点击 logo,且能说明两种隐藏文字方法的差异。
  2. 能完成导航栏结构搭建,使用 Flex 布局使导航项横向排列,并通过行高、外边距和 :hover 实现文字变色与下边框悬停效果。
  3. 能完成搜索框结构与样式,使用 :focus 和过渡实现输入框聚焦变宽,使用 ::placeholder 修改提示文字样式,并通过绝对定位放置放大镜图标。
  4. 能完成购物车模块结构,使用父子定位将数量角标覆盖到购物车图标上,并保证数量位数增加时角标向左扩展且不挤压搜索框。
  5. 能搭建底部大容器与版心结构,设置底部背景色、固定高度及版心包裹区域,为后续服务区域、帮助中心和版权区域布局做好准备。

知识点 ​

先搭购物车结构:一大套两小 ​

为什么需要:购物车是头部最后一个独立小模块,结构不先定下来,后面调图标和数量角标时容易把选择器写串。转写稿里先写 .car 盒子并放 123 测试位置,就是先确认“盒子在哪”,再往里装内容。

怎么想:整体是“一个父盒子 car,里面两个子元素:小车图标 i 和数量 span”。数量要压在图标右上角,所以后面必须用定位,但结构阶段先让它们按标准流排出来。

怎么做:按笔记保留结构:

html
<!-- car 车 -->
<div class="car">
  <i class="iconfont icon-cart-full"></i>
  <span>2</span>
</div>

易错点:i 和 span 是兄弟关系,不是父子;选择器要写清 .car i、.car span,不要写成页面里所有 i,否则容易和搜索框里的图标冲突。转写稿也强调“找最近一级的爸爸”。

小车图标:先定大小,再用父盒子调位置 ​

为什么需要:图标字体默认大小不一定符合效果图,且整个购物车要跟头部其他模块对齐,不能只调图标本身。

怎么想:图标大小归 .car i 管;整体上下左右位置归 .car 父盒子管。转写稿里一开始把 margin-top 加到 i 上发现“咋没动”,后来改给 .car,整体才被带下来。

怎么做:笔记样式保留:

CSS
/* car  */
.car {
  position: relative;
  margin: 20px 0 0 15px;
}

.car i {
  font-size: 36px;
}

易错点:调整体位置时优先给 .car 加 margin,不要误加到 i 上;图标大小按效果调,转写稿从 24px 试到 36px,说明这是调试值,不是死记。

数量角标:父相子绝,left 比 right 更符合认知 ​

为什么需要:数字“2”要浮在购物车右上角,普通标准流会占位置,把图标和数字左右排开,压不住。

怎么想:用“子绝父相”——.car 加 position: relative,span 加 position: absolute。转写稿先试 top:0; right:0,发现数字变大时角标往左长,不符合“数字越多往右撑”的认知,所以最终改为 left。

怎么做:保留笔记代码:

CSS
.car span {
  position: absolute;
  top: 0;
  left: 22px;
  padding: 0 8px;
  background-color: #E26237;
  color: #fff;
  border-radius: 11px;
}

易错点:span 不要写死宽高。转写稿明确说“有可能买200件”,要让数字自己把盒子撑开;padding: 0 8px 是给左右留空间。left: 22px 是配合 36px 图标微调出来的,改图标大小后要重新看位置。

调试顺序:先标准流,再定位,最后微调 ​

为什么需要:一上来就定位,出了问题分不清是结构、尺寸还是定位错。转写稿的做法是先让 car、i、span 横着显示,调好大小和间距,再加绝对定位。

怎么想:先确认 .car 的位置,再确认图标大小,最后把 span 压上去;用浏览器检查元素看盒子范围,比盲调可靠。

怎么做:按“结构→父盒子 margin→图标 font-size→span 绝对定位→微调 top/left”的顺序做。数字改成 200 测试,角标应向右撑开而不是往左跑。

易错点:绝对定位后 span 不占标准流位置,是“飘”在图标上的;父级忘了 relative,它会按更外层定位。角标不要给固定宽度,否则数字多会溢出或变形。

先看底部效果与结构 ​

底部布局效果图

底部属于页面公共部分。转写稿里强调:头部结束后不要急着写中间内容,先把“尾”搭出来,即先完成底部的大盒子,再在底部内部划分版心和上中下三块。这样公共样式可以继续放在公共 CSS 里,后面写中间区域时再换样式文件。

为什么需要先搭大盒子?因为底部整体有统一背景和高度,如果一上来就写“服务、帮助中心、版权”,很容易把背景、版心宽度和内部间距混在一起。怎么想?先把底部看成“一个通栏大盒子”,里面放“一个版心”,版心内再分三块。怎么做?按下面结构写。

HTML结构:大盒子套版心,再分三块 ​

html
<!-- 底部 -->
<div class="footer">
  <div class="wrapper">
    <!-- 服务 -->
    <div class="service">服务</div>
    <!-- 帮助中心 -->
    <div class="help">帮助中心</div>
    <!-- 版权 -->
    <div class="copyright">版权</div>
  </div>
</div>

这里的 footer 是通栏底部,wrapper 是版心,service、help、copyright 是版心内的三块内容。转写稿里说底部高度量到约 581.5,取整可理解为 582;但本节笔记最终给的是 580,写的时候以笔记代码为准,差一两像素不影响整体布局验收。易错点是:不要把三块内容直接塞到 footer 里,否则版心宽度不好统一控制。

CSS:底部背景与版心 ​

css
/* 底部 */
.footer {
  height: 580px;
  background-color: #F5F5F5;
}

/* 服务 */
.service {
  padding: 60px 0;
  height: 178px;
  border-bottom: 1px solid #E8E8E8;
}

/* 帮助中心 */
.help {
  display: flex;
  justify-content: space-between;
  padding-top: 60px;
  height: 300px;
  background-color: pink;
}

footer 给高度和浅灰背景 #F5F5F5,是为了先看到底部整体区域。wrapper 在笔记里没有写具体宽度,它承担版心作用,通常要配合公共版心样式使用;本节先保留结构,不额外编造宽度。service 用上下 60px 内边距把内容往里推,底部加 1px solid #E8E8E8 分隔线。help 用 display:flex 和 justify-content:space-between,是为了让帮助中心内部的多列内容分居两侧或均匀排开;padding-top:60px 控制与上方服务的距离。这里的 background-color: pink 是转写稿里明显的“测试背景”,先看盒子位置和大小,调好后应替换成设计稿颜色或删除。

调试思路与易错点 ​

转写稿的调试过程是:先给 footer 高度和背景,看到“顶”和“底”两大块;再加 wrapper 版心,让底部内容有统一宽度;然后写 service、help。所以本节不要急着把三块内容全部精修,先把盒子搭出来。易错点有三个:第一,service 同时写了 height 和上下 padding,如果实际高度与量图不一致,要用浏览器检查盒子模型,确认高度是否包含内边距;第二,help 的粉色只是测试色,不能当最终样式;第三,copyright 在笔记里只有结构没有样式,说明本节重点是底部骨架,版权区样式后续再补,不要自己编造具体数值。

服务区域在底部中的位置 ​

为什么需要:页面底部通常不是一整块文字,而是由版心继续分区。转写稿里明确说,底部先给大盒子,再给版心,版心“再分上中下是不是三部分就行了”。服务区域就是底部版心里的一块,所以不要一上来就写四个 li,要先明确它属于 .service,避免选择器影响到页面其他列表。

怎么想:服务区域本质是“四个服务承诺”的列表,用 ul > li 表达语义最合适;每个 li 里再放图标标题 h5 和说明文字 p。

怎么做:先保留笔记中的结构:

html
<ul>
  <li>
    <h5></h5>
    <p>价格亲民</p>
  </li>
  <li>
    <h5></h5>
    <p>物流快捷</p>
  </li>
  <li>
    <h5></h5>
    <p>品质新鲜</p>
  </li>
  <li>
    <h5></h5>
    <p>售后无忧</p>
  </li>
</ul>

易错点:结构写完后要先预览,不要“摁着一头写,结果发现第一行就错了,然后又开始改”。转写稿反复强调“做一做要测一测”,这里也一样:先确认四个 li 是否都在 .service 里面,再写样式。

用 flex 让四个服务项横排 ​

为什么需要:li 默认是块级元素,会竖着排列;效果图要求四个服务项在一行,所以必须让它们的父级 ul 变成伸缩容器。

怎么想:转写稿讲导航时说“他们的父亲是不是要加 flex”,这里同理:要管谁,就给谁的父亲加布局。四个 li 的父亲是 .service ul。

怎么做:

css
.service ul {
  display: flex;
  justify-content: space-evenly;
}

易错点:选择器要带 .service,不要只写 ul,否则可能影响页面其他列表;space-evenly 是平均分配剩余空间,不是简单左对齐。调试时可在浏览器检查工具里看 ul 是否真的变成 flex。

每个 li 内部图标与文字横排 ​

为什么需要:h5 和 p 默认上下排列,但效果图里图标在左、文字在右,所以 li 自己也要变成 flex 容器。

怎么想:li 给固定宽高,内部 h5 是 58×58 的图标盒子,p 用行高与 li 等高实现垂直居中。转写稿里讲垂直居中时常用“行高撑开、垂直居中”的思路,这里 line-height: 58px 就是让文字在 58px 高度里居中。

怎么做:

css
.service li {
  display: flex;
  width: 190px;
  height: 58px;
  /* background-color: pink; */
}

.service li h5 {
  margin-right: 20px;
  width: 58px;
  height: 58px;
  background-image: url(../images/sprite.png);
}

.service li p {
  font-size: 28px;
  line-height: 58px;
}

易错点:li 宽度只有 190px,要容得下 58px 图标、20px 间距和 28px 文字,调试时若文字挤掉,要先检查盒子和间距,不要盲目改行高;h5 默认有外边距时也要注意重置或覆盖。

精灵图定位四个图标 ​

为什么需要:四个小图标如果分别切图会多请求;用一张 sprite.png 通过背景定位取不同图标,是笔记里的做法。

怎么想:四个图标垂直排列在精灵图里,每个高度 58px。第一个默认在 0 0,第二个向上移动 58px,所以 background-position 的 y 值是 -58px,第三个 -116px,第四个 -174px。这就是“负值向上取图”的推导。

怎么做:

css
.service li:nth-child(2) h5 {
  background-position: 0 -58px;
}
.service li:nth-child(3) h5 {
  background-position: 0 -116px;
}
.service li:nth-child(4) h5 {
  background-position: 0 -174px;
}

易错点:nth-child 从 1 开始数,第 1 个不用写;选择器要写在 li 上再找 h5,不是直接给 h5:nth-child(2);背景图路径是相对 CSS 文件写的,路径错时四个图标都不显示。调试时先看 h5 是否为 58×58,再看 background-position 是否逐个变化。

调试与验收 ​

为什么需要:服务区域代码不长,但 flex、固定宽高、精灵图定位叠在一起,最容易出现“图标串位、文字不居中、四项不在一行”。

怎么想:按转写稿的调试顺序,先结构后样式,先父亲后孩子:ul 加 flex 管横排,li 加 flex 管图标文字横排,最后用 nth-child 改精灵图位置。转写稿说“找最近一级的爸爸”,这里就是 .service li h5、.service li p 这种层级要写清楚。

怎么做:在浏览器检查工具中逐项确认:四个 li 是否一行;每个 li 是否 190×58;h5 是否 58×58;p 的行高是否 58px;四个 h5 的背景位置是否分别为默认、-58、-116、-174。

易错点:不要给第一个 h5 再写 background-position: 0 0 也可以;但后三个必须写全 0 -58px 这种两个值。若某一项图标显示成半截,优先检查盒子高度和定位值是否对应 58 的倍数。

本节在底部中的位置 ​

本节做的是底部帮助中心的左侧区域。转写稿视频8明确说:头部结束后“应该写底部”,先把底部大盒子搭好,底部内部再用一个版心 wrapper,版心再分上中下三部分;“里面的三个盒子怎么做,我们下次再写”。因此本节应放在 footer 的版心中,先完成左侧五组帮助链接,不急着写中间和右侧。
本节笔记没有图片,故无图片可保留;下面保留原 HTML 与 CSS 代码。

用 dl、dt、dd 组织多组帮助链接 ​

为什么需要: 帮助中心不是一组普通列表,而是“购物指南、配送方式、关于我们、售后服务、服务热线”五组“标题 + 链接”的结构,用 dl 更符合语义。
怎么想: 每个 dl 表示一组,dt 写组标题,dd 写该组下的链接;五组并列放在 .left 中。
怎么做: 按笔记结构写五个 dl,每个 dt 后跟若干 dd > a;客服图标用 span.iconfont 放在链接内。
易错点: dt、dd 应直接作为 dl 的子项,不要随意改成无意义 div;占位链接统一写 href="#",避免空 href 造成刷新或跳转异常。

html
<div class="left">
  <dl>
    <dt>购物指南</dt>
    <dd><a href="#">购物流程</a></dd>
    <dd><a href="#">支付方式</a></dd>
    <dd><a href="#">售后规则</a></dd>
  </dl>
  <dl>
    <dt>配送方式</dt>
    <dd><a href="#">配送运费</a></dd>
    <dd><a href="#">配送范围</a></dd>
    <dd><a href="#">配送时间</a></dd>
  </dl>
  <dl>
    <dt>关于我们</dt>
    <dd><a href="#">平台规则</a></dd>
    <dd><a href="#">联系我们</a></dd>
    <dd><a href="#">问题反馈</a></dd>
  </dl>
  <dl>
    <dt>售后服务</dt>
    <dd><a href="#">售后政策</a></dd>
    <dd><a href="#">退款说明</a></dd>
    <dd><a href="#">取消订单</a></dd>
  </dl>
  <dl>
    <dt>服务热线</dt>
    <dd><a href="#">在线客服<span class="iconfont icon-customer-service"></span></a></dd>
    <dd><a href="#">客服电话 400-0000-000</a></dd>
    <dd><a href="#">工作时间 周一至周日 8:00-18:00</a></dd>
  </dl>
</div>

用 flex 让五组横向排列 ​

为什么需要: dl 默认是块级元素,会一组占一行;效果图要求五组横向并排。
怎么想: 横向排列应加在父容器 .left 上,而不是给每个 dl 单独写浮动。
怎么做: .help .left { display: flex; },五个 dl 自动成为一行中的 flex 项。
易错点: 不要把 display: flex 错写到 dl 上;父容器选择器要带 .help 限定,避免影响页面其他 .left。

css
.help .left {
  display: flex;
}

列间距与最后一列处理 ​

为什么需要: 五组之间要有稳定间距,最后一组右侧不应多出空白。
怎么想: 给每个 dl 统一加右外边距,再用 :last-child 把最后一组右间距清零。
怎么做: margin-right: 84px,最后一个 dl 设 margin-right: 0。
易错点: 不要给所有 dl 都保留 84px,否则右侧会多一截;last-child 要写在 .help .left dl 后面,保证优先级和范围正确。

css
.help .left dl {
  margin-right: 84px;
}

.help .left dl:last-child {
  margin-right: 0;
}

标题与链接的垂直节奏 ​

为什么需要: 组标题要明显大于链接,链接之间也要有可读间距。
怎么想: 用 dt 控制标题字号和下间距,用 dd 控制每条链接的下间距。
怎么做: dt 设 margin-bottom: 30px; font-size: 18px;,dd 设 margin-bottom: 10px;。
易错点: 字号不要写到 dd 上;最后一条 dd 仍会有 10px 下间距,通常可接受,若需极致可再单独处理,但本节按笔记保留。

css
.help .left dt {
  margin-bottom: 30px;
  font-size: 18px;
}

.help .left dd {
  margin-bottom: 10px;
}

链接颜色与客服图标强调 ​

为什么需要: 帮助链接属于辅助信息,颜色应弱化;客服图标需要绿色强调。
怎么想: 链接统一灰色,图标单独设绿色;图标选择器限定在 .help .left .iconfont 内。
怎么做: a { color: #969696; },.iconfont { color: #5EB69C; }。
易错点: 不要给 .iconfont 设全局颜色;图标 span 要放在 a 内,否则点击区域和语义都不对。

css
.help .left a {
  color: #969696;
}

.help .left .iconfont {
  color: #5EB69C;
}

整合与调试 ​

转写稿视频2提醒“做一做要测一测,不要摁着一头写,结果发现第一行就错了”;视频8也强调先搭底部大盒子和版心,再分块。按这个顺序:先确认 footer 与 wrapper 存在,再放入 .help .left,写五组 dl,最后加 flex、间距和颜色。调试时重点看五组是否一行、最后一组右侧是否无多余间距、客服图标是否绿色。易错点是小细节卡住时不要停住,先完成结构再回头微调。

先明确右侧区域在底部中的位置 ​

为什么需要:底部不是一上来就写细节,转写稿里反复强调“先搭大盒子,再放版心,再分块”。帮助中心右侧只是底部帮助中心里的一块,所以要先有 .help 这个父级,再用 .right 区分右侧二维码区。怎么想:结构上先写一个右侧容器,里面放一个 ul,两个 li 分别对应微信公众号和 APP 下载二维码。怎么做:保留下面结构,图片 alt 改成中文,便于检查图片含义。易错点:不要把两个 li 直接散在 .help 下;选择器要带 .help .right 限定,避免和页面其他 ul、p 冲突。转写稿里说“做一测一测,不要一头写”,这里也是先看结构是否在 .right 内。

html
<div class="right">
  <ul>
    <li>
      <div class="pic"><img src="./images/wechat.png" alt="微信公众号二维码"></div>
      <p>微信公众号</p>
    </li>
    <li>
      <div class="pic"><img src="./images/app.png" alt="APP下载二维码"></div>
      <p>APP下载二维码</p>
    </li>
  </ul>
</div>

用 flex 让两个二维码项横排 ​

为什么需要:li 默认是块级排列,会上下堆叠;右侧两个二维码应该左右并排。怎么想:转写稿讲导航时也是“找到它们的父亲加 flex”,这里两个 li 的父亲是 ul,所以给 ul 加 flex。怎么做:写 .help .right ul { display: flex; }。易错点:flex 加在 ul 上,不是加在 li 上;不要用浮动替代,否则还要清浮动。调完先在浏览器里看两个 li 是否同一行,再继续调间距。

css
/* right */
.help .right ul {
  display: flex;
}

用 margin-right 拉开第一项间距 ​

为什么需要:两个二维码项横排后会贴在一起,需要留出呼吸距离。怎么想:间距只加在第一项右侧最直接,第二项右侧不需要。怎么做:用 li:first-child 选中第一个 li,给 margin-right: 55px。易错点:不要两个 li 都加右边距,否则整体右侧多出空白;选择器仍要带 .help .right,避免影响别处列表。转写稿里调距离时强调“量一量、调到你满意”,这里 55px 就是笔记给定值,不要随意改结构。

css
.help .right li:first-child {
  margin-right: 55px;
}

固定二维码图片盒子尺寸 ​

为什么需要:二维码图片原始大小可能不一致,直接放 img 容易把布局撑乱。怎么想:外面套 .pic 盒子,统一宽高 120×120,再给下方文字留 10px 间距。怎么做:.help .right .pic { margin-bottom: 10px; width: 120px; height: 120px; }。易错点:只给 img 写宽高不够稳,盒子固定后图片才好对齐;margin-bottom 加在 .pic 上,不是加在 p 上。调试时可在浏览器检查 .pic 是否真是 120×120。

css
.help .right .pic {
  margin-bottom: 10px;
  width: 120px;
  height: 120px;
}

文字说明居中与颜色 ​

为什么需要:二维码下方有“微信公众号”“APP下载二维码”说明文字,要和图片居中对齐,颜色比正文浅。怎么想:文字在 p 里,所以 text-align:center 给 p;颜色用笔记里的 #969696。怎么做:.help .right p { color: #969696; text-align: center; }。易错点:text-align 不要写到 .pic 上;颜色不要写成纯黑。转写稿里也提醒类名拼写要双击检查,right、pic 写错时样式不会生效。

css
.help .right p {
  color: #969696;
  text-align: center;
}

调试顺序与常见坑 ​

为什么需要:这一块代码不长,但选择器范围、横排、间距、图片尺寸任一错都会“看起来没生效”。怎么想:按“结构是否在 .right 内 → ul 是否 flex → 第一个 li 是否有右边距 → .pic 是否 120×120 → p 是否居中变色”顺序查。怎么做:用浏览器检查元素,确认 display:flex 落在 ul 上,margin-right 落在第一个 li 上。易错点:父级选择器写得太宽会误伤其他列表;图片 alt 不要留空;转写稿里说的“版心”是内容容器,不是“钣金”,写结构时别把类名和层级弄混。

先定位:版权块在底部中的位置 ​

底部是公共区域的“尾”,转写稿里先搭的是大盒子:.footer 给高度 582px、背景 #F5F5F5,里面再用 .wrapper 版心把底部内容包起来,分成上中下三块。本节“版权”就是底部内容中的一块,不要把它写到头部或页面中间。

为什么需要:版权、帮助中心、售后服务等是整站公共信息,放在底部统一弱化展示,既不抢主体内容,又能让用户随时找到入口。
怎么想:先有大底部和版心,再写版权块;版权块内部是“一行链接 + 一行版权文字”。
怎么做:结构上用两个 p,第一个 p 放多个 a,第二个 p 放版权文字;外层用 .copyright 控制居中。
易错点:不要一上来只写版权而忘了它在 .footer > .wrapper 里;转写稿里的“点FOOT”就是 .footer,“rappper”是 wrapper,拼写要核对。

HTML结构:链接组与版权文字 ​

本节笔记给的结构是:

html
<p>
  <a href="#">关于我们</a>|
  <a href="#">帮助中心</a>|
  <a href="#">售后服务</a>|
  <a href="#">配送与验收</a>|
  <a href="#">商务合作</a>|
  <a href="#">搜索推荐</a>|
  <a href="#">友情链接</a>
</p>
<p>CopyRight © 小兔鲜</p>

为什么需要:这些链接是行内元素,放在同一个 p 里会自然横向排列;竖线 | 作为文字分隔,不需要额外盒子。
怎么想:版权区不是导航大菜单,不需要 ul/li,用 p 包 a 更轻量;每个 a 的 href 先写 # 占位。
怎么做:把链接组放在第一个 p,版权文字放在第二个 p,整体外层加 .copyright。
易错点:a 默认有蓝色和下划线,后面必须统一颜色;竖线是普通文本,不要误写成边框;CopyRight © 小兔鲜 不要拆成多个块,否则会换行。

CSS样式:居中、灰色与链接间距 ​

笔记样式:

css
/* 版权 */
.copyright {
  text-align: center;
}

.copyright p {
  margin-bottom: 10px;
  color: #A1A1A1;
}

.copyright p a {
  margin: 0 10px;
  color: #A1A1A1;
}

为什么需要:版权信息要视觉弱化,所以统一用 #A1A1A1 灰色;整体要居中,所以父级 .copyright 用 text-align: center。
怎么想:居中写在父级,颜色分别写给 p 和 a;a 不会自动继承到理想效果,需要单独覆盖颜色;链接之间用左右 margin: 0 10px 拉开距离。
怎么做:先让 .copyright 居中,再给 p 下边距 10px 和灰色,最后给 a 左右 10px 与同色。
易错点:只给 p 颜色,a 仍可能是默认蓝色;margin-bottom 会让两行版权文字有间隔,不要误写成 padding;text-align: center 对块级 p 内部的行内内容生效,但父容器要有正常宽度,别把 .copyright 写死成很小宽度。

调试顺序与常见坑 ​

按转写稿的思路,底部应先确认 .footer 的高度和背景,再确认 .wrapper 版心,最后写版权块。写版权时先看结构是否横向排列,再看是否居中,最后统一灰色和间距。

易错点:

  1. a 的颜色要单独写,不能只依赖父级 p;
  2. 链接之间的 | 是文本,前后间距由 a 的 margin 控制,别额外加很多空格;
  3. 两个 p 默认有上下外边距,笔记用 margin-bottom: 10px 控制第一行与版权文字的距离;
  4. 类名统一用 .copyright,不要和底部 .footer、版心 .wrapper 混写;
  5. 本节没有额外图片,笔记中的结构就是最终依据,先照结构写,再微调间距。

课件图示(PPTX) ​

day10 课件图

代码示例 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>头部-购物车</title>
  <style>
    /* car */
    .car {
      position: relative;
      margin: 20px 0 0 15px;
    }

    .car i {
      font-size: 36px;
    }

    .car span {
      position: absolute;
      top: 0;
      left: 22px;
      padding: 0 8px;
      background-color: #E26237;
      color: #fff;
      border-radius: 11px;
    }
  </style>
</head>
<body>
  <!-- car 车 -->
  <div class="car">
    <i class="iconfont icon-cart-full"></i>
    <span>2</span>
  </div>
</body>
</html>

要点解释:

  • .car 设置 position: relative,给里面的 span 做绝对定位参照,属于“父相子绝”。
  • .car span 使用 position: absolute; top: 0; left: 22px;,把数量徽标压到购物车图标右侧。
  • span 用 padding: 0 8px 横向撑开,不要写死宽度;转写稿中特别强调数字变多时应让盒子自动撑大。
  • 易错点:数量徽标用 left 而不是 right;转写稿中说明若用右侧对齐,数字越多会往左长,不符合“小车徽标向右撑开”的预期。
  • iconfont 需要项目已有对应字体类,笔记中只给了 class,没有给字体文件引入代码。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>底部-布局/服务/帮助中心/版权</title>
  <style>
    /* 底部 */
    .footer {
      height: 580px;
      background-color: #F5F5F5;
    }

    /* 服务 */
    .service {
      padding: 60px 0;
      height: 178px;
      border-bottom: 1px solid #E8E8E8;
    }

    .service ul {
      display: flex;
      justify-content: space-evenly;
    }

    .service li {
      display: flex;
      width: 190px;
      height: 58px;
      /* background-color: pink; */
    }

    .service li h5 {
      margin-right: 20px;
      width: 58px;
      height: 58px;
      background-image: url(../images/sprite.png);
    }

    .service li p {
      font-size: 28px;
      line-height: 58px;
    }

    .service li:nth-child(2) h5 {
      background-position: 0 -58px;
    }

    .service li:nth-child(3) h5 {
      background-position: 0 -116px;
    }

    .service li:nth-child(4) h5 {
      background-position: 0 -174px;
    }

    /* 帮助中心 */
    .help {
      display: flex;
      justify-content: space-between;
      padding-top: 60px;
      height: 300px;
      background-color: pink;
    }

    /* left */
    .help .left {
      display: flex;
    }

    .help .left dl {
      margin-right: 84px;
    }

    .help .left dl:last-child {
      margin-right: 0;
    }

    .help .left dt {
      margin-bottom: 30px;
      font-size: 18px;
    }

    .help .left dd {
      margin-bottom: 10px;
    }

    .help .left a {
      color: #969696;
    }

    .help .left .iconfont {
      color: #5EB69C;
    }

    /* right */
    .help .right ul {
      display: flex;
    }

    .help .right li:first-child {
      margin-right: 55px;
    }

    .help .right .pic {
      margin-bottom: 10px;
      width: 120px;
      height: 120px;
    }

    .help .right p {
      color: #969696;
      text-align: center;
    }

    /* 版权 */
    .copyright {
      text-align: center;
    }

    .copyright p {
      margin-bottom: 10px;
      color: #A1A1A1;
    }

    .copyright p a {
      margin: 0 10px;
      color: #A1A1A1;
    }
  </style>
</head>
<body>
  <!-- 底部 -->
  <div class="footer">
    <div class="wrapper">
      <!-- 服务 -->
      <div class="service">
        <ul>
          <li>
            <h5></h5>
            <p>价格亲民</p>
          </li>
          <li>
            <h5></h5>
            <p>物流快捷</p>
          </li>
          <li>
            <h5></h5>
            <p>品质新鲜</p>
          </li>
          <li>
            <h5></h5>
            <p>售后无忧</p>
          </li>
        </ul>
      </div>

      <!-- 帮助中心 -->
      <div class="help">
        <div class="left">
          <dl>
            <dt>购物指南</dt>
            <dd><a href="#">购物流程</a></dd>
            <dd><a href="#">支付方式</a></dd>
            <dd><a href="#">售后规则</a></dd>
          </dl>
          <dl>
            <dt>配送方式</dt>
            <dd><a href="#">配送运费</a></dd>
            <dd><a href="#">配送范围</a></dd>
            <dd><a href="#">配送时间</a></dd>
          </dl>
          <dl>
            <dt>关于我们</dt>
            <dd><a href="#">平台规则</a></dd>
            <dd><a href="#">联系我们</a></dd>
            <dd><a href="#">问题反馈</a></dd>
          </dl>
          <dl>
            <dt>售后服务</dt>
            <dd><a href="#">售后政策</a></dd>
            <dd><a href="#">退款说明</a></dd>
            <dd><a href="#">取消订单</a></dd>
          </dl>
          <dl>
            <dt>服务热线</dt>
            <dd><a href="#">在线客服<span class="iconfont icon-customer-service"></span></a></dd>
            <dd><a href="#">客服电话 400-0000-000</a></dd>
            <dd><a href="#">工作时间 周一至周日 8:00-18:00</a></dd>
          </dl>
        </div>

        <div class="right">
          <ul>
            <li>
              <div class="pic"><img src="./images/wechat.png" alt=""></div>
              <p>微信公众号</p>
            </li>
            <li>
              <div class="pic"><img src="./images/app.png" alt=""></div>
              <p>APP下载二维码</p>
            </li>
          </ul>
        </div>
      </div>

      <!-- 版权 -->
      <div class="copyright">
        <p>
          <a href="#">关于我们</a>|
          <a href="#">帮助中心</a>|
          <a href="#">售后服务</a>|
          <a href="#">配送与验收</a>|
          <a href="#">商务合作</a>|
          <a href="#">搜索推荐</a>|
          <a href="#">友情链接</a>
        </p>
        <p>CopyRight © 小兔鲜</p>
      </div>
    </div>
  </div>
</body>
</html>

要点解释:

  • .footer 使用笔记中的 height: 580px 和 background-color: #F5F5F5,内部用 .wrapper 包住服务、帮助中心、版权三块。
  • .service 使用 padding: 60px 0,同时写了 height: 178px;默认 content-box 下高度会把 padding 叠加进去,这是易错点。
  • .service li h5 使用雪碧图 ../images/sprite.png,通过 nth-child(2/3/4) 改 background-position 切换图标;实际项目路径要按图片目录调整。
  • .help 中 background-color: pink; 是笔记中的调试背景,实际页面应去掉。
  • 帮助中心左侧 .left 用 display: flex,每个 dl 用 margin-right: 84px 拉开,最后一个 dl:last-child 去掉右边距。
  • 右侧 .right li:first-child 控制第一项右边距;.pic 只给了盒子宽高,笔记中未给 img 宽高,实际项目通常还需要补图片尺寸样式。
  • 版权链接样式限定在 .copyright p a,避免影响页面其它 a 链接,这是作用域易错点。

常见错误 ​

1. logo 文字隐藏了,但页面右侧多出一条横向滚动条

  • 现象:text-indent: -9999em 写上了,logo 也正常,但整个页面可以左右拖动。
  • 原因:首行缩进只是把文字"推到左边看不见",元素本身没被裁剪,被推出去的部分仍然占据可滚动区域。
  • 修法:在同一个 a 上补 overflow: hidden(并确保 a 有确定的宽高),形成"推出去 + 裁剪掉"的双保险。

2. logo 图只显示一半,或被压扁

  • 现象:给 a 设了 width: 100%; height: 100%,背景图只露出上半截。
  • 原因:a 的百分比高度参照的是父级 h1,而 h1 是内容撑高的(约 48px),并非 logo 图本身的 88px。
  • 修法:别用百分比,直接给 a 写死高度 height: 88px; width: 100%;或反过来先给 h1 定高再让 a 继承。

3. 导航下划线贴着文字,鼠标经过时点击区域很小

  • 现象:a:hover 的下边框紧贴文字底部,鼠标稍微偏一点就点不到。
  • 原因:a 默认是行内元素,高度由字号决定,line-height 撑不出盒子高度。
  • 修法:先 display: block,再给 line-height(如 42px)把盒子撑高,下边框自然落到盒子底部;li 之间用 margin 或给 a 左右 margin 打开间距。

4. 搜索框聚焦变长时,放大镜被挤到下一行

  • 现象:输入框一获得焦点,放大镜图标"掉"到输入框下面。
  • 原因:放大镜是标准流盒子占位置,input 从 170px 变成 220px 后一行装不下,只能换行。
  • 修法:给放大镜 position: absolute 使其脱离标准流(父级 .search 设 position: relative),同时 .search 必须写死 width: 220px,否则拉长时会把旁边的购物车一起推走。

5. 购物车角标数字一多就往左溢出,甚至跑出车外

  • 现象:数字从 2 改成 200 时,角标向左扩张,盖住图标甚至越界。
  • 原因:用了 right 定位(右对齐),盒子以右边缘为锚点,宽度增加只能往左长。
  • 修法:改成 left: 22px 左对齐锚点,数字变大时向右自然扩展;同时角标只给 padding: 0 8px,绝不给固定 width。

6. 底部区域高度对不上,.help 把页面撑高

  • 现象:.footer 写 580px,但实际渲染更高,版权区被挤到灰色背景外面。
  • 原因:height 与 padding 同时存在时,默认盒模型下两者相加(300 + 60 = 360),padding 把盒子撑破了。
  • 修法:二选一——把 height 减去 padding(height: 240px),或改用 margin-top 替代 padding-top,或统一加 box-sizing: border-box。.service 的 padding: 60px 0 + height: 178px 同理。

7. input 的提示文字颜色改不动

  • 现象:给 input 写 color: #ccc,但"搜一搜"三个字仍是深色。
  • 原因:占位文字不属于 input 的文本内容,color 管不到它。
  • 修法:用伪元素选择器 input::placeholder { color: #ccc; } 单独设置。

练习 ​

1. logo 隐藏文字的两种方案对比 分别用"font-size: 0"、"text-indent: -9999em + overflow: hidden"实现 logo 文字隐藏,在浏览器里各做一次"鼠标手贱拖选"测试,写三句话说明:哪种在搜索引擎视角下更"诚实",为什么。

2. 购物车角标压力测试 把角标数字依次改成 2、99、9999,截图对比。要求:角标永远不溢出、不换行、不遮挡小车图标,且数字变大时向右扩展。写出你最终定稿的 position / top / left 三个值和理由。

3. 搜索框联动效果复现 实现:默认 input 宽 170px,聚焦时平滑变长到 220px,放大镜始终固定在左侧不位移。写出关键的三条规则(input:focus、过渡写在哪、放大镜与父级的定位关系),并回答:如果 .search 不写 width: 220px 会发生什么?

4. 盒模型溢出修复.footer { height: 580px } 内含 .service { height: 178px; padding: 60px 0 } 和 .help { height: 300px; padding-top: 60px }。先算出实际总高,再用两种不同方法修正到刚好 580px,并说明各自副作用。

5. 精灵图扩展 现有四个服务项分别取 0 0、0 -58px、0 -116px、0 -174px。若要新增第五个图标,写出它的 background-position 计算公式;再回答:如果某个 li 漏写 width 和 height,页面上会看到什么现象?

原视频对照 ​

#视频时长
1logo优化09:18
2导航nav部分14:23
3search搜索开始11:06
4search部分完成07:52
5小问题01:51
6购物车模块开始08:43
7购物车结束03:54
8底部开始04:06

小结 ​

  1. 隐藏文字优先选"缩进 + 裁剪"方案而非 font-size: 0:前者不篡改文字本身,对搜索引擎更友好,这是大厂通行做法。
  2. 百分比宽高永远相对于父级,遇到"图只显示一半",先去看父级实际高度,而不是怀疑图片路径。
  3. 行内元素想拥有可靠的可点击区域和下边框,先 display: block 再撑 line-height,这是导航、按钮类元素的通用套路。
  4. 绝对定位的本质是"脱离标准流、不占位置";凡是"变长/变宽时把兄弟挤走"的问题,答案几乎都是给那个兄弟加绝对定位 + 给父级加相对定位。
  5. 尺寸会变的元素(角标、标签、气泡)一律用 padding 撑,禁止写死 width;锚点方向决定扩展方向,左对齐才会向右长。
  6. 写死父容器宽度是"防抖动"的关键手段:搜索框父级不写 220px,输入框一拉长整行都会跳。
  7. height 与 padding 在默认盒模型下会相加,凡是"总高对不上"的排版,先查盒模型,再查外边距塌陷。
  8. 选择器一律从最近的父级写起(.header .nav li a),页面里 ul/li/a/i 满天飞,不带父级迟早打架。