布局:盒子、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>- L2内容 200 + 内边距 16 × 2 + 边框 2 × 2 = 屏幕上 236px。
- 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>- L2父元素变成 flex 容器;gap 在子元素之间留 16px。
- 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>- L3只在宽度不超过 600px 的屏幕上……
- L4……卡片竖着排。把预览区拉窄就能看到。
常见错误
算宽度时忘了内边距
宽 100% 又带内边距的盒子会撑破父元素。设置 box-sizing: border-box(大多数项目会给所有元素都设置)。
把 display: flex 写在子元素上
flex 安排的是元素的子元素。要让卡片排成一行,写在它们的容器上。
到处都写死像素宽度
900px 宽的盒子放不进 390px 的手机。让 flex 去分配空间,小屏幕用媒体查询处理。
小测验
1. 默认 box-sizing 下,`width: 100px; padding: 10px; border: 1px solid`。屏幕上盒子多宽?
查看答案
答案:A
100 + 10 + 10 + 1 + 1 = 122。
2. 要让三个按钮排成一行,`display: flex` 写在哪?
查看答案
答案:A
flex 排列的是它所在元素的子元素。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出量一量卡片
这张卡片在屏幕上有多宽?
- 改需求让卡片排成一行
三张卡片应该并排,中间隔 16px,现在却竖着叠在一起。修好 CSS。
- 从零写侧边栏布局
给这个页面写 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. |