CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
前端入门实战/课时/CSS
RawBlame
课时目录12 节

前端入门实战

  1. 01HTML
  2. 02CSS
  3. 03JavaScript
  4. 04Git
  5. 05GitHub
  6. 06npm
  7. 07React
  8. 08Tailwind
  9. 09Vitest
  10. 10综合练习
  11. 11部署预览
  12. 12路线图对照

CSS

布局与样式。

30 分钟

CSS:选择器、盒模型与布局系统

这一课你将能做到

  1. 写出现代 CSS 选择器,精准命中页面中的任意元素
  2. 用盒模型、flex 和 grid 三种方式控制元素的大小和位置
  3. 搭建一个完整的响应式页面,包含媒体查询和基础过渡动画

为什么要学

HTML 搭好了骨架,但所有网站都是「素颜」的白纸黑字。CSS 负责颜色、间距、排版、位置,也负责让同一套代码在手机、平板、电脑上看起来都对劲。不会 CSS,你就只能做出 90 年代的网页。

对初学者来说,CSS 的坑在于:它看起来很简单(就是改样式),但背后有层叠、优先级、盒模型、定位上下文等多个独立维度互相干扰。很多初学者写的样式「为什么不生效」或「为什么多了一像素」,本质上是对盒模型和层叠理解不到位。

先建立图像

浏览器把每个 HTML 元素都渲染成一个矩形盒子。盒子的构成从外到内:

┌─────────────────────────────────┐
│           margin(外边距)       │
│  ┌─────────────────────────────┐│
│  │       border(边框)         ││
│  │  ┌───────────────────────┐  ││
│  │  │     padding(内边距)  │  ││
│  │  │  ┌─────────────────┐  │  ││
│  │  │  │   content       │  │  ││
│  │  │  │   宽 × 高        │  │  ││
│  │  │  └─────────────────┘  │  ││
│  │  └───────────────────────┘  ││
│  └─────────────────────────────┘│
└─────────────────────────────────┘

默认情况下你写的 width 和 height 只是 content 区域。CSS3 引入了 box-sizing: border-box,让 width/height 直接代表整个可见盒子的大小——这是现代开发的标准做法。

跟着做

步骤 1:重置默认样式并理解盒模型

新建 style.css,写入:

/* 让所有元素按 border-box 计算,现代项目标配 */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.box {
    width: 200px;
    height: 100px;
    padding: 20px;
    border: 5px solid #333;
    margin: 15px;
    background-color: #f0f0f0;
}

在 index.html 中引入:

<head>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="box">内容区</div>
</body>

.box 的总渲染宽度是 200px(width)+ 0 padding/border/margin 不算入,因为用了 border-box。删掉 box-sizing 行再试,宽度会变成 250px(200 + 20×2 + 5×2),这就是标准盒模型的经典陷阱。

步骤 2:选择器层级练习

/* 1. 元素选择器 */
h1 {
    color: #1a1a1a;
}

/* 2. 类选择器 */
.card {
    background: white;
    border-radius: 8px;
}

/* 3. ID 选择器 */
#hero {
    min-height: 400px;
}

/* 4. 后代选择器:nav 里的所有 a */
nav a {
    text-decoration: none;
}

/* 5. 子选择器:ul 的直接子 li */
ul > li {
    list-style: none;
}

/* 6. 相邻兄弟 */
h2 + p {
    margin-top: 0.5rem;
}

/* 7. 伪类 */
a:hover {
    color: #e63946;
}

li:nth-child(odd) {
    background: #f8f9fa;
}

/* 8. 伪元素 */
h1::after {
    content: "!";
    color: #e63946;
}

class 优先级 0-1-0,id 是 1-0-0,内联样式(style="")是 1-0-0-0。优先级冲突时数字大的赢。多记一个规则:优先级相同,后写的覆盖先写的。

步骤 3:Flex 布局

Flex 是目前最常用的布局方式,用于一维排列(一行或一列):

.container {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    justify-content: center; /* 主轴对齐 */
    align-items: center;     /* 交叉轴对齐 */
}

.item {
    flex: 1 1 200px; /* 可放大、可缩小、基准 200px */
    min-height: 120px;
    background: #dee2e6;
    display: flex;
    align-items: center;
    justify-content: center;
}
<div class="container">
    <div class="item">A</div>
    <div class="item">B</div>
    <div class="item">C</div>
</div>

三个核心属性必记:

  • justify-content:主轴对齐(默认 row 时就是水平方向)
  • align-items:交叉轴对齐(默认 row 时就是垂直方向)
  • flex-wrap: wrap:空间不够时自动换行,不写的话子元素会被压扁

步骤 4:Grid 布局

Grid 用于二维布局(同时控制行和列),适合仪表盘、图片画廊、整体页面骨架:

.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

.grid-item:first-child {
    grid-column: span 2; /* 第一个元素占两列 */
}
<div class="grid-container">
    <div class="grid-item">占两列</div>
    <div class="grid-item">B</div>
    <div class="grid-item">C</div>
    <div class="grid-item">D</div>
    <div class="grid-item">E</div>
</div>

repeat(3, 1fr) 表示三列等宽;1fr 是「一份剩余空间」。如果要实现侧边栏固定、主内容自适应:grid-template-columns: 250px 1fr。

步骤 5:定位

/* 相对定位:相对于自己原本的位置偏移 */
.relative-box {
    position: relative;
    top: 10px;
    left: 10px;
}

/* 绝对定位:相对于最近的非 static 祖先元素 */
.parent {
    position: relative;
}

.absolute-box {
    position: absolute;
    top: 0;
    right: 0;
}

/* 固定定位:相对于视口 */
.fixed-header {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 1000;
}

绝对定位会脱离文档流,不占据原来的空间;相对定位不会脱离,只是视觉上偏移。z-index 只在定位元素(非 static)上有效。

步骤 6:响应式基础

.container {
    padding: 16px;
    max-width: 1200px;
    margin: 0 auto;
}

/* 手机优先:小屏幕默认,大屏幕覆盖 */
@media (min-width: 768px) {
    .container {
        padding: 32px;
    }
}

@media (min-width: 1024px) {
    .grid-container {
        grid-template-columns: repeat(4, 1fr);
    }
}

现代前端普遍采用「移动优先」写法:先写手机样式,再用 min-width 媒体查询叠加桌面样式。这样加载的 CSS 更少,逻辑也更清晰。

步骤 7:基础过渡动画

.button {
    background: #4361ee;
    color: white;
    padding: 12px 24px;
    border: none;
    border-radius: 6px;
    transition: background 0.3s ease, transform 0.2s ease;
    cursor: pointer;
}

.button:hover {
    background: #3a0ca3;
    transform: translateY(-2px);
}

transition 写在默认状态上,这样悬停和离开都有过渡效果。

讲清楚要点

  1. 盒模型是一切的基础:content-box(默认,width 只含 content)vs border-box(width 含 content + padding + border)。现代项目通配符重置 border-box 是行业惯例。
  2. 层叠和优先级决定「谁生效」:不是后写一定赢,而是优先级高者赢。!important 是核武器,只在覆盖第三方库或临时调试时用,禁止在自己代码里滥用。
  3. Flex 管一维,Grid 管二维:简单横向/纵向排列用 Flex;同时需要行列控制的复杂布局用 Grid。
  4. 定位要理解「参照物」:relative 参照自己,absolute 参照最近的定位祖先,fixed 参照视口。没有定位祖先时 absolute 会一路追到 body。
  5. 响应式不是写两套页面:是同一套代码在不同断点(breakpoint)做渐进增强。常用断点:768px(平板)、1024px(小桌面)、1280px(桌面)。

你可能会懵的地方

  • 为什么我的样式不生效? 按这个顺序排查:选择器写错(类名拼写)→ 优先级不够(被覆盖)→ 属性拼写错误 → 浏览器缓存(Ctrl+F5)。

  • margin 的上下边距会合并? 是的。垂直相邻块级元素的 margin-top 和 margin-bottom 不会相加,而是取最大值。这是 CSS 的标准行为,用 Flex 的 gap 或只用一个方向的 margin 来规避。

  • flex: 1 到底是什么意思? flex: 1 是 flex-grow: 1; flex-shrink: 1; flex-basis: 0% 的简写。意思是「我参与分配剩余空间,基准大小为 0」。

  • 百分比宽度是相对于谁? 相对于直接父元素的内容区宽度。如果父元素没有显式宽度,百分比可能无效。width: 100% 加 padding 在不设 border-box 时会撑破容器。

  • Grid 和 Flex 能不能嵌套? 完全可以。一个 grid item 里面放 flex container,或者反过来,都是常见做法。没有性能问题,放心用。

错法对照

错法问题正解
width: 100% + padding 不用 border-box实际宽度超过父容器通配符重置 border-box
滥用 !important优先级不可控,后期无法覆盖用更高特异性的选择器
用 float 做页面布局浮动原本用于图文混排,做布局难维护用 Flex/Grid
定位元素不写 z-index层叠顺序由 DOM 顺序决定,难以预期显式设置 z-index
垂直居中用 margin: auto只对水平方向生效用 Flex 的 align-items: center
所有元素都设 height: 100%内容撑不开,溢出截断内容撑开高度,容器用 min-height
媒体查询写一堆 max-width逻辑混乱,CSS 冗余移动优先,用 min-width 渐进增强

卡点急救

  1. 样式改了不生效:F12 的 Elements 面板看对应元素,右侧 Styles 会显示生效规则和被打叉的规则;被打叉的规则就是优先级不够或被覆盖。
  2. 元素位置不对:F12 → Computed → 看盒模型示意图,确认 margin/padding/border 各是多少。
  3. Flex 子元素被压扁:给子元素加 min-width: 0(防止内容撑开)或给容器加 flex-wrap: wrap。
  4. Grid 出现意外的空白列:grid-template-columns 定义的列数与实际 item 数量不匹配,检查 HTML 结构。

面试常问

  • 盒模型是什么?标准盒模型和 IE 盒模型的区别? 标准模型下 width/height 只含 content;IE 模型(即 border-box)下含 content + padding + border。现代开发通配符设置 box-sizing: border-box 就是为了统一用 IE 模型。

  • BFC 是什么?怎么创建? BFC(Block Formatting Context)是一块独立的渲染区域,内部布局不影响外部。创建方式:float 不为 none、position 为 absolute/fixed、display 为 inline-block/flex/grid、overflow 不为 visible。经典应用:清除浮动、防止 margin 合并、阻止文字环绕浮动。

  • 居中一个元素有多少种方法? 至少三种:1) Flex:justify-content: center; align-items: center;2) Grid:place-items: center;3) 绝对定位 + transform: translate(-50%, -50%)。

  • rem、em、px 的区别? px 是绝对单位;em 相对于父元素字体大小;rem 相对于根元素(html)字体大小。现代响应式项目推荐 rem + 根元素动态字体大小。

自测三问

  1. box-sizing: border-box 到底改变了什么计算规则?
  2. 写一段 Flex 代码,实现「三个卡片等宽,间距 16px,超出换行」。
  3. position: absolute 的参照物是谁?如果没有定位祖先会怎样?

小结一句话

CSS 的核心是「选得到、放得下、排得齐」——选择器命中目标、盒模型控制尺寸、Flex/Grid 控制位置,三者叠加就能做出任何现代页面布局。

延伸

  • MDN CSS 基础
  • 下一课:JavaScript——让页面动起来,学会变量、函数、DOM 操作和事件监听。
加载本节练习…
← 上一课HTML下一课 →JavaScript