人人都能学编程
English 开始学习
核心 · 前端第 4 课 / 共 8 课免费阅读

布局:盒子、flexbox、手机 · 前端:HTML、CSS 与 JavaScript

盒子是怎么并排摆放的,又怎么在手机上也放得下?

课程目录

为什么需要它

写 CSS 的大部分时间都花在布局上。两个概念就能解决大部分问题:每个元素都是一个盒子,大小可以算出来;flexbox 把盒子排成一行或一列。再加一个媒体查询,同一个页面在手机上也能用。

直觉理解

盒模型。 每个元素都是一个盒子,从里到外分几层:内容、内边距 padding(边框里面的空白)、边框 border、外边距 margin(边框外面的空白)。

默认情况下,width 只管内容。width: 200px; padding: 16px; border: 2px solid 时,屏幕上的盒子宽 200 + 16 + 16 + 2 + 2 = 236px。加上 box-sizing: border-box,width 就包含了内边距和边框,盒子正好 200px。大多数网站会给所有元素都加上它。

Flexbox。 在父元素上写 display: flex,它的子元素就排成一行:

.toolbar { display: flex; gap: 12px; justify-content: space-between; align-items: center; }
  • gap:子元素之间的间距
  • justify-content:沿着这一行怎么分布
  • align-items:垂直于这一行怎么对齐
  • flex-direction: column:改成竖着排

媒体查询。 写在 @media (max-width: 600px) { … } 里的规则,只在宽度不超过 600px 的屏幕上生效,这样就可以在手机上把一行改成竖排。

display: grid 是 flex 的二维版本,同时管行和列。

定义

盒模型

Content, padding, border and margin, from the inside out. With content-box sizing, width covers the content only.
从里到外依次是内容、内边距、边框、外边距。content-box 模式下,width 只算内容。

Flexbox 弹性布局

display: flex on a parent lays its children out in a row (or a column), with gap, justify-content and align-items controlling the space.
在父元素上写 display: flex,子元素就排成一行(或一列),间距和对齐由 gap、justify-content、align-items 控制。

媒体查询

@media (max-width: 600px) { … }: rules that apply only when the screen matches the condition.
@media (max-width: 600px) { … }:只在屏幕满足条件时才生效的规则。

示例

它到底有多宽?

在互动课里运行

同样的 width,两个不同的盒子。

<style>
  .a { width: 200px; padding: 16px; border: 2px solid black; }
  .b { width: 200px; padding: 16px; border: 2px solid black; box-sizing: border-box; }
</style>
<div class="a">content-box</div>
<div class="b">border-box</div>
逐步执行
  1. L2内容 200 + 内边距 16 × 2 + 边框 2 × 2 = 屏幕上 236px。
  2. L3border-box:内边距和边框都算在 200px 里面,所以盒子就是 200px。

在父元素上写 display: flex,卡片就并排了。

   <style>
     .cards { display: flex; gap: 16px; }
     .card { flex: 1; padding: 12px; border: 1px solid #ccc; }
   </style>

<div class="cards">
  <div class="card">One</div>
  <div class="card">Two</div>
  <div class="card">Three</div>
</div>
逐步执行
  1. L2父元素变成 flex 容器;gap 在子元素之间留 16px。
  2. L3flex: 1 让卡片平分剩余空间。

在手机上竖着排

在互动课里运行

一个媒体查询,在窄屏上把一行改成一列。

   <style>
     .cards { display: flex; gap: 16px; }
     @media (max-width: 600px) {
       .cards { flex-direction: column; }
     }
   </style>

<div class="cards">
  <div class="card">One</div>
  <div class="card">Two</div>
  <div class="card">Three</div>
</div>
逐步执行
  1. L3只在宽度不超过 600px 的屏幕上……
  2. L4……卡片竖着排。把预览区拉窄就能看到。

常见错误

算宽度时忘了内边距

宽 100% 又带内边距的盒子会撑破父元素。设置 box-sizing: border-box(大多数项目会给所有元素都设置)。

把 display: flex 写在子元素上

flex 安排的是元素的子元素。要让卡片排成一行,写在它们的容器上。

到处都写死像素宽度

900px 宽的盒子放不进 390px 的手机。让 flex 去分配空间,小屏幕用媒体查询处理。

小测验

1. 默认 box-sizing 下,`width: 100px; padding: 10px; border: 1px solid`。屏幕上盒子多宽?

  1. A122px
  2. B100px
  3. C120px
查看答案

答案:A

100 + 10 + 10 + 1 + 1 = 122。

2. 要让三个按钮排成一行,`display: flex` 写在哪?

  1. A写在包着按钮的元素上
  2. B写在每个按钮上
  3. C只写在 body 上
查看答案

答案:A

flex 排列的是它所在元素的子元素。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出量一量卡片

    这张卡片在屏幕上有多宽?

  2. 改需求让卡片排成一行

    三张卡片应该并排,中间隔 16px,现在却竖着叠在一起。修好 CSS。

  3. 从零写侧边栏布局

    给这个页面写 CSS:

    • .layout 让侧边栏和主区域并排
    • .sidebar 在屏幕上正好 240px 宽,包括它 16px 的内边距
    • 在宽度不超过 600px 的屏幕上,.layout 改成竖着排

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
Box model盒模型Content, padding, border and margin around every element.
Flexbox弹性布局A layout mode that arranges children in a row or column.
Media query媒体查询CSS that applies only when the screen matches a condition, such as max-width.
Responsive design响应式设计One page that adapts to any screen size.