Appearance
布局与响应式
HTML 搭结构、CSS 加样式,但元素还是从上到下堆叠。真实页面要左右分栏(侧栏+内容区)、横向工具栏(标题+按钮同一行)、小屏幕自动变单栏——这些都是布局的事。
布局核心工具是 Flex(弹性盒)。一个 display: flex 就能让子元素横向或纵向排列,控制对齐、间距和空间分配。
一、文档流与显示类型
浏览器默认按 HTML 出现顺序摆放元素。块级元素(div、p、section)各占一行,行内元素(a、span)跟文字流动排在一行。这个默认行为叫文档流——不写任何 CSS 就有的排列方式。
用 display 属性改变元素的排列行为:block(独占一行)、inline(跟文字排)、inline-block(一行内排但能设宽高)、flex(子元素按弹性盒排)。
css
.tag {
display: inline-block;
padding: 2px 8px;
border: 1px solid #d1d5db;
border-radius: 999px;
}inline-block 常用于小标签、短状态这类内容——它不像行内元素那样难控制尺寸。
二、Flex 基础
给父元素设 display: flex,它的直接子元素就进入 Flex 布局:
html
<div class="toolbar">
<h2>文章列表</h2>
<button type="button">新增</button>
</div>css
.toolbar {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: space-between; /* 两端分散:标题在左,按钮在右 */
gap: 12px; /* 子元素间距 */
}justify-content: space-between 把标题推到最左、按钮推到最右——这是页面工具栏最常见的布局。
Flex 的几个关键属性:flex-direction(row 横向排、column 纵向排)、gap(子元素间距)、justify-content(主轴对齐:space-between 两端分散、center 居中)、align-items(交叉轴对齐:center 居中、stretch 拉伸)、flex-wrap(wrap 放不下时换行)。
三、弹性尺寸
Flex 子元素可以用 flex 属性控制占用多少空间:
html
<div class="layout">
<nav class="sidebar">导航</nav>
<main class="content">文章内容</main>
</div>css
.layout {
display: flex;
gap: 16px;
}
.sidebar {
width: 220px;
flex: none; /* 固定宽度,不伸缩 */
}
.content {
flex: 1; /* 占用剩余空间 */
min-width: 0; /* 防止内容撑爆 */
}flex: none 让侧栏保持 220px 不变;flex: 1 让内容区吃掉剩下的所有空间。min-width: 0 在 Flex 内容区里很关键——不写的话,长文本、宽表格会把内容区撑出屏幕,因为 Flex 子元素默认 min-width: auto,不会收缩到比内容更小。
卡片列表换行排列:
css
.cards {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 240px; /* 基础宽度 240px,多了变宽,少了收缩换行 */
min-width: 0;
}四、常见页面结构
管理类页面通常长这样:顶部标题栏 + 左侧导航 + 右侧内容区。用 Flex 搭:
html
<div class="shell">
<header class="header">
<h1>文章管理</h1>
</header>
<div class="body">
<nav class="sidebar">
<a href="#published">已发布</a>
<a href="#drafts">草稿箱</a>
</nav>
<main class="content">
<!-- 文章列表 -->
</main>
</div>
</div>css
.shell {
min-height: 100vh; /* 至少占满整个视口高度 */
}
.header {
padding: 16px 24px;
border-bottom: 1px solid #e5e7eb;
background-color: #ffffff;
}
.body {
display: flex; /* 侧栏和内容区左右排列 */
}
.sidebar {
width: 220px;
flex: none;
padding: 16px;
border-right: 1px solid #e5e7eb;
}
.content {
flex: 1;
min-width: 0;
padding: 24px;
}.body 用 Flex 让侧栏和内容区左右排。侧栏固定 220px,内容区 flex: 1 占剩余空间。这就是大多数后台管理页面的骨架。
五、响应式——小屏幕自适应
同一个页面在桌面(宽屏)和手机(窄屏)上都要能用。桌面左右分栏,手机改成上下排列。用媒体查询(@media)在不同宽度下切换布局:
css
@media (max-width: 720px) {
.body {
flex-direction: column; /* 左右排列改成上下排列 */
}
.sidebar {
width: auto; /* 不再固定 220px */
border-right: 0;
border-bottom: 1px solid #e5e7eb;
}
}视口宽度小于等于 720px 时,.body 从横向变纵向,侧栏从左侧变成顶部。720px 这个值叫断点——不是固定标准,按内容决定。常见做法:960px 以下减少留白、720px 以下双栏改单栏、480px 以下进一步压缩。
响应式先看内容能不能读、能不能点、会不会横向溢出。动画和细节可以晚点处理。
六、内容溢出
小屏幕上最容易出问题的几种溢出:
宽表格——列多时表格比屏幕宽,加横向滚动容器:
html
<div class="table-wrap">
<table>
<!-- 列很多的表格 -->
</table>
</div>css
.table-wrap {
overflow-x: auto; /* 横向滚动 */
}
.table-wrap table {
min-width: 520px; /* 表格本身不压缩,外层滚动 */
}长文本——长链接或长英文单词不断行会撑宽容器:
css
.content {
overflow-wrap: anywhere; /* 长文本强制换行 */
}固定宽度——写死 width: 320px 在窄屏上会溢出,加 max-width: 100% 兜底:
css
.card {
width: 320px;
max-width: 100%;
}七、完整布局页面
把前面的布局技术合到一个文章管理页面。桌面端双栏(侧栏+内容区),720px 以下自动变单栏。
文件:index.html
html
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>文章管理</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="shell">
<header class="header">
<h1>文章管理</h1>
</header>
<div class="body">
<nav class="sidebar">
<a href="#published">已发布</a>
<a href="#drafts">草稿箱</a>
</nav>
<main class="content">
<section class="card">
<div class="toolbar">
<h2>已发布</h2>
<button type="button">新增</button>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>标题</th>
<th>分类</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>Python 入门</td>
<td>技术</td>
<td>已发布</td>
</tr>
<tr>
<td>CSS 布局笔记</td>
<td>技术</td>
<td>已发布</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
</div>
</div>
</body>
</html>文件:style.css
css
* {
box-sizing: border-box;
}
body {
margin: 0;
color: #111827;
background-color: #f3f4f6;
font-family: Arial, "Microsoft YaHei", sans-serif;
line-height: 1.6;
}
.shell {
min-height: 100vh;
}
.header {
padding: 16px 24px;
border-bottom: 1px solid #e5e7eb;
background-color: #ffffff;
}
.header h1 {
margin: 0;
font-size: 24px;
}
.body {
display: flex;
}
.sidebar {
display: flex;
flex-direction: column;
gap: 8px;
width: 220px;
flex: none;
padding: 16px;
border-right: 1px solid #e5e7eb;
background-color: #ffffff;
}
.sidebar a {
color: #2563eb;
text-decoration: none;
}
.content {
flex: 1;
min-width: 0;
padding: 24px;
}
.card {
padding: 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
background-color: #ffffff;
}
.toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.toolbar h2 {
margin: 0;
font-size: 18px;
}
button {
padding: 8px 12px;
border: 1px solid #2563eb;
border-radius: 6px;
color: #ffffff;
background-color: #2563eb;
cursor: pointer;
}
.table-wrap {
overflow-x: auto;
}
table {
width: 100%;
min-width: 400px;
border-collapse: collapse;
}
th, td {
padding: 10px 12px;
border-bottom: 1px solid #e5e7eb;
text-align: left;
}
th {
background-color: #f9fafb;
font-weight: 600;
}
/* 小屏幕:双栏改单栏 */
@media (max-width: 720px) {
.body {
flex-direction: column;
}
.sidebar {
width: auto;
flex-direction: row;
flex-wrap: wrap;
gap: 12px;
border-right: 0;
border-bottom: 1px solid #e5e7eb;
}
.content {
padding: 16px;
}
}拖动浏览器窗口宽度到 720px 以下,侧栏从左边移到顶部,内容区变成全宽——这就是响应式。整个页面到现在还是静态的:点新增按钮没有反应,表格数据是写死的。交互需要 JavaScript,那是接下来的事。
八、常见问题
| 现象 | 常见原因 | 排查入口 |
|---|---|---|
| 子元素没有横向排列 | 父元素没设 display: flex | 父元素样式 |
| 内容区被表格撑宽 | Flex 子元素缺 min-width: 0 | .content 的 min-width |
| 小屏幕仍是双栏 | 媒体查询没命中或被覆盖 | DevTools 视口宽度、Styles 面板 |
| 元素间距不一致 | 混用了 margin 和 gap | 统一用 gap |
布局排查时,开发者工具选中元素看盒模型尺寸、父元素 display、是否命中媒体查询,基本能定位。F12 打开 DevTools,Elements 面板选元素,Computed 区域看实际生效的 display 和尺寸。