Skip to content

学成在线(三) ​

本页对应 学成在线,共 8 段视频,约 1 小时 12 分。

学习目标 ​

  • 能独立搭建 header 中导航模块的 div > ul > li > a 结构,并使用 Flex 布局使导航项横向排列,通过 margin、padding 和 :hover 完成间距与下划线效果。
  • 能完成搜索区域盒子布局,设置指定宽高、圆角与背景色,并让 input 铺满父盒子,去除默认边框、背景透明、取消聚焦外轮廓并设置内边距。
  • 能完成用户模块结构搭建,使用 a 包裹头像图片和文字,设置左外边距,并通过 vertical-align: middle 实现图片与文字垂直居中对齐。
  • 能搭建 banner 通栏、版心和左右盒子结构,使用背景图、Flex 主轴两端对齐与侧轴垂直居中完成左右区域布局。
  • 能使用 rgba() 为 banner 左侧盒子设置黑色半透明背景,并根据效果图调整透明度。
  • 能使用浏览器开发者工具按“先检查结构、再检查样式”的顺序定位布局错位问题,并通过调整 DOM 层级或 CSS 属性完成修复。

知识点 ​

先定搜索大盒子 ​

搜索区域效果图

为什么需要:header 里 logo、导航之后就是搜索区域。搜索框不是一段普通文字,而是一个有固定尺寸、灰色底、圆角的“外观盒子”,先把外观盒子定下来,后面的输入框才有地方放。

怎么想:看效果图先量尺寸。转写稿里量到搜索区域约 412 × 40,背景是浅灰 #f3f5f7,圆角 20px,正好是高度的一半。它与左侧导航之间还有距离,量到约 96px,实际取 80px 更方便。

怎么做:先写一个 div.search,再用 CSS 给宽高、背景色、圆角和左外边距。

html
<div class="search"></div>
css
/* 搜索 */
.search {
  width: 412px;
  height: 40px;
  background-color: #f3f5f7;
  border-radius: 20px;
  margin-left: 80px;
}

易错点:margin-left 是加在 .search 盒子上的,不要误加到里面的输入框上;圆角想做成胶囊形,通常取高度的一半,这里就是 20px。

用 input 铺满搜索盒 ​

为什么需要:搜索区域最终要能输入关键词。转写稿明确做法是:大盒子 .search 负责灰色底和圆角,里面直接放一个 input,让输入框铺满父盒子。

怎么想:输入框自己也有默认背景和边框,如果直接放进去,会盖住父盒子的灰色底和圆角效果。因此思路是“父盒子做外观,input 只负责输入”,把 input 做成透明并铺满。

怎么做:在 .search 里放 input,并给 input 设置与父盒子一样的宽高,再去掉默认边框和背景。

html
<div class="search">
  <input type="search" placeholder="请输入关键词">
</div>
css
.search input {
  width: 100%;
  height: 100%;
  border: 0;
  background-color: transparent;
}

易错点:transparent 是“透明”,不是白色;如果 input 保留默认白底,就会把 .search 的灰色底盖住。去掉边框用 border: 0;,不要和后面的焦点线混淆。

去掉焦点黑线并留出文字距离 ​

为什么需要:输入框获得焦点时,浏览器默认会出现一圈黑色或蓝色轮廓线,效果图上没有,而且看起来比较丑。同时文字紧贴左边也不好看,需要给内容留内边距。

怎么想:默认边框是 border,点击后出现的线是 outline,两者不是同一个东西。转写稿里专门强调:去掉点击后的黑线要用 outline。

怎么做:给 input 增加 outline: 0; 或 outline: none;,再用 padding-left 把文字往里挤。转写稿中先给 20px 左右,右侧还可以预留空间给后面的放大镜。

css
.search input {
  width: 100%;
  height: 100%;
  border: 0;
  background-color: transparent;
  outline: 0;
  padding-left: 20px;
}

易错点:只写 border: 0; 去不掉点击后的焦点线,还要处理 outline;给 input 加 padding 时要注意它仍要铺满父盒子,别把宽高算乱。放大镜部分转写稿说等学定位后再补,这里先把输入框和搜索盒做好。

调试距离时先看盒子再看样式 ​

为什么需要:搜索盒与导航之间的距离不是凭感觉写,量出来约 96px,取 80px 是为了凑整、视觉上也够用。写完后如果位置不对,要用调试工具检查。

怎么想:转写稿的调试思路是先看结构对不对,再看盒子尺寸、margin、padding 是否合理,不要一上来乱改代码。

怎么做:在浏览器里选中 .search,看它的宽高、背景、圆角和 margin-left;再选中 input,看是否铺满、是否透明、是否还有边框和 outline。距离测量时先点左侧元素,再把鼠标放到右侧元素上读取间距。

易错点:不要给 .search 随便加左右 padding 还保持 width: 412px,否则内容区会被压缩;搜索框内部元素多起来后,优先检查父盒子宽度是否还够用。

搜索区域要解决什么问题 ​

为什么需要:header 右侧要放一个“输入关键词”的搜索框,它既有输入功能,又要有圆角、浅灰底色和合适的内边距。
怎么想:不要把圆角、底色、尺寸都直接压到 input 上,而是先用一个 .search 盒子做外观,再让 input 铺满并透明化。这样以后在右侧补放大镜、调背景都更方便。
怎么做:先写 .search 大盒子,再在盒子里放 input。
易错点:如果直接给 input 设背景色,容易盖住父盒子的圆角和底色;搜索框的边框和点击黑框是两个不同属性,不能混。

先搭搜索盒子结构 ​

为什么需要:搜索框是一个独立模块,结构清楚后才好调尺寸和间距。
怎么想:外层用 div.search 表示“搜索”,里面放一个 input,用 placeholder 提示“输入关键词”。
怎么做:保留笔记中的结构:

html
<!-- search 搜索  -->
<div class="search">
  <input type="search" placeholder="输入关键词">
</div>

转写稿里提到,type="search" 是搜索专用文本框,输入后可能出现小叉号;如果不想出现叉号,也可以用 type="text"。
易错点:placeholder 是提示文字,不是默认值;type 写错会影响浏览器自带的搜索表现。

父盒子负责外观:尺寸、底色、圆角、间距 ​

为什么需要:效果图里的搜索框是 412×40、浅灰底、20px 圆角,并且距离左侧有一段距离。
怎么想:这些外观交给 .search 父盒子,input 只负责输入。转写稿中测量到搜索盒子约 412×40,背景色为 #F3F5F7,圆角 20px,距离左侧约 80px。
怎么做:可写成:

css
.search {
  width: 412px;
  height: 40px;
  background-color: #F3F5F7;
  border-radius: 20px;
  margin-left: 80px;
}

易错点:圆角 20px 正好是高度 40px 的一半;margin-left 是盒子与左侧导航之间的距离,不要误写成 padding-left。

input 铺满并透明化 ​

为什么需要:输入框要覆盖整个搜索盒子,但外观仍显示父盒子的浅灰底和圆角。
怎么想:让 input 宽高与父盒子一致,背景透明,去掉自带边框。
怎么做:保留笔记样式:

css
.search input {
  width: 412px;
  height: 40px;
  /* 背景色透明 */
  background-color: transparent;
  /* 自带边框为0不显示 */
  border: 0;
  padding-left: 20px;
  padding-right: 30px;
  /* 去掉点击之后显示的黑色边框 */
  outline: 0;
}

易错点:background-color: transparent 是透明,不是白色;border: 0 去的是 input 自带边框;outline: 0 去的才是点击后出现的黑色外线。

内边距与右侧留白 ​

为什么需要:文字不能贴着左边,右侧还要给以后定位补上的放大镜留位置。
怎么想:左侧用 padding-left 让输入文字往里缩,右侧用 padding-right 留出空间。
怎么做:笔记中已经给出 padding-left: 20px; padding-right: 30px;。转写稿也说明,右侧 30px 是为了以后把放大镜放进去。
易错点:给 input 加 padding 后,如果还固定 width: 412px,要注意盒子实际占用可能变化;这里按笔记写法保留即可。

调试与收尾 ​

为什么需要:搜索框做完后,容易出现文字贴边、点击有黑框、背景盖住圆角等问题。
怎么想:先看结构,再看样式;先确认 .search 盒子尺寸和背景,再检查 input 是否透明、边框是否去掉。
怎么做:在浏览器检查工具里选中 .search 和 input,分别看宽高、背景、border、outline、padding。
易错点:不要一上来就改很多代码;先定位是父盒子问题还是 input 问题。搜索框的小放大镜按转写稿安排,等学完定位再回来补,不在本节硬写。

用户区域效果图

用户区域要解决什么 ​

为什么需要:头部右侧要放“用户头像 + 用户名”,并且用户区域通常可以点击进入个人页,所以不能只放一张图和一段文字。
怎么想:先把它当成一个整体盒子,再在盒子里放可点击的 A,A 里放图片和文字;位置由父级横向排列和左边距控制。
怎么做:结构写成 .user > a > img + span,样式先给 .user 左边距,再处理图片与文字对齐、文字颜色。
易错点:不要直接把 img 和 span 散放在头部里;转写稿里反复强调“先看结构,再看样式”,结构错了先调结构。

HTML 结构:用 A 包住图片和文字 ​

为什么需要:用户名和头像都属于用户入口,用 A 包住后,鼠标放在图片或文字上都能点击,点击范围更自然。
怎么想:转写稿中说“用户名正常情况下都能点击”,所以先写 .user 盒子,再放 A,A 内放 img 和 span。
怎么做:按笔记保留如下结构,文字按笔记写“播仔学前端”,不要写成转写稿里的同音字“波仔/博彩”。
易错点:A 要包住 img 和 span 两者;如果只包文字,点图片就不能跳转。

html
<div class="user">
  <a href="#">
    <img src="./uploads/user.png" alt="">
    <span>播仔学前端</span>
  </a>
</div>

CSS 样式:左边距、垂直居中、文字颜色 ​

为什么需要:用户区域要和前面的搜索框拉开距离;图片和文字默认是基线对齐,看起来字会偏下;文字颜色也要比默认黑色浅。
怎么想:转写稿中测量用户区域左侧距离约 32px,所以给 .user 加 margin-left;图片和文字居中对齐用 vertical-align: middle;文字用 #666666。
怎么做:保留笔记 CSS,并注意选择器要“找最近一级带类名的爸爸”,即 .user img、.user span,不要写成影响全局的 img、span。
易错点:vertical-align: middle 是给图片加的,不是给 .user 加的;转写稿里“没度”实际是 middle,“马志刚 left”实际是 margin-left。如果 user 掉到下一行,先检查它是否还在父级 wrapper 里,再看父级宽度、padding、margin-left 是否把它挤出去。

css
/* 用户模块 */
.user {
  margin-left: 32px;
}

.user img {
  /* 让文字和图片垂直居中对齐 */
  vertical-align: middle;
}

.user span {
  color: #666666;
}

调试与收尾 ​

为什么需要:代码写到头部时,盒子一多就容易出现掉盒子、换行、距离不对,靠肉眼找很慢。
怎么想:转写稿中的调试顺序是:先打开检查工具看结构,确认 wrapper 下是不是 logo、nav、search、user 四个子盒子;结构对了再看样式。
怎么做:如果 user 单独掉下去,先看它是否误放到 wrapper 外面;再看父级是否左右 padding 过多导致宽度不够,或 .user 的 margin-left 是否过大。
易错点:结构错误时不要先猛调样式;转写稿中就是先发现 user 不在 rapper 里,把它放回父级后才恢复正常。用户区域本身较简单,核心就是 A 包裹、margin-left: 32px、图片 vertical-align: middle、文字 #666666。

先看效果:banner 是“通栏 + 版心 + 左右两栏” ​

banner区域布局效果图

为什么需要:banner 是广告条区域,通常背景要铺满浏览器宽度,但内容不能跟着无限铺开,所以要分成“通栏盒子”和“版心盒子”两层。
怎么想:先做一个 .banner 通栏,给高度和背景色;里面再放 .wrapper 版心,给同高和背景图;版心里再分 .left 和 .right 两个盒子。转写稿里反复强调:先把大盒子外形搭出来,再往里面填内容。
怎么做:结构就是笔记里的三层:.banner > .wrapper > .left/.right。
易错点:不要把背景图直接写到 .banner 上就以为版心也有了;版心需要自己的高度,否则背景图看不见。

HTML 结构:先搭骨架,不急着填内容 ​

html
<div class="banner">
  <div class="wrapper">
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</div>

为什么需要:左右两栏是兄弟关系,必须放在同一个父盒子 .wrapper 里,后面才能用 Flex 让它们在一行上。
怎么想:转写稿里说“先看结构,再看样式”。.wrapper 里应该只有 .left 和 .right 两个兄弟,结构对了再调样式。
怎么做:先写通栏、版心、左右盒子,文字先用 left/right 占位。
易错点:把 .right 写到 .wrapper 外面,后面怎么调都掉下来;选择器也不要只写 .left、.right,要限定成 .banner .left、.banner .right,避免和页面其他同名类冲突。

通栏和版心:两层盒子各管一件事 ​

css
.banner {
  height: 420px;
  background-color: #0092cb;
}

.banner .wrapper {
  height: 420px;
  background: url(../uploads/banner.png);
}

为什么需要:.banner 负责通栏底色,.wrapper 负责版心宽度和 banner 背景图。
怎么想:转写稿里先量出 banner 高度是 420px,背景色用吸色得到 #0092cb;版心也要给 420px 高,否则背景图没有高度撑开。
怎么做:.banner 给高和背景色;.banner .wrapper 给同高和背景图。
易错点:背景图路径容易写错,转写稿里就是到 uploads 里找 banner.png;另外 .wrapper 是公共版心类,banner 里要写 .banner .wrapper,避免影响页头版心。

用 Flex 让左右分开并垂直居中 ​

css
.banner .wrapper {
  display: flex;
  /* 主轴两侧对齐 */
  justify-content: space-between;
  /* 侧轴居中 */
  align-items: center;
}

为什么需要:.left 和 .right 默认是块级盒子,会上下排列;要让它们一行显示,并且一个靠左、一个靠右。
怎么想:转写稿里说“谁在一行上,就给谁的亲父亲加 flex”。这里要让 .left 和 .right 一行,所以 flex 加在 .wrapper 上,不是加在 .banner 上。
怎么做:display: flex 先让它们一行;justify-content: space-between 让主轴两侧对齐;align-items: center 让侧轴垂直居中。
易错点:flex 加错父亲是最常见问题;.left 高度和父盒子一样高,垂直居中对它看不出效果,真正明显的是右侧 .right。

左右盒子尺寸与半透明背景 ​

css
.banner .left {
  width: 191px;
  height: 420px;
  /*背景半透明*/
  background-color: rgba(0, 0, 0, 0.42);
}

.banner .right {
  width: 218px;
  height: 305px;
  background-color: pink;
}

为什么需要:左侧是半透明黑色遮罩,右侧是内容占位盒子。
怎么想:转写稿里量到左侧宽 191px、高 420px,透明度约 0.42;右侧宽 218px、高 305px,先用 pink 占位,方便看清盒子位置。
怎么做:左侧用 rgba(0,0,0,0.42),前三个 0 是黑色,0.42 是透明度;右侧先给尺寸和占位背景色。
易错点:选择器要写 .banner .left、.banner .right,不要裸写 .left/.right;半透明是写在 background-color 里的 rgba,不是把整个盒子都改掉。

完整 CSS 与调试提醒 ​

css
/* header盒子制作结束啦 */

/* banner开始 */
.banner {
  height: 420px;
  background-color: #0092cb;
}

.banner .wrapper {
  height: 420px;
  background: url(../uploads/banner.png);
}

.banner .wrapper {
  display: flex;
  /* 主轴两侧对齐 */
  justify-content: space-between;
  /* 侧轴居中 */
  align-items: center;
}

.banner .left {
  width: 191px;
  height: 420px;
  /*背景半透明*/
  background-color: rgba(0, 0, 0, 0.42);
}

.banner .right {
  width: 218px;
  height: 305px;
  background-color: pink;
}

转写稿里的调试思路同样适用于 banner:先看结构,再看样式。先确认 .wrapper 里是不是正好有 .left 和 .right 两个兄弟,再看 flex 是不是加在 .wrapper 上,最后检查宽高、背景图路径和 rgba 透明度。这样布局乱了也能按顺序定位,而不是盲目改代码。

侧导航在 banner 中的位置 ​

banner 是广告区域,通常是一张通栏背景图。背景图上面还要放内容:左侧是课程分类侧导航,右侧是用户信息等。做侧导航前,先要把它放回 banner 的版心里理解:banner 通栏给高度和背景图,版心负责居中,版心里再用 flex 把左侧 left 和右侧 right 排成一行。转写稿里反复强调“先搭大盒子,再填内容”,因为侧导航不是孤立存在的,它的大小、透明背景和位置都受 banner 版心影响。

侧导航的需求是:黑色半透明底、白字、每行一个分类,鼠标经过时文字变蓝并换右侧箭头。为什么用半透明?因为它盖在 banner 背景图上,既要保证文字可读,又不能把底图完全挡住。为什么用列表?分类导航本质是一组链接,ul > li > a 比一堆 a 直接堆在一起更清晰,也方便用 li 隔开链接、控制每一项。

HTML 结构:ul/li/a 的分工 ​

html
<div class="left">
  <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="#">UI设计</a></li>
    <li><a href="#">产品</a></li>
  </ul>
</div>

这里不要直接把 a 全放在 div 里。转写稿讲导航时提到,用 li 把链接隔开,是为了避免大量 a 堆积,结构上也更像“导航项”。每个 li 是一行,a 是这一行里真正可点击的区域。后面把 a 设为块级,就能让整行都可点,而不是只有文字可点。

left 容器样式 ​

css
/* 侧导航 */
.banner .left {
  padding: 3px 20px;
  width: 191px;
  height: 420px;
  background-color: rgba(0,0,0,0.42);
}

padding: 3px 20px 是上下 3px、左右 20px,让文字和盒子边缘留出距离。width:191px; height:420px 对应设计稿量出的左侧盒子尺寸。rgba(0,0,0,0.42) 前三个 0 是纯黑,最后的 0.42 表示 42% 不透明度,所以它盖在 banner 图上会呈现黑色半透明效果。

这里要想清楚:笔记里的 width:191px 默认是内容宽度,加上左右 padding 后,盒子实际占位会变大。如果设计稿量的是“总宽 191”,就要检查盒模型,必要时配合 box-sizing:border-box;如果项目全局已经处理过,就按现有代码写。易错点是看到侧导航比预期宽,就盲目改 width,其实可能是 padding 撑开的。

a 的块级与箭头背景 ​

css
.banner .left a {
  /* 块级:宽度是父级的100% */
  display: block;
  height: 46px;
  background: url(../images/right.png) no-repeat right center;
  line-height: 46px;
  font-size: 16px;
  color: #fff;
}

a 默认是行内元素,不给 display:block 时,宽高和背景都不好控制。设为块级后,它会占满父级内容宽度,每一行都变成完整可点击区域。height:46px 配合 line-height:46px,让单行文字垂直居中。background 里 no-repeat right center 表示箭头图片不重复,放在右侧、垂直居中。

为什么箭头用背景图而不是额外标签?因为箭头只是装饰,放在 a 的背景里最简单,也不会多出无意义的结构。注意路径 ../images/right.png 要按实际目录检查,背景图不显示时先用调试工具看图片是否 404。

hover 状态 ​

css
.banner .left a:hover {
  background-image: url(../images/right-hover.png);
  color: #00a4ff;
}

鼠标经过时只换背景图、改文字颜色,位置和尺寸不变,所以视觉上稳定。这里写 background-image 而不是重新写整个 background,可以避免把 no-repeat right center 覆盖掉。易错点是 hover 后箭头跑位,通常是 hover 里重写了 background 简写但漏了定位。

易错点与调试 ​

第一,ul 默认有圆点和缩进,如果页面出现左侧缩进或小圆点,先查全局 reset 是否去掉了 list-style 和默认 margin/padding,不要直接怪 left。第二,a 不要写死宽度,侧导航文字长短不一,写死宽度容易装不下;这里用块级占满父级即可。第三,调试时按转写稿的思路:先看结构,left > ul > li > a 是否完整;再看样式,选中 left 看宽高、padding、背景色,选中 a 看背景图是否加载、line-height 是否等于高度。先结构后样式,比在几百行 CSS 里盲找更快。

课件图示 ​

课件第28页:左侧侧导航(left) 实现方法: • 标签结构:.left > ul > li

课件第21页:header 区域-布局 通栏:宽度与浏览器窗口相同的盒子 标签结构:通栏 >

课件第22页:logo 制作技巧 logo 功能: • 单击跳转到首页 • 搜索引擎优化:提升

课件第23页:导航制作技巧(nav) 导航功能 • 单击跳转页面 实现方法: • 标签结构:u

课件第27页:banner 区域 – 布局 结构:通栏banner > 版心 > .left

课件第14页:网站根目录是指存放网站的第一层文件夹,内部包含当前网站的所有素材,包含 HTML

课件第16页:l 清除默认样式,例如内边距、外边距、项目符号等等 l 设置通用样式,例如:文字

课件第32页:精品课程-标题区域(hd) 思路:“标题”与“查看全部” 各个区域样式复用 •

代码示例 ​

示例一:header 搜索框 + 用户区域 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>header 搜索与用户区域</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background-color: #fff; font-family: "Microsoft YaHei", sans-serif; }
    a { text-decoration: none; }

    /* 版心:转写稿中给 wrapper 加 flex,让里面的盒子排成一行 */
    .wrapper {
      display: flex;
      align-items: center;
      width: 1200px;
      height: 100px;
      margin: 0 auto;
    }

    /* 搜索 */
    .search {
      width: 412px;
      height: 40px;
      background-color: #f3f5f7;
      border-radius: 20px;
      margin-left: 80px;
    }

    .search input {
      width: 412px;
      height: 40px;
      /* 背景色透明 */
      background-color: transparent;
      /* 自带边框为 0 不显示 */
      border: 0;
      padding-left: 20px;
      padding-right: 30px;
      /* 去掉点击之后显示的黑色边框 */
      outline: 0;
    }

    /* 用户模块 */
    .user {
      margin-left: 32px;
    }

    .user img {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      /* 让文字和图片垂直居中对齐 */
      vertical-align: middle;
    }

    .user span {
      color: #666666;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <!-- search 搜索 -->
    <div class="search">
      <input type="search" placeholder="输入关键词">
    </div>

    <!-- user 用户区域 -->
    <div class="user">
      <a href="#">
        <img src="./uploads/user.png" alt="">
        <span>播仔学前端</span>
      </a>
    </div>
  </div>
</body>
</html>

关键行与易错点

  • .search 的 border-radius: 20px 正好是高度 40px 的一半,转写稿原话:“圆角是多圆?20 像素,是不是高的一半”。
  • input 与父级同宽高、background-color: transparent,目的是露出父盒子 .search 的灰底和圆角;border: 0 去掉表单自带边框,outline: 0 去掉点击后的黑框——这两个是两条不同的线,转写稿专门强调 border 是自带的、outline 是点击后才出现的,只写一个去不干净。
  • padding-left: 20px; padding-right: 30px; 给文字留位置,右侧 30px 是给后面学完定位再补的放大镜留的。
  • 易错点:input 写了 width: 412px 又加左右内边距,如果不写 box-sizing: border-box,实际宽度会变成 462px 撑破 412px 的父盒子。这里保留 * { box-sizing: border-box; } 就是为了修掉这个坑。
  • type="search" 会自带一个清除的小叉号,type="text" 没有,转写稿里现场对比演示过,按需要选。
  • vertical-align: middle 加在 img 上,因为图片默认是基线对齐,不加文字会贴到底部。
  • .user 里必须用 a 包住 img 和 span,转写稿说“A 一定要包进去,鼠标放到任何一个地方都能点击”。

示例二:header 导航 nav ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>header 导航 nav</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; }
    ul { list-style: none; }
    a { text-decoration: none; }

    .wrapper {
      display: flex;
      align-items: center;
      width: 1200px;
      height: 100px;
      margin: 0 auto;
    }

    /* 导航 */
    .nav {
      margin-left: 100px;
    }

    /* 让 li 在一行上:flex 加在 li 的爸爸 ul 上 */
    .nav ul {
      display: flex;
    }

    /* 盒子之间的距离给 li */
    .nav li {
      margin-right: 20px;
    }

    /* 修饰 A 一定找最近一级带类名的爸爸 */
    .nav li a {
      display: block;
      padding: 8px;
      line-height: 25px;
      font-size: 16px;
    }

    .nav li a:hover {
      border-bottom: 2px solid #00a4ff;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="nav">
      <ul>
        <li><a href="#">首页</a></li>
        <li><a href="#">课程</a></li>
        <li><a href="#">职业规划</a></li>
      </ul>
    </div>
  </div>
</body>
</html>

关键行与易错点

  • 结构是 div.nav > ul > li > a。转写稿反复强调:“不能直接放 A,要拿 li 把它们隔开”,一是避免一堆 A 堆在一起,二是方便给 li 加间距。
  • display: flex 加在 .nav ul 上,不是加在 a 上。转写稿:“A 本身就是横着的,我要把 li 在一行上,所以找 li 的爸爸 ul”。
  • a 不能给宽度,因为三个导航字数不一样(首页/课程/职业规划),给宽会装不下,所以用 padding: 8px 把盒子撑开、同时扩大点击范围。
  • 间距 margin-right: 20px 给 li 而不给 a:转写稿解释得很清楚,给 A 的话“你的 li 会被撑大,li 和 A 就不一样大了”,给 li 则两者一样大,更优雅。
  • line-height: 25px 用来微调文字的上下位置。转写稿提到 A 是行内元素,直接给上下 padding 位置会有偏差,用行高整体挪更靠谱。
  • 易错点:选择器绝不能写 .wrapper a 或更外层的类,否则会命中别的链接产生样式冲突,“本质原则就是找最近一级带类名的爸爸”。
  • 转写稿里下划线一开始给所有 li 都加了,后来“全部剪切走”,只留 :hover 状态,默认第一个有下划线的效果留到学 JS 再做。

示例三: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; }
    body { font-family: "Microsoft YaHei", sans-serif; }
    ul { list-style: none; }
    a { text-decoration: none; }

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

    /* banner 开始 */
    .banner {
      height: 420px;
      background-color: #0092cb;
    }

    /* 必须加 .banner 限定,否则和 header 里的 .wrapper 冲突 */
    .banner .wrapper {
      height: 420px;
      background: url(../uploads/banner.png);
      display: flex;
      /* 主轴两侧对齐 */
      justify-content: space-between;
      /* 侧轴居中 */
      align-items: center;
    }

    /* 侧导航 */
    .banner .left {
      padding: 3px 20px;
      width: 191px;
      height: 420px;
      /* 背景半透明 */
      background-color: rgba(0, 0, 0, 0.42);
    }

    .banner .left a {
      /* 块级:宽度是父级的 100% */
      display: block;
      height: 46px;
      background: url(../images/right.png) no-repeat right center;
      line-height: 46px;
      font-size: 16px;
      color: #fff;
    }

    .banner .left a:hover {
      background-image: url(../images/right-hover.png);
      color: #00a4ff;
    }

    .banner .right {
      width: 218px;
      height: 305px;
      background-color: pink;
    }
  </style>
</head>
<body>
  <div class="banner">
    <div class="wrapper">
      <div class="left">
        <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="#">云计算&amp;大数据</a></li>
          <li><a href="#">运维&amp;测试</a></li>
          <li><a href="#">UI设计</a></li>
          <li><a href="#">产品</a></li>
        </ul>
      </div>
      <div class="right">right</div>
    </div>
  </div>
</body>
</html>

关键行与易错点

  • .banner 是通栏盒子,只给高 420px 和底色 #0092cb,宽度不写,让标准流铺满。
  • .banner .wrapper 给了高度 420px,因为背景图不会撑开盒子,不给高背景图根本看不见。
  • 选择器必须写成 .banner .wrapper。转写稿原话:“谁你们的版心?banner 的 wrapper,要不然就和上面的冲突了”,header 里也有一个 .wrapper,不限定就会互相污染。
  • display: flex 写在 .wrapper(left 和 right 的亲爸爸)上;justify-content: space-between 让左右两个盒子分居两端,align-items: center 让右侧 305px 的盒子在 420px 里垂直居中。
  • 半透明用 rgba(0, 0, 0, 0.42):前三个 0 是纯黑,最后 0.42 相当于 42% 透明度,这个 0.42 是从像素大厨上量出来的。
  • 左侧 a 给 display: block,宽度自动等于父级的 100%,所以整行都能点;height: 46px 配合 line-height: 46px 让文字垂直居中;背景箭头用 no-repeat right center 固定在右侧。
  • 尺寸彩蛋:9 个 li × 46px = 414px,加上 .left 的上下 padding 3px × 2 = 6px,刚好 420px,和 banner 同高——所以 46 和 3 不是随便写的。
  • 易错点:.left 写了 width: 191px; height: 420px 又加了 padding: 3px 20px,不写 box-sizing: border-box 会变成 231 × 426,直接撑出 banner 并挤压右侧盒子。
  • right.png / banner.png 路径不存在时只会显示底色,不影响布局,可以先看结构对不对再补图。

常见错误 ​

  1. 现象:搜索框点击后出现黑色边框。→ 原因:只去掉了 border,没有处理聚焦外框。→ 修法:给 .search input 增加 outline: 0;。
  2. 现象:输入框盖住父盒子圆角和灰色底。→ 原因:input 保留了默认背景和边框。→ 修法:设置 background-color: transparent; border: 0;。
  3. 现象:用户区图片和文字上下错位。→ 原因:图片默认基线对齐。→ 修法:给 .user img 加 vertical-align: middle;,必要时再微调间距。
  4. 现象:banner 左右盒子没有分到两侧或没有垂直居中。→ 原因:flex、justify-content、align-items 加错父级。→ 修法:确认加在 .banner .wrapper 上,而不是 .banner 或 .left/.right 上。
  5. 现象:侧导航加内边距后总宽超出 191px,右侧被挤乱。→ 原因:盒子有固定宽高后又加左右 padding。→ 修法:优先只给上下 padding,或重新核算宽度并使用 box-sizing 思路修正。
  6. 现象:.left、.right 样式误作用到 header 其他区域。→ 原因:选择器范围过大,类名复用时未限定父级。→ 修法:写成 .banner .left、.banner .right,避免全局污染。
  7. 现象:导航项鼠标热区很小或下划线长度异常。→ 原因:把宽高或外边距随意加在 a 上,未用内边距撑开热区。→ 修法:用 padding 扩大 a 的可点击范围,项间距优先给 li。

练习 ​

  1. 打开搜索框聚焦状态,检查并修复“黑框、灰底被盖、文字贴边”三个问题,要求输入区域与父盒子视觉一致。
  2. 用浏览器调试工具定位一次 banner 右侧盒子掉行问题,记录你判断的顺序:先结构、再尺寸、再样式。
  3. 将导航项鼠标经过效果改为下划线显示,并检查每个导航项热区是否覆盖整块可点击区域。
  4. 给用户区图片与昵称之间增加合适间距,要求不破坏垂直居中对齐。
  5. 检查侧导航 .left 的最终盒模型尺寸,确保加 padding 后仍不超过设计宽度 191px。

原视频对照 ​

#视频时长
1学成在线-nav盒子搭建08:27
2学成在线nav制作完成13:15
3学成在线搜索盒子开始09:03
4学成在线搜索框结束09:35
5用户模块制作09:49
6调试代码08:36
7banner模块开始07:38
8左右盒子搭建05:56

小结 ​

  1. 先确认 DOM 兄弟/父子关系,再决定 flex 加在哪一层。
  2. 修饰组件样式时优先限定到最近一级带类名的父级,避免选择器污染。
  3. 表单控件进入页面前先做重置:边框、外框、背景、内边距逐项确认。
  4. 图片与文字混排时,默认对齐往往不是设计稿效果,需要显式校正。
  5. 固定宽高盒子加内边距前先算总尺寸,尤其是侧导航和版心区域。
  6. 调试页面时先看结构是否完整,再看盒子尺寸,最后查具体样式。
  7. 类名复用时加父级限定,是避免 header、banner 区域互相干扰的低成本手段。