Skip to content

小兔鲜儿(三) ​

本页对应 小兔鲜儿,共 7 段视频,约 47 分钟。

学习目标 ​

  • 能够使用 ::before/::after 伪元素完成 banner 小圆点的实心圆与半透明选中态,并通过 position、padding、border-radius 调整到居中位置。
  • 能够将 banner 侧边栏作为 wrapper 内与图片、小圆点同级的兄弟盒子搭建,使用绝对定位、宽高和 rgba 半透明背景实现覆盖在图片左侧的效果。
  • 能够编写侧边栏 ul > li > a 的多链接结构,并通过 li 高度、行高、左内边距、链接颜色与字号、:first-child、li:hover 完成列表项样式。
  • 能够仅用 li::after 配合定位、content、字体图标字体族实现侧边栏右侧箭头,不增加额外 HTML 标签,并验证所有列表项箭头一致显示。
  • 能够搭建“新鲜好物”模块的 wrapper > hd + bd 结构,使用 display:flex 与 justify-content:space-between 完成标题、副标题与“查看全部”链接的左右布局及上下间距。

知识点 ​

侧导航的目标与定位思路 ​

为什么需要:banner 图上要压一层分类导航,宽 250、高 500,半透明黑底,鼠标经过某一项时高亮。
怎么想:转写稿里明确说,侧边栏和轮播图、小圆点都放在 wrapper 里,是兄弟关系;侧边栏要压住图片,所以用绝对定位。父级 wrapper 已设相对定位,这里直接 absolute 即可。
怎么做:先写 .subnav,再定位到 left:0; top:0,背景用 rgba(0,0,0,.42)。
易错点:不要给 .banner 乱加定位,定位参照应是同一父级的 wrapper;半透明背景用 rgba,不要用 opacity,否则子元素也会一起透明。

HTML结构:一个 li 装多个链接 ​

为什么需要:转写稿用京东、淘宝举例:生鲜、水果、蔬菜是不同页面,所以一个 li 里要放多个 a,不能只放一个链接。
怎么想:外层 .subnav > ul > li,每个 li 里放 1 个主链接 + 若干子链接。
怎么做:保留下面结构,先全部用 # 占位。

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>

易错点:不要把每个分类写成单独一个 li 只放一个 a;后面第一个 a 要单独变大,必须有“兄弟”才能用 :first-child 选中。

CSS样式与调试要点 ​

为什么需要:li 高 50、行高 50 让文字垂直居中;padding-left:29px 让文字往里走,而不是盒子跑。
怎么想:li 设 position:relative,给 ::after 做定位参照;箭头统一用伪元素生成,避免 HTML 里复制 10 个 i。
怎么做:::after 必须有 content:"\e687",字体图标还要声明 font-family: iconfont;。\e687 是右箭头,转写稿说不要背,打开 iconfont.css 查;左箭头可能是 \e685。
易错点:忘写 content 或 font-family 会显示小方框;hover 变色给 li,不要给 a,因为 a 是点击跳转;所有 a 先设白色 14px,再用 a:first-child 把第一个改成 16px 并加右边距。

转写稿里还有一个重要调试:给 li 加粉色背景后发现它不通栏,检查继承发现 ul 继承了上面的 flex。解决是给亲儿子选择器加 >,只选当前层级的 ul,避免影响 .subnav 里的孙子 ul。调试时先加背景色看盒子,再看“层叠/继承”,不要只盯代码。

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;
}

目标与公共样式:先做可复用的模块头 ​

新鲜好物头部效果图

这一节只完成“新鲜好物”的头部 hd,下面的商品列表暂不展开。为什么需要先考虑公共样式?因为后面还会出现类似“模块标题 + 查看全部”的结构,如果把样式写死在某个父级里,复用时会很麻烦。怎么想?把头部统一命名为 hd,把内容区命名为 bd,CSS 直接写 .hd、.bd,不要过度依赖父级选择器。怎么做?先在 wrapper 版心里放 hd,再在 hd 中放标题和“查看全部”。易错点:不要把 hd 放到 banner 里面,也不要把结构套错;转写稿里也反复提醒,先折叠上面已完成的 banner,再写新模块,避免旧样式干扰观察。

HTML 结构:h2 里用 span,查看全部单独起类名 ​

html
<div class="wrapper">
  <!-- 上侧 hd  -->
  <div class="hd">
    <h2>新鲜好物
      <span>新鲜出炉 品质靠谱</span>
    </h2>
    <a href="#" class="all">
      查看全部
      <i class="iconfont icon-arrow-right-bold"></i>
    </a>
  </div>
</div>

为什么需要这样写?主标题“新鲜好物”和副标题“新鲜出炉 品质靠谱”要在同一行,所以副标题用 span 放在 h2 里面;如果写成 p,它会独占一行,后面还得额外处理。怎么想?h2 负责标题语义,span 负责副标题样式;“查看全部”是链接,并且页面里可能还有别的 a,所以给它单独加 class="all",避免选择器误伤。怎么做?先写 wrapper,再写 hd,hd 里先放 h2,h2 里包 span,再放 a.all 和字体图标 i。易错点:span 不要放到 h2 外面;a 不要只写标签选择器;图标类名要保留,后面才能显示右箭头。

CSS:flex 让标题和“查看全部”左右分布 ​

css
/* 新鲜好物 */
/* 新鲜好物 */
.hd {
  display: flex;
  justify-content: space-between;
  /* 侧轴垂直居中 */
  align-items: center;
  padding: 40px 0 30px;

}

.hd h2 {
  font-size: 30px;
}

.hd h2 span {
  font-size: 16px;
  color: var(--hui);
  margin-left: 30px;
}

.hd .all {
  font-size: 16px;
  color: var(--hui);
}

.hd .all:hover {
  color: var(--lv);
}

为什么需要 flex?h2 和 a 默认不会自然形成“左边标题、右边查看全部”的布局。怎么想?父级 .hd 加 display:flex,让子项一行排列;justify-content:space-between 让两端对齐;align-items:center 让它们在侧轴垂直居中。怎么做?给 .hd 设置上下内边距 40px 0 30px,即上 40、左右 0、下 30;标题 30px;副标题 16px、灰色、左间距 30px;“查看全部”16px、灰色,悬停变绿色。易错点:padding 顺序别写反;不要用 float 硬做;var(--hui)、var(--lv) 是项目公共颜色变量,若项目没有变量要按实际项目处理,不能随意改结构。

调试过程:先看盒子,再补细节 ​

转写稿里的调试思路是:先写 wrapper 看版心是否出现,再写 hd 和 bd;给 .hd 加 padding 后观察上下距离;h2 和 a 默认上下排列,加上 flex 后才在一行;副标题原来若用 p 会独占一行,所以换成 span。为什么需要这样调试?因为先看盒子边界,才能判断结构有没有套错。怎么做?保存后看页面,必要时用检查工具看盒子位置;发现“查看全部”选择器可能影响别的链接,就用 .all 限定。易错点:写完不保存、结构层级放错、选择器过泛,都会让样式看起来“没生效”。

先看整体:bd 是“新鲜好物”的下半区 ​

为什么需要:一个商品模块通常分成头部 HD 和内容 BD。HD 放标题、查看更多,BD 专门承载商品卡片列表,结构清楚,样式也好复用。
怎么想:本节只处理 BD,所以外层用 .bd,里面用 ul > li > a 组织商品。转写稿里强调“不要一上来把 HTML 全写完”,先把 BD 盒子、宽高、背景色搭出来,看到盒子,再一层层放 ul、空 li、pic、h4、p。
怎么做:先保留下面结构,图片 alt 改成中文,便于说明商品图。
易错点:不要把 .bd 套错父级;先折叠上面 banner 部分,确认本节只改新鲜好物下半区。

html
<!-- 下部分 bd  -->
    <div class="bd">
      <ul>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="KN95级莫兰迪色防护口罩商品图">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="KN95级莫兰迪色防护口罩商品图">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="KN95级莫兰迪色防护口罩商品图">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="KN95级莫兰迪色防护口罩商品图">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
      </ul>
    </div>

列表布局:ul 用 flex 一行排开 ​

为什么需要:四张商品卡要横向等距排列,用浮动也可以,但 flex 更直接。
怎么想:父级 ul 负责“排成一行并两端对齐”,子级 li 负责固定尺寸。
怎么做:display:flex 加 justify-content:space-between。
易错点:li 固定 304px,父容器宽度要够;若出现换行或挤压,先检查 ul 默认内外边距是否被公共样式清掉。

卡片:li 尺寸、背景与悬停 ​

为什么需要:商品卡需要统一底色和鼠标经过反馈,提升可点击感。
怎么想:把尺寸、背景、过渡都放在 li 上;悬停时上移并加阴影。
怎么做:width:304px;height:404px;background:#EEF9F4;transition:all .3s;,hover 时 margin-top:-5px 和 box-shadow。
易错点:transition 写在 li 本身,不是写在 :hover 里;阴影用 rgba(0,0,0,.42),不要写成不透明黑。

链接与图片:a 撑满,pic 固定 ​

为什么需要:整张卡片最好都能点击,图片区域要稳定占位。
怎么想:a 变成块级并撑满 li,pic 固定 304×304。
怎么做:a{display:block;height:100%;},.pic{width:304px;height:304px;background:skyblue;}。
易错点:a 不设块级时高度撑不满;图片加载前 .pic 的背景色可用于检查占位是否正确。

标题与价格:层级和溢出 ​

为什么需要:标题要突出,价格要醒目,数字要比“¥”更大。
怎么想:h4 控制标题字号和间距,p 控制价格颜色,span 单独放大数字。
怎么做:h4 设 font-size:20px;margin:18px 15px 9px;,p 设 #AA2113、17px,span 设 22px。
易错点:HTML 里 h4 带了 text-overflow 类,说明标题依赖公共单行溢出规则;调试时确认该类是否生效,否则长标题会换行撑高卡片。

css
/* 好物内容 -- 公共样式 */

.bd ul {
  display: flex;
  justify-content: space-between;
}

.bd ul li {
  width: 304px;
  height: 404px;
  background-color: #EEF9F4;
  text-align: center;
  transition: all .3s;
}

.bd ul li:hover {
  margin-top: -5px;
  box-shadow: 0 15px 30px rgba(0, 0, 0, .42);
}

.bd ul li a {
  display: block;
  height: 100%;
}

.bd ul li .pic {
  width: 304px;
  height: 304px;
  background-color: skyblue;
}

.bd ul li h4 {
  font-size: 20px;
  margin: 18px 15px 9px;

}

.bd ul li p {
  color: #AA2113;
  font-size: 17px;
}

.bd ul li p span {
  font-size: 22px;
}

调试顺序:一块一块看效果 ​

转写稿提醒:写的时候不要按着 HTML 一口气全写完。先写 .bd 看盒子,再放 ul 和一个空 li,给 li 宽高背景色,确认卡片尺寸;再放 pic、h4、p。这样一出问题就能定位是布局、尺寸还是文字样式。易错点是只盯代码不检查盒子,建议用浏览器检查工具逐层看宽高和继承样式。

课件图示(PPTX) ​

day11 课件图

day11 课件图

day11 课件图

代码示例 ​

示例 1:banner 侧导航(subnav) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>banner 侧导航</title>
  <!-- 字体图标样式表,按项目实际路径引入 -->
  <!-- <link rel="stylesheet" href="./iconfont/iconfont.css"> -->
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    li { list-style: none; }
    a { text-decoration: none; }

    :root {
      --lv: #27ba9b;   /* 主题绿,按设计稿色值替换 */
      --hui: #999;     /* 辅助灰,按设计稿色值替换 */
    }

    .banner { height: 500px; background: #f5f5f5; }

    /* 关键:侧边栏的定位父级 */
    .banner .wrapper {
      position: relative;
      width: 1240px;
      height: 500px;
      margin: 0 auto;
    }

    .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;
    }

    .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;
    }
  </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>

关键行与易错点

  • .banner .wrapper { position: relative; } 是整段的前提。subnav 用 position: absolute 后,会向上找最近的定位父级;不给 wrapper 相对定位,侧边栏会跑到浏览器左上角,而不是压在轮播图左侧。
  • ::after 必须写 content,否则伪元素根本不生成。content: "\e687" 与 font-family: iconfont; 缺一不可:不声明字体,\e687 只会显示成一个小方框。
  • 一个 li 里放的是 3 个 a(生鲜 / 水果 / 蔬菜分别跳到不同页面),不是一个 a 包全部文字。所以放大第一个用 a:first-child,而不是 li:first-child。
  • :hover 写在 li 上而不是 a 上:整行 50px 高都要变底色,且 a 之间有空隙,写在 a 上会一段一段变色。
  • 如果项目里给 .wrapper > ul 加过 display: flex,一定要用子代选择器 >。否则 subnav 里的 ul 也会被匹配到,li 会变成按内容收缩宽度,而不是通栏 250px。

示例 2:新鲜好物 hd(模块头部) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>新鲜好物 - hd</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    a { text-decoration: none; }

    :root {
      --lv: #27ba9b;
      --hui: #999;
    }

    .wrapper {
      width: 1240px;
      margin: 0 auto;
    }

    /* 新鲜好物 */
    .hd {
      display: flex;
      justify-content: space-between;
      /* 侧轴垂直居中 */
      align-items: center;
      padding: 40px 0 30px;
    }

    .hd h2 {
      font-size: 30px;
    }

    .hd h2 span {
      font-size: 16px;
      color: var(--hui);
      margin-left: 30px;
    }

    .hd .all {
      font-size: 16px;
      color: var(--hui);
    }

    .hd .all:hover {
      color: var(--lv);
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <!-- 上侧 hd -->
    <div class="hd">
      <h2>新鲜好物
        <span>新鲜出炉 品质靠谱</span>
      </h2>
      <a href="#" class="all">
        查看全部
        <i class="iconfont icon-arrow-right-bold"></i>
      </a>
    </div>
  </div>
</body>
</html>

关键行与易错点

  • display: flex 加在 .hd 上,让 h2 和右侧 a 排到一行;justify-content: space-between 让它们左右贴边,align-items: center 让侧轴垂直居中。
  • h2 里的副标题必须用 span(行内元素)。如果写成 p,p 是块级元素,会把标题和副标题顶成两行,flex 也救不回来。
  • 右侧 a 单独起类名 .all,不要用 .hd a 这种后代选择器。模块里链接一多,后代选择器很容易误伤。
  • padding: 40px 0 30px 是上 40、左右 0、下 30。左右留白交给 .wrapper 的宽度控制,不要在这里写左右 padding。
  • --lv、--hui 是项目自定义属性,必须先定义,否则 var() 取值失败,颜色会变成无效值。

示例 3:新鲜好物 bd(商品列表) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>新鲜好物 - bd</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    li { list-style: none; }
    a { text-decoration: none; color: #333; }

    .wrapper {
      width: 1240px;
      margin: 0 auto;
    }

    /* 好物内容 -- 公共样式 */
    .bd ul {
      display: flex;
      justify-content: space-between;
    }

    .bd ul li {
      width: 304px;
      height: 404px;
      background-color: #EEF9F4;
      text-align: center;
      transition: all .3s;
    }

    .bd ul li:hover {
      margin-top: -5px;
      box-shadow: 0 15px 30px rgba(0, 0, 0, .42);
    }

    .bd ul li a {
      display: block;
      height: 100%;
    }

    .bd ul li .pic {
      width: 304px;
      height: 304px;
      background-color: skyblue;
    }

    .bd ul li h4 {
      font-size: 20px;
      margin: 18px 15px 9px;
    }

    .bd ul li p {
      color: #AA2113;
      font-size: 17px;
    }

    .bd ul li p span {
      font-size: 22px;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <!-- 下部分 bd -->
    <div class="bd">
      <ul>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
        <li>
          <a href="#" title="KN95级莫兰迪色防护口罩">
            <div class="pic">
              <img src="./uploads/goods1.png" alt="">
            </div>
            <h4 class="text-overflow">KN95级莫兰迪色防护口罩你值得拥有</h4>
            <p>¥ <span>99.00</span></p>
          </a>
        </li>
      </ul>
    </div>
  </div>
</body>
</html>

关键行与易错点

  • ul 用 display: flex; justify-content: space-between; 一行排 4 个卡片;li 固定 304px,4×304 加间距正好填满版心。
  • a 必须 display: block; height: 100%;,让整张卡片(含空白处)都能点击。行内 a 只有文字区域可点。
  • transition: all .3s 要写在 li 上,不能写在 li:hover 里,否则移开鼠标时没有过渡,会“啪”地弹回去。
  • li:hover 用 margin-top: -5px 上移,配合 box-shadow 做悬浮效果;注意负 margin 会改变元素在 flex 中的位置,不要再用 transform 重复位移。
  • text-align: center 写在 li 上,图片、标题、价格一起居中,不用逐个设置。
  • 价格只放大数字:p span 单独写 22px,¥ 保持 p 的 17px,层级不要写反。
  • h4 上的 text-overflow 是项目的单行省略工具类,本段笔记未给出它的具体声明,需要另行定义(或先删掉该类名),否则长标题会换行撑高卡片。图片 src 也要按实际项目路径替换。

常见错误 ​

  • 侧边栏跑到 banner 左上角、宽度压不满或偏移
    现象:.subnav 定位后没贴住轮播图左上角,或被挤到页面外。
    原因:position: absolute 参照的是最近一个定位祖先,只给 .banner 写了定位,而实际要参照的是 .banner .wrapper。
    修法:给 .banner .wrapper 加 position: relative,.subnav 写 left: 0; top: 0。

  • 侧边栏每一行只剩一小截,背景色只铺了半行
    现象:li 高度 50px 有了,但宽度跟着文字走,粉色背景很短。
    原因:.banner .wrapper ul 里的 display: flex 写成了后代选择器,把 .subnav 内部的 ul(孙子)也命中了,li 变成 flex 项目按内容撑开。
    修法:改成子代选择器 .banner .wrapper > ul { display: flex; },只作用于亲儿子。

  • 伪元素写了 content 却什么都不显示
    现象:::after 已写 content: "",页面看不到盒子。
    原因:伪元素默认是行内元素,没有宽高,也没定位。
    修法:display: block + width/height + position: absolute(父级 li 补 position: relative)。

  • 右箭头显示成一个小方块(豆腐块)
    现象:content: "\e687" 出来是方框而不是箭头。
    原因:只写了字符编码,没声明字体图标字体,浏览器用默认字体渲染该码位。
    修法:补 font-family: iconfont;(名字取自 iconfont.css),编码到 iconfont.css 里核对,不要背。

  • 小圆点无法居中,总是贴着左上角
    现象:22×22 的 li 里,14×14 的 ::after 偏在角上。
    原因:只给伪元素设了宽高,没做居中处理。
    修法:li 上 padding: 4px(22 = 14 + 4 + 4)把小球挤到中间;或伪元素 left/top: 50% + transform 居中。

  • 鼠标经过整行不变色,只有点到文字才变色
    现象:hover 高亮区域和行高不一致,右侧空白区不响应。
    原因::hover 写在 a 上,而 a 是行内元素,只覆盖文字范围。
    修法::hover 写在 li 上,a 只负责颜色与字号。

  • .hd 里标题和"查看全部"分两行
    现象:h2 和 a 上下排列,两端对齐不生效。
    原因:h2 是块级元素独占一行;justify-content 没生效是因为父级没变成 flex 容器。
    修法:.hd { display: flex; justify-content: space-between; align-items: center; };h2 里的副标题用 span 而不是 p,避免再次独占一行。

  • 商品卡 hover 时整行内容跟着抖动
    现象:鼠标移上去卡片上移,周围元素也被顶动。
    原因:用 margin-top: -5px 改的是布局位置,会影响文档流。
    修法:改 transform: translateY(-5px),配合 transition,不影响其他元素。

练习 ​

  1. 现有 .banner .wrapper 内有轮播图 ul、小圆点 ol、侧边栏 .subnav,请只给轮播图那一层 ul 加 flex,写出选择器,并说明为什么不能用 .banner .wrapper ul。

  2. 不给 HTML 增加任何标签,用 ::after + 字体图标为 .subnav 的 10 个 li 各加一个右侧白色箭头,要求:箭头距右 29px、垂直居中、hover 变色时箭头不变色。写出完整 CSS。

  3. 小圆点结构为 <ol class="circle"><li class="active"></li><li></li><li></li></ol>,li 22×22、内部 ::after 14×14。请写出让小白点居中、且只有 active 项显示半透明底圈的 CSS。

  4. 把"新鲜好物"的 .hd 改造成可复用头部:左侧 h2 内含主标题 + 灰色副标题,右侧"查看全部 + 箭头",要求两端对齐、垂直居中、上下内边距 40/30,且副标题不与主标题换行。

  5. 商品卡 li 尺寸 304×404,h4 需单行省略。请补全让 text-overflow: ellipsis 真正生效所需的全部声明,并说明缺哪一条会失效。

原视频对照 ​

#视频时长
1小圆点继续08:21
2banner侧边栏盒子搭建04:24
3banner盒子侧边栏开始09:19
4banner侧边栏链接处理05:46
5banner侧边栏右箭头处理10:12
605-12_18-13-3101:39
7新鲜好物模块头部开始07:25

小结 ​

  1. 伪元素的三个必要条件是 content、盒模型(display + 宽高)、定位参照(父级 position: relative),缺一个就"看不见"或"跑偏"。
  2. 字体图标在 ::after 中使用时,content 里的编码与 font-family 必须成对出现,二者缺一即为方块。
  3. 后代选择器会把孙级元素一起选中,凡是父容器要加布局属性(flex/浮动),一律优先用 > 限定层级。
  4. padding 推动内容、margin 推动盒子;行内文字缩进、小圆点居中都用 padding。
  5. :hover 的挂载点决定响应区域:整行交互挂 li,跳转行为留给 a。
  6. 模块化命名(.hd / .bd)不带父级前缀,才能被下方多个模块复用。
  7. 位移类交互统一用 transform,避免 margin 引发的文档流抖动。
  8. 写页面的顺序是"先盒子(宽高背景色)→ 再结构 → 再细节",一次只加一层,加完立刻用检查工具验证。