Skip to content

学成在线(三) ​

本页对应 学成在线,共 7 段视频,约 45 分钟。

学习目标 ​

  1. 能够将推荐课程、前端开发工程师区域按“左右/上下”结构拆分,并使用带父级限定的类选择器完成盒子命名与样式编写,避免影响页面其他模块。
  2. 能够使用 Flex 布局实现指定区域的左右两端对齐、右侧上下分区及底部三列横向排列,并按标注设置宽高、背景、外边距与内边距。
  3. 能够独立完成底部通栏盒子与版心布局,制作左侧 Logo、说明文字、下载 App 按钮及右侧 DL/DT/DD 链接列表,并实现链接 hover 颜色效果。
  4. 能够识别并修复单行 Flex 子项宽度塌陷问题,通过限定类名补充宽度并保持其他模块样式不受影响。
  5. 能够运用“高度剩余法”设置 DT/DD 高度来控制底部链接列表间距,并通过复制结构复用已有样式完成重复模块。
  6. 能够按作业要求补全页面底部并从整体复现学生在线页面,检查结构、命名、布局与样式复用是否符合页面效果。

知识点 ​

先明确本节目标:把“课程卡片”的内容区样式定下来 ​

推荐课程列表不是简单堆文字,而是“封面图 + 标题 + 级别/学习人数”的卡片。外层用 ul > li > a,是为了让整张卡片可点击;a 里再分 .pic 和 .text,分别控制图片区和文字区。这样做的原因是:图片和文字职责分开,后续调高度、背景、间距不会互相牵连。易错点是结构必须统一,每个 li 都保持同样的层级,否则共用 .bd li ... 样式时会有的生效、有的不生效。

HTML结构:整卡可点,图片和文字分区 ​

html
<ul>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course01.png" alt="JavaScript数据看板项目实战课程封面"></div>
      <div class="text">
        <h4>JavaScript数据看板项目实战</h4>
        <p><span>高级</span> · <i>1125</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course02.png" alt="Vue.js实战面经全端项目课程封面"></div>
      <div class="text">
        <h4>Vue.js实战——面经全端项目</h4>
        <p><span>高级</span> · <i>2726</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course03.png" alt="玩转Vue全家桶iHRM人力资源项目课程封面"></div>
      <div class="text">
        <h4>玩转Vue全家桶,iHRM人力资源项目</h4>
        <p><span>高级</span> · <i>9456</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course04.png" alt="Vue.js实战医疗项目优医问诊课程封面"></div>
      <div class="text">
        <h4>Vue.js实战医疗项目——优医问诊</h4>
        <p><span>高级</span> · <i>7192</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course05.png" alt="小程序实战小兔鲜电商小程序项目课程封面"></div>
      <div class="text">
        <h4>小程序实战:小兔鲜电商小程序项目</h4>
        <p><span>高级</span> · <i>2703</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course06.png" alt="前端框架Flutter开发实战课程封面"></div>
      <div class="text">
        <h4>前端框架Flutter开发实战</h4>
        <p><span>高级</span> · <i>2841</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course07.png" alt="熟练使用React.js极客园H5项目课程封面"></div>
      <div class="text">
        <h4>熟练使用React.js——极客园H5项目</h4>
        <p><span>高级</span> · <i>95682</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course08.png" alt="熟练使用React.js极客园PC端项目课程封面"></div>
      <div class="text">
        <h4>熟练使用React.js——极客园PC端项目</h4>
        <p><span>高级</span> · <i>904</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course09.png" alt="前端实用技术Fetch API实战课程封面"></div>
      <div class="text">
        <h4>前端实用技术,Fetch API 实战</h4>
        <p><span>高级</span> · <i>1516</i>人在学习</p>
      </div>
    </a>
  </li>
  <li>
    <a href="#">
      <div class="pic"><img src="./uploads/course10.png" alt="前端高级Node.js零基础入门教程课程封面"></div>
      <div class="text">
        <h4>前端高级Node.js零基础入门教程</h4>
        <p><span>高级</span> · <i>2766</i>人在学习</p>
      </div>
    </a>
  </li>
</ul>

CSS样式:固定图片区,文本区两行标题 ​

css
.bd li .pic {
  height: 156px;
}

.bd li .text {
  padding: 20px;
  height: 115px;
  background-color: #fff;
}

.bd li .text h4 {
  margin-bottom: 13px;
  height: 40px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
}

.bd li .text p {
  font-size: 14px;
  line-height: 20px;
  color: #999;
}

.bd li .text p span {
  color: #fa6400;
}

.bd li .text p i {
  font-style: normal;
}

.pic 给固定高度,是为了让不同尺寸封面在列表里保持整齐;.text 给内边距、高度和白色背景,是让文字区形成独立卡片内容区。h4 的 height:40px 配合 line-height:20px,实际是给两行标题留位置;font-weight:400 是因为 h4 默认加粗,设计稿这里不需要粗体。p 统一 14px/20px、灰色 #999,span 单独改成橙色 #fa6400 强调级别,i 默认斜体,这里必须 font-style:normal 改回正常。易错点:只写 height 不检查盒模型,.text 的 padding:20px 是否把总高撑大,要看项目有没有统一 box-sizing;调试时用浏览器检查元素看实际高度。转写稿里反复强调“样式要共用、不要影响上面的盒子”,对应到这里就是选择器要带 .bd li 限定,不要随手写全局 li .pic,否则页面其他列表也会被影响。复制 li 后要核对数量,删掉多余项;如果父级用了 flex,还要检查 ul 是否被内容宽度撑住,必要时给当前模块单独加类限定宽度,避免影响其他 .bd 区域。

先看效果与整体划分 ​

前端开发工程师区域效果图

这一块的目标是把“前端开发工程师”区域做成上下结构:上面是标题区 hd,下面是内容区 bd。为什么需要先划分?因为如果直接往大盒子里堆标题、图片和列表,后面调间距、改布局会互相牵连。怎么想?按转写稿的思路:先分上下,再在 bd 里分左右;右侧再分上、下。怎么做?保留下面结构,标题、导航、更多按钮放 hd,左侧大图放 left,右侧横幅和课程列表放 right。易错点:类名不要直接写 .left、.right,否则容易影响页面其他同名盒子,应写成 .bd .left、.bd .right。

html
<!-- 前端 -->
<div class="wrapper">
  <!-- 标题 -->
  <div class="hd">
    <h3>前端开发工程师</h3>
    <ul>
      <li><a href="#" class="active">热门</a></li>
      <li><a href="#">初级</a></li>
      <li><a href="#">中级</a></li>
      <li><a href="#">高级</a></li>
    </ul>
    <a href="#" class="more">查看全部</a>
  </div>
  <div class="bd">
    <div class="left">
      <img src="./uploads/web_left.png" alt="前端左侧大图">
    </div>
    <div class="right">
      <div class="top"><img src="./uploads/web_top.png" alt="前端右侧顶部横幅"></div>
      <div class="bottom">
        <ul>
          <li>
            <a href="#">
              <div class="pic"><img src="./uploads/web01.png" alt="JS高级课程封面"></div>
              <div class="text">
                <h4>JS高级javaScript进阶面向对象ES6</h4>
                <p><span>高级</span> · <i>101937</i>人在学习</p>
              </div>
            </a>
          </li>
          <li>
            <a href="#">
              <div class="pic"><img src="./uploads/web02.png" alt="微信小程序课程封面"></div>
              <div class="text">
                <h4>零基础玩转微信小程序</h4>
                <p><span>高级</span> · <i>133781</i>人在学习</p>
              </div>
            </a>
          </li>
          <li>
            <a href="#">
              <div class="pic"><img src="./uploads/web03.png" alt="JavaScript基础课程封面"></div>
              <div class="text">
                <h4>JavaScript基础——语法解析+项目实战</h4>
                <p><span>高级</span> · <i>8927</i>人在学习</p>
              </div>
            </a>
          </li>
          <li>
            <a href="#">
              <div class="pic"><img src="./uploads/web04.png" alt="Vue课程封面"></div>
              <div class="text">
                <h4>前端框架Vue2+Vue3全套视频</h4>
                <p><span>高级</span> · <i>26022</i>人在学习</p>
              </div>
            </a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</div>

顶部标题区:横向排列与激活态 ​

为什么需要单独处理 hd?因为标题、四个导航项和“查看全部”要在同一行,且导航项之间有固定距离。怎么想?把 ul 变成弹性盒,li 负责间距,active 负责当前项蓝色。怎么做?.hd ul 加 display:flex,.hd li 给 margin-right:60px 和字号,激活色写在 .hd li .active。易错点:active 加在 a 上,选择器要对应;不要给 li 加浮动,既然用了 flex 就统一用 flex 思路。

css
/* 前端 */
.hd ul {
  display: flex;
}

.hd li {
  margin-right: 60px;
  font-size: 16px;
}

.hd li .active {
  color: #00a4ff;
}

底部左右分栏:先量尺寸再两端对齐 ​

为什么需要 bd 分左右?左侧是固定大图,右侧是课程内容,二者并排。怎么想?转写稿里先量左侧约 228×386、右侧宽 957,用背景色临时验证尺寸,确认后再放图片。怎么做?.bd 加 display:flex 和 justify-content:space-between,左右分别给宽。易错点:不要写全局 .left;左侧宽度、右侧宽度要写在 .bd 内部;调试背景色完成后要删掉,避免影响成品。

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

.bd .left {
  width: 228px;
  /* background-color: pink; */
}

.bd .right {
  width: 957px;
  /* background-color: pink; */
}

.bd .right .top {
  margin-bottom: 15px;
  height: 100px;
}

右侧上下结构与列表复用 ​

为什么右侧还要分上下?上面是横幅图,下面是课程列表,间距只需加在 .top 下方。怎么想?先放 .top 图片,再放 .bottom 的 ul。怎么做?.top 高 100px,margin-bottom:15px;每个 li 里用 a 包住 .pic 和 .text,让整块可点击。易错点:列表样式若写在 .bd ul、.bd li 这类公共层级上,后续复制模块可复用;但单行模块若因父级 flex 导致 ul 宽度变成内容宽度,不能直接改公共选择器,应给复制模块单独加类名控制宽度,避免影响上面的盒子。

易错点小结 ​

转写稿里反复强调“别影响上面的盒子”,这是本节最重要的调试意识:先写公共结构,再用后代选择器限定范围;用背景色验证宽高;发现宽度异常时检查父级是否加了 display:flex,因为 flex 后子项宽度可能由内容决定。按这个顺序写,结构清楚,后面复制同类模块也更容易。

版权区域布局示意图

为什么需要:版权区通常是一条通栏背景,不是只包住中间内容。如果直接给内容盒子加背景,两侧会留白,视觉上不像完整底部。
怎么想:先做一个大盒子 .footer 负责“通栏背景 + 上下间距”,里面再放 .wrapper 负责“版心居中”。这是先大后小、先背景后内容的思路。
怎么做:按笔记给 .footer 设置 margin-top、padding-top、height 和白色背景;它不需要额外写宽度,块级元素默认撑满。
易错点:不要把版心宽度写到 .footer 上;也不要一上来就写左右内容,先把通栏盒子和版心关系理清。

html
<!-- 版权 -->
<div class="footer">
  <div class="wrapper">
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</div>
css
/* 版权 */
.footer {
  margin-top: 60px;
  padding-top: 60px;
  height: 273px;
  background-color: #fff;
}

转写稿里反复强调:底部是“通栏的盒子”,先给高、给背景色,再用 margin-top 和 padding-top 把内容压到合适位置。笔记中先写 margin-top: 60px,实际调试时上下距离要结合页面已有外边距微调,但这里以给定代码为准。

版心与左右分栏:wrapper 上写 flex ​

为什么需要:版权区内容要限制在版心内,并且左侧信息与右侧链接区要一左一右分开。
怎么想:结构上 .wrapper 里先放 .left 和 .right,布局上让它们的“亲爸爸” .wrapper 变成 flex 容器,再用 justify-content: space-between 做两端对齐。
怎么做:在 .footer .wrapper 上写 display: flex; justify-content: space-between;。注意不是写给 .footer,也不是写给 .left。
易错点:space-between 必须配合 flex 父级才有效;如果给错元素,左右不会分开。转写稿中特别纠正:“一定要找亲爸爸,是不是他的亲爸爸叫 wrapper”。

css
.footer .wrapper {
  display: flex;
  justify-content: space-between;
}

左侧盒子:先给宽度占位 ​

为什么需要:左右分栏后,左侧需要明确占据一块宽度,右侧才好安排;先用背景色占位也方便观察布局是否正确。
怎么想:当前笔记先完成左侧宽度占位,右侧结构先保留。转写稿中左侧后续会放 logo、说明文字和下载入口,但本节先解决布局骨架。
怎么做:给 .footer .left 设置 width: 440px,并用 background-color: pink 临时观察区域。
易错点:选择器不能直接写 .left,否则可能影响页面上面同名模块。转写稿反复提醒:“不要直接选点 left,要写 .footer 里面的 .left。”这是命名作用域问题。

css
.footer .left {
  width: 440px;
  background-color: pink;
}

调试顺序与常见错误 ​

为什么需要:底部布局容易因为选择器、flex 写错位置而乱,按顺序调试最快。
怎么想:先看 .footer 是否通栏、高度和背景是否出来;再看 .wrapper 是否在版心;最后看 .left 和 .right 是否一行两端对齐。
怎么做:先临时给左右盒子背景色,确认位置;确认后再补内部内容。右侧后续再分上下或使用列表结构,本节先把左右骨架搭好。
易错点:一是 .left/.right 命名太通用,必须加 .footer 限定;二是把 display:flex 加到 .footer 而不是 .wrapper;三是忘记 justify-content: space-between,导致左右贴在一起。按转写稿的说法,样式写好后要“不能影响上面的盒子”,这是本节最关键的检查点。

底部版权模块的整体划分 ​

为什么需要:页面底部通常承载版权、备案、下载入口和站点导航。它既要通栏铺满,又要内容居中,不能把整屏都铺成内容区。
怎么想:先做“通栏大盒子”,再在内部放“版心”,版心里再分左右。转写稿里反复强调:先分左右,右侧再分上下;底部右侧则用多个 dl 并排。
怎么做:外层给 .footer 高度和背景色,内部用 .wrapper 约束宽度并居中,再在版心里放 .left 与 .right。
易错点:不要直接给 .left、.right 写全局样式,必须限定在 .footer 内,避免影响页面上面同名的左右盒子。

HTML结构 ​

为什么需要:左侧是“Logo + 版权文字 + 下载APP”,右侧是“关于学成网、新手指南、合作伙伴”三组导航。结构清晰,样式才好复用。
怎么想:左侧两个 a 容易混淆,所以要给 Logo 和下载按钮不同类名;右侧每组用 dl,标题用 dt,每个链接用 dd > a。
怎么做:保留下面结构,图片 alt 改为中文说明:

html
<div class="left">
  <a href="#"><img src="./images/logo.png" alt="学成在线Logo"></a>
  <p>学成在线致力于普及中国最好的教育它与中国一流大学和机构合作提供在线课程。
    © 2017年XTCG Inc.保留所有权利。-沪ICP备15025210号</p>
  <a href="#" class="download">下载APP</a>
</div>
<div class="right">
  <dl>
    <dt>关于学成网</dt>
    <dd><a href="#">关于</a></dd>
    <dd><a href="#">管理团队</a></dd>
    <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>
    <dd><a href="#">学分是什么</a></dd>
    <dd><a href="#">考试未通过怎么办</a></dd>
  </dl>
  <dl>
    <dt>合作伙伴</dt>
    <dd><a href="#">合作机构</a></dd>
    <dd><a href="#">合作导师</a></dd>
  </dl>
</div>

易错点:每个 dd 里放一个 a,不要把多个链接塞进同一个 dd;右侧三组是并列的 dl,不要拆成互不相关的大盒子。

CSS样式与布局 ​

为什么需要:左侧文字需要行高和宽度控制,下载按钮要像按钮;右侧三组导航要横向排列,并保持统一字号和间距。
怎么想:版心父级用 Flex 让左右两端对齐;右侧 .right 也用 Flex 让三个 dl 一行显示,再用 margin-left 打开间距。转写稿还提到“高度剩余法”:给 dt、dd 固定高度,间距自然形成,减少逐项调 margin。
怎么做:保留笔记 CSS:

css
.footer .left p {
  margin-top: 24px;
  margin-bottom: 14px;
  font-size: 12px;
  line-height: 17px;
  color: #666;
}

.footer .left .download {
  display: block;
  width: 120px;
  height: 36px;
  border: 1px solid #00a4ff;
  text-align: center;
  line-height: 34px;
  font-size: 16px;
  color: #00a4ff;
}

.footer .right {
  display: flex;
}

.footer .right dl {
  margin-left: 130px;
}

.footer .right dt {
  margin-bottom: 12px;
  font-size: 16px;
  line-height: 23px;
}

.footer .right a {
  font-size: 14px;
  color: #666;
  line-height: 24px;
}

易错点:.download 是行内 a,必须 display: block 才能设宽高;行高与高度配合时,1px 边框会让视觉居中差 1px,转写稿用 line-height: 34px 配 height: 36px 加边框;a 的颜色不会从父级 dd 自动继承,必须直接选中 .footer .right a。

调试与易错点复盘 ​

为什么需要:底部常见问题是“左右没对齐、右侧挤在一起、链接颜色不生效”。转写稿中通过浏览器检查发现:给父级加 display:flex 后,子项宽度可能由内容决定,单行模块需要单独补宽度,且不能影响上面的模块。
怎么想:先看父级是否 Flex,再看子项宽度和间距;样式要按“先父后子”的顺序写,便于查找。
怎么做:底部版心父级加 display:flex; justify-content:space-between;;右侧三个 dl 一行显示后,用 .footer .right dl { margin-left:130px; } 打开距离。若要做悬停变色,可再加 .footer .right a:hover { color:#00a4ff; },这是转写稿提到的可选修饰。
易错点:不要给全局 .left、.right 加样式;复制结构后要检查 dl 数量和 dd 内链接层级;底部通栏盒子不要误设版心宽度,版心交给内部 wrapper。

课件图示 ​

课件第19页:1. 布局思路:先整体再局部,从外到内,从上到下,从左到右 2. CSS 实现思

课件第30页:精品推荐(recommend) 实现方法: • 标签结构:.recommend

课件第33页:精品课程-内容区域 思路:“课程卡片”各个区域样式复用 标签结构:.bd > u

课件第38页:今日 作业 1. 按照“前端学科课程”布局方式实现“其他学科课程” 区域的布局效

课件第35页:学科课程 – 标题 标签结构:h3 + ul + a.more tab 栏 /

课件第36页:学科课程-内容 标签结构:.left + .right > .top + .bo

代码示例 ​

示例一:推荐课程 —— 内容样式(卡片列表) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>推荐课程 - 内容样式</title>
  <style>
    /* ---------- 基础重置 ---------- */
    * { margin: 0; padding: 0; }
    li { list-style: none; }
    a { color: #333; text-decoration: none; }
    img { border: none; vertical-align: middle; }

    /* 版心:整页公共的居中容器 */
    .wrapper { width: 1200px; margin: 0 auto; }
    .hd { margin-bottom: 20px; }
    .hd h3 { font-size: 24px; font-weight: 400; }

    /* ---------- 卡片列表 ---------- */
    .bd ul { display: flex; flex-wrap: wrap; justify-content: space-between; }
    .bd li { width: 228px; margin-bottom: 15px; background-color: #fff; }
    .bd li a { display: block; }

    /* ---------- 笔记原始样式 ---------- */
    .bd li .pic { height: 156px; }

    .bd li .text {
      padding: 20px;
      height: 115px;
      background-color: #fff;
    }

    .bd li .text h4 {
      margin-bottom: 13px;
      height: 40px;
      font-size: 14px;
      line-height: 20px;
      font-weight: 400;
    }

    .bd li .text p {
      font-size: 14px;
      line-height: 20px;
      color: #999;
    }

    .bd li .text p span { color: #fa6400; }
    .bd li .text p i { font-style: normal; }

    /* 补充:图片撑满 .pic */
    .bd li .pic img { display: block; width: 100%; height: 100%; }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="hd"><h3>精品推荐</h3></div>

    <div class="bd">
      <ul>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course01.png" alt=""></div>
            <div class="text">
              <h4>JavaScript数据看板项目实战</h4>
              <p><span>高级</span> · <i>1125</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course02.png" alt=""></div>
            <div class="text">
              <h4>Vue.js实战——面经全端项目</h4>
              <p><span>高级</span> · <i>2726</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course03.png" alt=""></div>
            <div class="text">
              <h4>玩转Vue全家桶,iHRM人力资源项目</h4>
              <p><span>高级</span> · <i>9456</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course04.png" alt=""></div>
            <div class="text">
              <h4>Vue.js实战医疗项目——优医问诊</h4>
              <p><span>高级</span> · <i>7192</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course05.png" alt=""></div>
            <div class="text">
              <h4>小程序实战:小兔鲜电商小程序项目</h4>
              <p><span>高级</span> · <i>2703</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course06.png" alt=""></div>
            <div class="text">
              <h4>前端框架Flutter开发实战</h4>
              <p><span>高级</span> · <i>2841</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course07.png" alt=""></div>
            <div class="text">
              <h4>熟练使用React.js——极客园H5项目</h4>
              <p><span>高级</span> · <i>95682</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course08.png" alt=""></div>
            <div class="text">
              <h4>熟练使用React.js——极客园PC端项目</h4>
              <p><span>高级</span> · <i>904</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course09.png" alt=""></div>
            <div class="text">
              <h4>前端实用技术,Fetch API 实战</h4>
              <p><span>高级</span> · <i>1516</i>人在学习</p>
            </div>
          </a>
        </li>
        <li>
          <a href="#">
            <div class="pic"><img src="./uploads/course10.png" alt=""></div>
            <div class="text">
              <h4>前端高级Node.js零基础入门教程</h4>
              <p><span>高级</span> · <i>2766</i>人在学习</p>
            </div>
          </a>
        </li>
      </ul>
    </div>
  </div>
</body>
</html>

关键行与易错点

  • .bd li a { display: block; }:a 默认是行内元素,不给块级就无法把 padding 撑到整张卡片,点击区域也会只剩文字那一行。
  • .bd li .pic { height: 156px; } 只给了高度,图片必须再写 width: 100%; height: 100%; display: block,否则图片按原始尺寸显示、还会在图片下方多出几像素空隙(行内元素基线问题)。
  • .bd li .text { padding: 20px; height: 115px; } 是内容高度,默认 content-box 下盒子实际高 155px;如果你在全局写了 box-sizing: border-box,视觉高度会变小,这一点要和设计稿核对。
  • h4 { height: 40px; line-height: 20px; } = 固定两行标题,保证每张卡片文字区高度一致;标题超出两行时会溢出,实际项目需再配溢出隐藏(笔记未涉及,属于后续补充)。
  • 选择器一定要带 .bd 前缀(.bd li ...):转写稿反复强调"不要直接写 .left/.li",否则会误伤页面上其他同名的 li、left。

示例二:前端开发工程师区域(左右分栏 + 上下分块) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>前端开发工程师区域</title>
  <style>
    * { margin: 0; padding: 0; }
    li { list-style: none; }
    a { color: #333; text-decoration: none; }
    img { border: none; vertical-align: middle; }

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

    /* ---------- 头部:标题 + 选项卡 + 查看全部 ---------- */
    .hd { display: flex; align-items: center; margin-bottom: 20px; }
    .hd h3 { font-size: 24px; font-weight: 400; }
    .hd ul { display: flex; margin-left: 40px; }
    .hd li { margin-right: 60px; font-size: 16px; }
    .hd li .active { color: #00a4ff; }
    .hd .more { margin-left: auto; font-size: 14px; color: #999; }

    /* ---------- 主体:一左一右,两端对齐 ---------- */
    .bd { display: flex; justify-content: space-between; }

    .bd .left { width: 228px; }
    .bd .left img { display: block; width: 100%; }

    .bd .right { width: 957px; }
    .bd .right .top { margin-bottom: 15px; height: 100px; }
    .bd .right .top img { display: block; width: 100%; height: 100%; }

    /* ---------- 卡片:与"推荐课程"共用同一套 .bd li 样式 ---------- */
    .bd .right .bottom ul { display: flex; justify-content: space-between; }

    .bd li { width: 228px; }
    .bd li a { display: block; }
    .bd li .pic { height: 156px; }
    .bd li .pic img { display: block; width: 100%; height: 100%; }

    .bd li .text {
      padding: 20px;
      height: 115px;
      background-color: #fff;
    }
    .bd li .text h4 {
      margin-bottom: 13px;
      height: 40px;
      font-size: 14px;
      line-height: 20px;
      font-weight: 400;
    }
    .bd li .text p { font-size: 14px; line-height: 20px; color: #999; }
    .bd li .text p span { color: #fa6400; }
    .bd li .text p i { font-style: normal; }
  </style>
</head>
<body>
  <!-- 前端 -->
  <div class="wrapper">
    <!-- 标题 -->
    <div class="hd">
      <h3>前端开发工程师</h3>
      <ul>
        <li><a href="#" class="active">热门</a></li>
        <li><a href="#">初级</a></li>
        <li><a href="#">中级</a></li>
        <li><a href="#">高级</a></li>
      </ul>
      <a href="#" class="more">查看全部</a>
    </div>

    <div class="bd">
      <div class="left">
        <img src="./uploads/web_left.png" alt="">
      </div>
      <div class="right">
        <div class="top"><img src="./uploads/web_top.png" alt=""></div>
        <div class="bottom">
          <ul>
            <li>
              <a href="#">
                <div class="pic"><img src="./uploads/web01.png" alt=""></div>
                <div class="text">
                  <h4>JS高级javaScript进阶面向对象ES6</h4>
                  <p><span>高级</span> · <i>101937</i>人在学习</p>
                </div>
              </a>
            </li>
            <li>
              <a href="#">
                <div class="pic"><img src="./uploads/web02.png" alt=""></div>
                <div class="text">
                  <h4>零基础玩转微信小程序</h4>
                  <p><span>高级</span> · <i>133781</i>人在学习</p>
                </div>
              </a>
            </li>
            <li>
              <a href="#">
                <div class="pic"><img src="./uploads/web03.png" alt=""></div>
                <div class="text">
                  <h4>JavaScript基础——语法解析+项目实战</h4>
                  <p><span>高级</span> · <i>8927</i>人在学习</p>
                </div>
              </a>
            </li>
            <li>
              <a href="#">
                <div class="pic"><img src="./uploads/web04.png" alt=""></div>
                <div class="text">
                  <h4>前端框架Vue2+Vue3全套视频</h4>
                  <p><span>高级</span> · <i>26022</i>人在学习</p>
                </div>
              </a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</body>
</html

常见错误 ​

  1. 页头样式被底部"带崩" 现象:写完 footer 的 .left / .right 后,顶部导航、前端模块的左右布局全部错位。 原因:直接写 .left{}、.right{}、.pic{} 这类全局类选择器,命中了页面上所有同名类。 修法:一律从最近的、唯一的祖先往下限定(.footer .wrapper .left、.bd .right .bottom li .pic),写完立刻滚动整页复查一遍有没有"不该变的地方变了"。

  2. 给 flex 容器加完 display:flex,里面只剩一个 ul 时它变窄了 现象:单行课程模块的 ul 只占内容宽度(约 1140px),右侧空出一块,和上面通栏对不齐。 原因:父级成为 flex 容器后,唯一子项按内容宽度收缩,不再撑满 1200px 版心。 修法:给这个模块单独加一个类(如 .line),只对它写 width:1200px(必要时再加 justify-content:space-between);不要把宽度写在不带限定的 .bd ul 上,否则多行模块全部被打乱。

  3. display:flex 加错了对象 现象:左图和右内容上下堆叠,没有并排;或者整块内容跑到页面左侧贴边。 原因:flex 写在了子元素(.left/.right/.right .top)身上,而不是它们共同的直接父元素上。 修法:先确认"谁的孩子需要排成一行",flex 与 justify-content 只写给这个直接父元素;父元素写完后不要再往下重复加。

  4. dt/dd 结构写错,样式怎么调都不对 现象:底部右侧一列里所有链接挤成一行、dt 标题和链接混排,或者加 margin 只推动第一个。 原因:把多个 <a> 塞进了同一个 <dd>,或者 dd 直接写在 dl 外。 修法:严格一 dt 一标题、每个 dd 内只放一个 a;先核对 DOM 结构再写样式,结构不对时任何 CSS 都是徒劳。

  5. dd 上设的 color 不生效 现象:给 dd 写了 color:#666,链接文字仍是蓝色。 原因:a 有自身的颜色声明,父级的 color 不会覆盖它。 修法:把颜色写到 a 上(.footer .right dd a),并用 a:hover 单独处理悬停色。

  6. 两个 a 混在一起,样式互相污染 现象:给底部"下载 APP"设了边框和宽高,结果页头 logo 链接也变形了。 原因:两个 a 用了相同类名或都用元素选择器 .footer .left a 统一处理。 修法:分别起语义类名(.f-logo / .download),选择器精确到类,不要用元素名批量命中。

  7. 间距靠逐个 margin 硬调,改一处崩一片 现象:dt 与第一个 dd 之间、dd 之间距离不一致,删掉一条链接后整列错位。 原因:给每个 dd 分别写 margin-top/margin-bottom,没有统一的行高基准。 修法:改用高度剩余法——dt 给固定高度、dd 给固定 line-height,让间距由盒子高度自然产生,条目增删都不用再调数值。

  8. padding-top 与 margin-top 混用导致顶部空白对不上 现象:footer 内容没有贴到预期位置,或页面底部多出一条滚动空白。 原因:外层容器用了 margin-top(可能与上方元素外边距合并),内层又重复加了 padding。 修法:容器定位用 margin-top,内容与容器上边缘的距离用 padding-top,同一处只保留一种;改完刷新确认没有多余滚动条。

练习 ​

  1. 复制出第三个课程板块("人工智能"),要求 5 门课程一行排满、与上方模块左右对齐。全程不得修改已有 CSS,只能新增一条带模块限定的规则;完成后回头检查前两个板块是否完全没变。
  2. 把底部右侧三列 dl 改成四列:新增一列"联系我们",并保证列间距与原来一致、整体仍在版心内不换行。写出你用的间距方案及为什么不需要逐个测距。
  3. 给底部所有链接加悬停变主色(#00a4ff),并说明为什么颜色必须写在 a 上而不是 dd 上;再让"下载 APP"按钮悬停时背景填充、文字变白。
  4. 把"前端开发工程师"区域的右侧上下结构(.top + .bottom)中的 4 个课程条目,改为每行 2 个、共 2 行的网格排布,要求复用已有的 .pic / .text 样式不改动,只加新规则。
  5. 自查题:把整页所有类选择器列表出来,标出哪些是"全局类"(如 .pic、.left),并为它们各写一条更安全的作用域写法。

原视频对照 ​

#视频时长
1前端模块左侧制作04:41
2前端模块结束05:23
3人工智能模块课07:47
4底部盒子制作03:47
5底部盒子左侧制作09:58
6底部盒子右侧完成11:00
7作业安排02:44

小结 ​

  1. 这一段的难点不在写新样式,而在控制影响范围:页面越长,选择器越要往下限定,"能命中多少就命中多少"是 bug 的源头。
  2. 写之前先做结构分组:相似的东西放进同一个父容器,样式才能一处写好、多处复用;判断依据是"长得像"而不是"挨得近"。
  3. 复制粘贴是这类页面的主要生产力,但复制前必须先确认源结构的层级(父是谁、几个孩子),复制后立刻删掉多余条目再刷新验证。
  4. flex 只加在"需要并排的那一层父元素"上,加完要意识到它会改变子项的宽度行为,单行场景要显式给宽度。
  5. 间距优先用"高度 + 行高"的确定性方案,margin 只用于块与块之间的一次性距离;一旦发现自己在逐个测数值,就说明方案选错了。
  6. a 的颜色、img 的尺寸都不会从父级继承,凡是"设了没反应",先怀疑是不是写在了错误的层级或元素上。
  7. 每写完一个模块就整页滚动 + 缩放检查一次,比最后统一调试便宜得多;样式污染越晚发现,定位成本越高。
  8. 这套页面把 HTML 结构、盒模型、浮动/flex、选择器优先级都用上了,写两三遍比看十遍讲解更有效。