CSS 基础教程
CSS 是网页的视觉语言。HTML 负责描述页面结构,CSS 负责控制页面长什么样:颜色、字体、间距、边框、布局、响应式、动画,都离不开 CSS。
学习 CSS 时,不要只背属性。更重要的是理解三个问题:
- 这个样式会作用到哪些元素?
- 这个元素在页面里占多少空间?
- 这些元素之间如何排列?
理解了这三个问题,CSS 就会从“玄学调样式”变成一套可以推理的规则。
CSS 是什么
Section titled “CSS 是什么”CSS 全称是 Cascading Style Sheets,中文通常叫层叠样式表。
“层叠”是 CSS 的核心特点:同一个元素可能同时被多条规则影响,浏览器会根据选择器权重、规则顺序、继承关系来决定最终样式。
一个最简单的 CSS 规则如下:
/* 选择页面中所有 p 标签 */p { /* 设置文字颜色 */ color: #333;
/* 设置字体大小 */ font-size: 16px;
/* 设置行高,让正文更容易阅读 */ line-height: 1.7;}这段 CSS 的意思是:找到所有 <p> 元素,然后给它们设置颜色、字号和行高。
推荐文件结构
Section titled “推荐文件结构”刚开始学习 CSS,可以用下面这种结构:
文件夹css-demo/
- index.html
文件夹assets/
文件夹styles/
- reset.css
- style.css
文件夹images/
- cover.jpg
其中:
index.html放页面结构。reset.css放浏览器默认样式重置。style.css放自己的页面样式。images/放图片资源。
实际项目里文件会更多,但入门阶段先保持简单。
引入 CSS 的三种方式
Section titled “引入 CSS 的三种方式”最推荐的方式是使用外部 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 基本语法
Section titled “CSS 基本语法”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 titled “ID 选择器”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;}继承属性常见有:
colorfont-familyfont-sizeline-height
不继承的属性常见有:
marginpaddingborderwidthheight
理解继承后,你就不需要给每个元素重复写文字颜色和字体。
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
Section titled “margin 和 padding”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
Section titled “display”display 决定元素如何参与布局。
.block { /* 块级元素,默认占满一行 */ display: block;}
.inline { /* 行内元素,不会独占一行 */ display: inline;}
.inline-block { /* 行内排列,但可以设置宽高 */ display: inline-block;}
.hidden { /* 不显示,也不占空间 */ display: none;}常见默认行为:
div、p、h1默认是block。span、a、strong默认是inline。img比较特殊,表现类似行内替换元素。
Flex 布局
Section titled “Flex 布局”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 titled “Grid 布局”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 定位
Section titled “position 定位”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);}渐变不要滥用。它适合强调区域,但大面积使用容易显得廉价。
border、radius 和 shadow
Section titled “border、radius 和 shadow”边框、圆角、阴影常用于卡片和按钮。
.card { padding: 20px;
/* 细边框 */ border: 1px solid #e5e7eb;
/* 圆角 */ border-radius: 8px;
/* 背景 */ background: white;
/* 阴影,注意不要太重 */ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);}建议:
- 内容卡片圆角不要过大。
- 阴影要轻,不要像悬浮广告。
- 边框和阴影通常二选一,或者都很克制。
hover 和 transition
Section titled “hover 和 transition”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 变量
Section titled “CSS 变量”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);}变量适合放:
- 颜色。
- 字号。
- 间距。
- 圆角。
- 阴影。
- 页面宽度。
一个完整页面示例
Section titled “一个完整页面示例”先写 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 写法。
到处写固定宽度
Section titled “到处写固定宽度”.container { width: 1200px;}这样在小屏幕上容易溢出。
更好的写法:
.container { width: min(100% - 32px, 1200px); margin: 0 auto;}不理解盒模型
Section titled “不理解盒模型”.card { width: 300px; padding: 24px; border: 1px solid #ddd;}如果没有设置 box-sizing: border-box,最终宽度会超过 300px。
建议全局设置:
* { box-sizing: border-box;}用 margin 硬凑布局
Section titled “用 margin 硬凑布局”.button { margin-left: 180px;}这种写法在屏幕变化时很容易崩。
更好的方式是用布局控制:
.actions { display: flex; justify-content: center; gap: 12px;}选择器写得太长
Section titled “选择器写得太长”.page .content .article .header .title span { color: orange;}选择器越长,越难覆盖,也越依赖 HTML 结构。
更好的方式是给关键元素一个清晰类名:
.article-title { color: orange;}学习 CSS 时,建议按下面顺序推进:
- 先掌握选择器、继承、权重。
- 再理解盒模型、margin、padding。
- 接着学习 Flex 和 Grid。
- 然后学习响应式布局。
- 最后再看动画、主题、工程化。
不要一开始就追求复杂视觉。先把页面结构摆正、间距稳定、响应式不崩,已经超过很多随手写出来的页面。
CSS 的核心能力可以总结为三件事:
- 选中元素。
- 设置样式。
- 控制布局。
入门阶段最应该掌握:
- CSS 引入方式。
- 常用选择器。
- 权重和继承。
- 颜色、字体、文本。
- 盒模型。
- Flex 和 Grid。
- 响应式设计。
- CSS 变量。
CSS 看起来细碎,但它不是玄学。只要从规则、空间、布局三个角度理解,样式就会越来越可控。