跳转到内容

CSS 基础教程

建议学习 75 分钟更新于 2023/3/20

CSS 是网页的视觉语言。HTML 负责描述页面结构,CSS 负责控制页面长什么样:颜色、字体、间距、边框、布局、响应式、动画,都离不开 CSS。

学习 CSS 时,不要只背属性。更重要的是理解三个问题:

  • 这个样式会作用到哪些元素?
  • 这个元素在页面里占多少空间?
  • 这些元素之间如何排列?

理解了这三个问题,CSS 就会从“玄学调样式”变成一套可以推理的规则。

CSS 全称是 Cascading Style Sheets,中文通常叫层叠样式表。

“层叠”是 CSS 的核心特点:同一个元素可能同时被多条规则影响,浏览器会根据选择器权重、规则顺序、继承关系来决定最终样式。

一个最简单的 CSS 规则如下:

/* 选择页面中所有 p 标签 */
p {
/* 设置文字颜色 */
color: #333;
/* 设置字体大小 */
font-size: 16px;
/* 设置行高,让正文更容易阅读 */
line-height: 1.7;
}

这段 CSS 的意思是:找到所有 <p> 元素,然后给它们设置颜色、字号和行高。

刚开始学习 CSS,可以用下面这种结构:

  • 文件夹css-demo/
    • index.html
    • 文件夹assets/
      • 文件夹styles/
        • reset.css
        • style.css
      • 文件夹images/
        • cover.jpg

其中:

  • index.html 放页面结构。
  • reset.css 放浏览器默认样式重置。
  • style.css 放自己的页面样式。
  • images/ 放图片资源。

实际项目里文件会更多,但入门阶段先保持简单。

最推荐的方式是使用外部 CSS 文件。

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CSS 示例</title>
<!-- 引入外部 CSS 文件 -->
<!-- href 是 CSS 文件路径 -->
<!-- rel="stylesheet" 表示这是一个样式表 -->
<link rel="stylesheet" href="./assets/styles/style.css" />
</head>
<body>
<h1>你好,CSS</h1>
</body>
</html>

外部样式表的优点:

  • HTML 和 CSS 分离,结构更清楚。
  • 多个页面可以复用同一个 CSS 文件。
  • 浏览器可以缓存 CSS 文件,加载更高效。

内部样式写在 HTML 的 <style> 标签里。

<style>
/* 这段样式只影响当前 HTML 页面 */
h1 {
color: orange;
}
</style>

这种方式适合简单演示,不适合长期维护的大页面。

行内样式直接写在元素上。

<h1 style="color: orange; font-size: 32px;">你好,CSS</h1>

行内样式不推荐大量使用,因为:

  • 结构和样式混在一起。
  • 不方便复用。
  • 权重较高,后续覆盖麻烦。

CSS 由选择器和声明块组成。

/* p 是选择器,表示选中所有 p 元素 */
p {
/* color 是属性,#333 是属性值 */
color: #333;
/* 每条声明通常以分号结束 */
font-size: 16px;
}

基本结构是:

选择器 {
属性: 属性值;
}

如果忘记分号,有些情况下浏览器仍能解析,但建议始终写上,避免后续新增属性时出错。

标签选择器会选中页面里所有同名标签。

/* 选中所有 h1 */
h1 {
color: #222;
}
/* 选中所有 p */
p {
color: #555;
}

标签选择器适合设置全局基础样式。

类选择器以 . 开头。

<p class="intro">这是一段介绍文字。</p>
/* 选中 class="intro" 的元素 */
.intro {
color: #666;
font-size: 18px;
}

类选择器是实际项目中最常用的选择器。一个元素可以有多个类名:

<button class="button button-primary">提交</button>
/* 按钮基础样式 */
.button {
padding: 8px 16px;
border: 0;
border-radius: 6px;
cursor: pointer;
}
/* 主按钮样式 */
.button-primary {
color: white;
background: #f08a24;
}

ID 选择器以 # 开头。

<section id="profile">个人介绍</section>
/* 选中 id="profile" 的元素 */
#profile {
padding: 24px;
}

ID 在同一个页面中应该唯一。一般不建议用 ID 写大量样式,因为权重较高,后续覆盖不方便。

后代选择器用空格连接。

<article class="post">
<h2>文章标题</h2>
<p>文章摘要。</p>
</article>
/* 选中 .post 里面的所有 h2 */
.post h2 {
color: #222;
}
/* 选中 .post 里面的所有 p */
.post p {
color: #666;
}

后代选择器不要写得太长,否则样式会变得难维护。

子代选择器用 > 连接,只选中直接子元素。

/* 只选中 .nav 下面第一层的 a */
.nav > a {
color: #333;
text-decoration: none;
}

如果 .nav 里面还有更深层的链接,这条规则不会影响它们。

伪类用于描述元素的某种状态。

/* 鼠标悬停时 */
a:hover {
color: #f08a24;
}
/* 输入框聚焦时 */
input:focus {
outline: 2px solid #f08a24;
}
/* 列表中的第一个子元素 */
li:first-child {
font-weight: bold;
}

伪类常用于交互状态。

当多条 CSS 同时作用到一个元素时,浏览器会根据权重决定谁生效。

<p id="summary" class="text">这是一段文字。</p>
/* 标签选择器,权重较低 */
p {
color: gray;
}
/* 类选择器,权重更高 */
.text {
color: blue;
}
/* ID 选择器,权重更高 */
#summary {
color: red;
}

最终文字会是红色。

简单记忆:

  • 行内样式权重很高。
  • ID 选择器高于类选择器。
  • 类选择器高于标签选择器。
  • 权重相同时,后写的规则覆盖先写的规则。

尽量不要依赖很高的权重解决问题。样式越依赖强行覆盖,后期越难维护。

有些 CSS 属性会从父元素继承给子元素。

body {
/* color 会被多数文本元素继承 */
color: #333;
/* font-family 也会被继承 */
font-family: system-ui, sans-serif;
}

继承属性常见有:

  • color
  • font-family
  • font-size
  • line-height

不继承的属性常见有:

  • margin
  • padding
  • border
  • width
  • height

理解继承后,你就不需要给每个元素重复写文字颜色和字体。

CSS 里常见的颜色写法有几种。

.color-demo {
/* 颜色关键词,简单但不够灵活 */
color: red;
/* 十六进制,常见于设计稿 */
color: #f08a24;
/* rgb,分别表示红、绿、蓝 */
color: rgb(240, 138, 36);
/* rgba,最后一个值表示透明度 */
color: rgba(240, 138, 36, 0.8);
/* hsl,适合系统化调整色相、饱和度、亮度 */
color: hsl(30, 87%, 54%);
}

实际项目里,我更推荐使用 CSS 变量管理颜色。

:root {
/* 主色 */
--color-accent: hsl(30, 87%, 54%);
/* 正文颜色 */
--color-text: hsl(220, 12%, 18%);
/* 弱化文字 */
--color-muted: hsl(220, 8%, 46%);
}
body {
color: var(--color-text);
}
a {
color: var(--color-accent);
}

使用变量的好处是:以后要换主题色,只需要改变量,不用到处找颜色值。

字体相关属性经常一起使用。

body {
/* 系统字体,适合大多数中文网站 */
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
/* 基础字号 */
font-size: 16px;
/* 行高,正文建议 1.6 到 1.8 */
line-height: 1.7;
/* 正文颜色 */
color: #333;
}
h1 {
/* 标题字号 */
font-size: 40px;
/* 字重 */
font-weight: 700;
/* 标题行高通常比正文小 */
line-height: 1.2;
}
p {
/* 段落上方不留空,只用下方间距控制节奏 */
margin-top: 0;
margin-bottom: 16px;
}

常见文本属性:

.text-demo {
/* 文本居中 */
text-align: center;
/* 去掉链接下划线 */
text-decoration: none;
/* 英文字母大写 */
text-transform: uppercase;
/* 字间距,谨慎使用 */
letter-spacing: 0.04em;
}

中文正文不建议把 letter-spacing 调得很大,否则阅读会变累。

盒模型是 CSS 最重要的基础之一。页面上的每个元素都可以理解为一个盒子。

一个盒子由四部分组成:

  • content:内容区域。
  • padding:内边距。
  • border:边框。
  • margin:外边距。
.box {
/* 内容宽度 */
width: 240px;
/* 内容高度 */
height: 120px;
/* 内边距,内容和边框之间的距离 */
padding: 16px;
/* 边框 */
border: 1px solid #ddd;
/* 外边距,盒子和其他盒子之间的距离 */
margin: 24px;
}

默认情况下,width 只表示 content 宽度,不包含 padding 和 border。

更推荐全局设置:

* {
/* 让 width 包含 content、padding、border */
box-sizing: border-box;
}

这样写之后:

.card {
/* 整个卡片的最终宽度就是 320px */
width: 320px;
/* padding 会被计算在 320px 内部 */
padding: 24px;
border: 1px solid #ddd;
}

这会让布局更直观。

margin 是外部距离,padding 是内部距离。

.card {
/* 卡片和其他元素之间的距离 */
margin-bottom: 24px;
/* 卡片内容和卡片边缘之间的距离 */
padding: 20px;
}

一个简单判断:

  • 想让两个元素离远一点,用 margin
  • 想让元素里面的内容不要贴边,用 padding

常见写法:

.demo {
/* 四个方向都是 16px */
padding: 16px;
/* 上下 12px,左右 20px */
padding: 12px 20px;
/* 上 8px,左右 16px,下 24px */
padding: 8px 16px 24px;
/* 上、右、下、左,顺时针 */
padding: 8px 12px 16px 20px;
}

margin 也支持同样写法。

display 决定元素如何参与布局。

.block {
/* 块级元素,默认占满一行 */
display: block;
}
.inline {
/* 行内元素,不会独占一行 */
display: inline;
}
.inline-block {
/* 行内排列,但可以设置宽高 */
display: inline-block;
}
.hidden {
/* 不显示,也不占空间 */
display: none;
}

常见默认行为:

  • divph1 默认是 block
  • spanastrong 默认是 inline
  • img 比较特殊,表现类似行内替换元素。

Flex 适合一维布局:一行或一列。

<nav class="nav">
<a href="/">首页</a>
<a href="/blog/">博客</a>
<a href="/knowledge/">知识库</a>
</nav>
.nav {
/* 开启 Flex 布局 */
display: flex;
/* 子元素之间的间距 */
gap: 16px;
/* 主轴方向上的对齐方式 */
justify-content: center;
/* 交叉轴方向上的对齐方式 */
align-items: center;
}

常用属性:

.flex-demo {
display: flex;
/* row 是默认值,横向排列 */
flex-direction: row;
/* 空间不够时允许换行 */
flex-wrap: wrap;
/* 主轴对齐 */
justify-content: space-between;
/* 交叉轴对齐 */
align-items: center;
/* 子元素间距 */
gap: 12px;
}

卡片列表也可以用 Flex:

.card-list {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
/* flex: grow shrink basis */
/* 允许放大,允许缩小,基础宽度 240px */
flex: 1 1 240px;
}

Flex 常用于:

  • 导航栏。
  • 按钮组。
  • 卡片列表。
  • 左右对齐。
  • 垂直居中。

Grid 适合二维布局:行和列同时控制。

<section class="grid">
<article>卡片 1</article>
<article>卡片 2</article>
<article>卡片 3</article>
</section>
.grid {
/* 开启 Grid 布局 */
display: grid;
/* 创建三列,每列平分可用空间 */
grid-template-columns: repeat(3, 1fr);
/* 网格间距 */
gap: 20px;
}

响应式网格可以这样写:

.grid {
display: grid;
/* auto-fit:根据容器宽度自动放下尽可能多的列 */
/* minmax(220px, 1fr):每列最小 220px,最大平分剩余空间 */
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}

这段写法非常实用,适合文章卡片、产品卡片、标签列表等。

position 用来控制元素定位方式。

.normal {
/* 默认值,元素在正常文档流中 */
position: static;
}
.relative {
/* 相对自身原本位置偏移 */
position: relative;
top: 8px;
left: 8px;
}
.absolute {
/* 相对最近的定位祖先元素定位 */
position: absolute;
top: 0;
right: 0;
}
.fixed {
/* 相对浏览器窗口定位 */
position: fixed;
right: 24px;
bottom: 24px;
}
.sticky {
/* 滚动到指定位置后吸附 */
position: sticky;
top: 0;
}

常见组合是父元素 relative,子元素 absolute

.card {
/* 给绝对定位子元素提供定位参考 */
position: relative;
}
.badge {
/* 相对 .card 定位 */
position: absolute;
top: 12px;
right: 12px;
}

不要滥用 position: absolute 做整体布局。现代页面布局优先考虑 Flex 和 Grid。

响应式设计让页面在不同屏幕宽度下都有合理表现。

最常见方式是媒体查询。

.layout {
display: grid;
grid-template-columns: 1fr 280px;
gap: 32px;
}
/* 当屏幕宽度小于等于 768px 时 */
@media (max-width: 768px) {
.layout {
/* 改成单列布局 */
grid-template-columns: 1fr;
/* 移动端间距收窄 */
gap: 20px;
}
}

移动端优先也很常见:

.cards {
/* 默认先写移动端,一列 */
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
/* 屏幕变宽后,再增强为多列 */
@media (min-width: 768px) {
.cards {
grid-template-columns: repeat(3, 1fr);
}
}

响应式设计的核心不是“给所有设备单独写一套”,而是让布局可以自然伸缩。

图片很容易撑破容器,所以通常要写基础规则。

img {
/* 图片最大宽度不超过父容器 */
max-width: 100%;
/* 高度自动,避免变形 */
height: auto;
/* 去掉图片底部因为行内元素产生的空隙 */
display: block;
}

如果需要固定比例裁剪:

.cover {
width: 100%;
/* 固定宽高比 */
aspect-ratio: 16 / 9;
/* 图片填满容器,超出部分裁剪 */
object-fit: cover;
border-radius: 8px;
}

object-fit: cover 适合封面图、头像、卡片图。

背景可以是颜色、图片、渐变。

.hero {
/* 背景色 */
background-color: #fff7ed;
/* 背景图 */
background-image: url("/assets/images/cover.jpg");
/* 图片居中 */
background-position: center;
/* 图片覆盖整个容器 */
background-size: cover;
/* 不重复平铺 */
background-repeat: no-repeat;
}

渐变背景:

.banner {
/* 135deg 表示渐变方向 */
background: linear-gradient(135deg, #f08a24, #e4572e);
}

渐变不要滥用。它适合强调区域,但大面积使用容易显得廉价。

边框、圆角、阴影常用于卡片和按钮。

.card {
padding: 20px;
/* 细边框 */
border: 1px solid #e5e7eb;
/* 圆角 */
border-radius: 8px;
/* 背景 */
background: white;
/* 阴影,注意不要太重 */
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
}

建议:

  • 内容卡片圆角不要过大。
  • 阴影要轻,不要像悬浮广告。
  • 边框和阴影通常二选一,或者都很克制。

hover 表示鼠标悬停状态。

.button {
padding: 10px 18px;
border: 0;
border-radius: 999px;
color: white;
background: #f08a24;
cursor: pointer;
/* 让变化更平滑 */
transition:
background 0.2s ease,
transform 0.2s ease;
}
.button:hover {
background: #d97706;
/* 轻微上移 */
transform: translateY(-1px);
}

交互动画要克制。按钮轻微反馈就够了,不需要每个元素都大幅移动。

CSS 变量可以减少重复,让主题维护更方便。

:root {
/* 品牌主色 */
--color-accent: #f08a24;
/* 正文颜色 */
--color-text: #1f2937;
/* 边框颜色 */
--color-border: #e5e7eb;
/* 常用圆角 */
--radius-sm: 6px;
--radius-md: 8px;
/* 页面最大宽度 */
--content-width: 960px;
}
.container {
max-width: var(--content-width);
margin: 0 auto;
padding: 0 16px;
}
.button {
border-radius: var(--radius-sm);
background: var(--color-accent);
}

变量适合放:

  • 颜色。
  • 字号。
  • 间距。
  • 圆角。
  • 阴影。
  • 页面宽度。

先写 HTML:

<main class="page">
<section class="hero">
<p class="hero-kicker">Frontend</p>
<h1>CSS 基础教程</h1>
<p class="hero-desc">用清晰的结构和克制的样式,构建稳定的页面。</p>
<a class="hero-link" href="#articles">开始阅读</a>
</section>
<section id="articles" class="article-grid" aria-label="文章列表">
<article class="article-card">
<span class="article-tag">HTML</span>
<h2>HTML 基础教程</h2>
<p>学习网页结构、语义化标签和基础 SEO。</p>
</article>
<article class="article-card">
<span class="article-tag">CSS</span>
<h2>CSS 基础教程</h2>
<p>学习选择器、盒模型、布局和响应式设计。</p>
</article>
<article class="article-card">
<span class="article-tag">JavaScript</span>
<h2>JavaScript 入门</h2>
<p>学习变量、函数、事件和 DOM 操作。</p>
</article>
</section>
</main>

再写 CSS:

/* 全局变量:集中管理站点基础样式 */
:root {
--color-bg: #ffffff;
--color-text: #1f2937;
--color-muted: #6b7280;
--color-border: #e5e7eb;
--color-accent: #f08a24;
--color-accent-soft: #fff7ed;
--radius: 8px;
--content-width: 960px;
}
/* 让 width 更符合直觉 */
* {
box-sizing: border-box;
}
body {
margin: 0;
color: var(--color-text);
background: var(--color-bg);
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
line-height: 1.7;
}
a {
color: inherit;
}
.page {
width: min(100% - 32px, var(--content-width));
margin: 0 auto;
padding: 64px 0;
}
.hero {
padding-bottom: 40px;
border-bottom: 1px solid var(--color-border);
}
.hero-kicker {
margin: 0 0 12px;
color: var(--color-accent);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.hero h1 {
margin: 0;
font-size: clamp(36px, 6vw, 64px);
line-height: 1.1;
}
.hero-desc {
max-width: 560px;
margin: 20px 0 0;
color: var(--color-muted);
font-size: 18px;
}
.hero-link {
display: inline-flex;
margin-top: 28px;
padding: 10px 18px;
border-radius: 999px;
color: white;
background: var(--color-accent);
font-weight: 700;
text-decoration: none;
transition:
background 0.2s ease,
transform 0.2s ease;
}
.hero-link:hover {
background: #d97706;
transform: translateY(-1px);
}
.article-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-top: 40px;
}
.article-card {
padding: 20px;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: white;
}
.article-tag {
color: var(--color-accent);
font-size: 12px;
font-weight: 700;
}
.article-card h2 {
margin: 10px 0 0;
font-size: 20px;
line-height: 1.35;
}
.article-card p {
margin: 10px 0 0;
color: var(--color-muted);
}
@media (max-width: 768px) {
.page {
padding: 40px 0;
}
.article-grid {
grid-template-columns: 1fr;
}
}

这个示例包含了:

  • CSS 变量。
  • 全局盒模型。
  • 页面容器。
  • 标题排版。
  • 按钮样式。
  • Grid 卡片布局。
  • 响应式媒体查询。

它不复杂,但已经覆盖了真实页面里最常见的 CSS 写法。

.container {
width: 1200px;
}

这样在小屏幕上容易溢出。

更好的写法:

.container {
width: min(100% - 32px, 1200px);
margin: 0 auto;
}
.card {
width: 300px;
padding: 24px;
border: 1px solid #ddd;
}

如果没有设置 box-sizing: border-box,最终宽度会超过 300px。

建议全局设置:

* {
box-sizing: border-box;
}
.button {
margin-left: 180px;
}

这种写法在屏幕变化时很容易崩。

更好的方式是用布局控制:

.actions {
display: flex;
justify-content: center;
gap: 12px;
}
.page .content .article .header .title span {
color: orange;
}

选择器越长,越难覆盖,也越依赖 HTML 结构。

更好的方式是给关键元素一个清晰类名:

.article-title {
color: orange;
}

学习 CSS 时,建议按下面顺序推进:

  1. 先掌握选择器、继承、权重。
  2. 再理解盒模型、margin、padding。
  3. 接着学习 Flex 和 Grid。
  4. 然后学习响应式布局。
  5. 最后再看动画、主题、工程化。

不要一开始就追求复杂视觉。先把页面结构摆正、间距稳定、响应式不崩,已经超过很多随手写出来的页面。

CSS 的核心能力可以总结为三件事:

  • 选中元素。
  • 设置样式。
  • 控制布局。

入门阶段最应该掌握:

  • CSS 引入方式。
  • 常用选择器。
  • 权重和继承。
  • 颜色、字体、文本。
  • 盒模型。
  • Flex 和 Grid。
  • 响应式设计。
  • CSS 变量。

CSS 看起来细碎,但它不是玄学。只要从规则、空间、布局三个角度理解,样式就会越来越可控。