欢迎来到 CSS3 的世界! 这份教程旨在帮助你彻底理解 CSS3 的方方面面,无论你是前端初学者还是希望系统提升 CSS 技能的开发者。我们将从最基础的概念开始,一步步深入到现代前端开发中不可或缺的高级布局和动画技术。准备好,让我们一起探索如何让网页变得生动、美观、响应式!
在深入 CSS3 之前,我们首先需要理解 CSS 在网页开发中的核心作用。简单来说,CSS (Cascading Style Sheets,层叠样式表) 是一种用于描述 HTML 或 XML(包括 SVG、MathML 等)文档样式的语言。它定义了如何显示 HTML 元素,例如字体、颜色、间距、布局等。
想象一下,HTML 是网页的骨架和内容,它负责定义网页的结构(比如哪里是标题,哪里是段落,哪里是图片)。而 CSS 就像网页的“衣服”和“化妆品”,它负责让这些骨架和内容变得美观、有吸引力。
<h1>,段落用 <p>,图片用 <img>。
CSS 并非一蹴而就,它也经历了漫长的发展:
CSS 的语法非常直观和简单。一个基本的 CSS 规则由两部分组成:选择器 (Selector) 和 声明块 (Declaration Block)。
h1 { /* h1 是选择器,{} 内是声明块 */
color: blue; /* color 是属性,blue 是值,这是一个声明 */
font-size: 24px; /* font-size 是属性,24px 是值,这是另一个声明 */
}
.my-button {
background-color: #4CAF50; /* 背景色 */
color: white; /* 文字颜色 */
padding: 10px 20px; /* 内边距 */
border: none; /* 无边框 */
border-radius: 5px; /* CSS3 圆角! */
}
h1),类名(.my-button),ID 名(#header)等等。{} 包裹。它包含了这个选择器所有要应用的样式声明。: 分隔,并以分号 ; 结束。color (颜色), font-size (字体大小), background-color (背景颜色)。blue, 24px, #4CAF50。/* 开始,以 */ 结束。它们不会被浏览器解析,用于解释代码或暂时禁用样式。
/* 这是一个单行注释 */
/*
* 这是一个
* 多行注释
*/
.element {
color: red; /* 这也是一个注释 */
}
例如,以下是 margin 属性的缩写:
/* 完整写法 */
.box-full {
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 40px;
}
/* 缩写:上 右 下 左 */
.box-shorthand-1 {
margin: 10px 20px 30px 40px;
}
/* 缩写:上下 左右 */
.box-shorthand-2 {
margin: 10px 20px; /* margin-top: 10px; margin-bottom: 10px; margin-left: 20px; margin-right: 20px; */
}
/* 缩写:所有方向相同 */
.box-shorthand-3 {
margin: 15px; /* margin-top/right/bottom/left 都是 15px */
}
其他常见的缩写属性包括 padding, border, background, font, flex 等。掌握它们能显著提高你的编码效率。
-)来分隔单词,而不是驼峰命名法(CamelCase)。
例如:font-size, background-color, my-custom-class。这是一种普遍的约定,有助于代码的可读性。
有四种主要方式可以将 CSS 规则应用到 HTML 文档中。
直接将 CSS 规则写在 HTML 元素的 style 属性中。
<p style="color: blue; font-size: 16px;">这段文字是蓝色的,字体大小是 16px。</p>
在 HTML 文档的 <head> 区域使用 <style> 标签来定义 CSS 规则。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>内部样式表示例</title>
<style>
/* 这里是 CSS 代码 */
h1 {
color: green;
text-align: center;
}
p {
font-family: sans-serif;
line-height: 1.6;
}
</style>
</head>
<body>
<h1>欢迎学习 CSS!</h1>
<p>内部样式表适用于样式只作用于单个 HTML 页面,且不想创建独立 CSS 文件的情况。</p>
</body>
</html>
将 CSS 规则写在一个独立的 .css 文件中,然后在 HTML 文档中使用 <link> 标签将其引入。这是最常用也是最推荐的方式。
styles.css 文件内容:
/* styles.css */
body {
background-color: #f0f8ff;
font-family: Arial, sans-serif;
}
h1 {
color: #8a2be2; /* 蓝紫色 */
}
.highlight {
background-color: yellow;
font-weight: bold;
}
index.html 文件内容:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>外部样式表示例</title>
<link rel="stylesheet" href="styles.css"> <!-- 引入外部 CSS 文件 -->
</head>
<body>
<h1>通过外部样式表美化页面</h1>
<p class="highlight">这是被高亮显示的段落。</p>
<p>外部样式表是大型项目和多页面网站的最佳选择。</p>
</body>
</html>
.css 文件可以被多个 HTML 页面引用,实现样式的一致性。@import 规则
@import 规则允许在一个 CSS 文件中导入另一个 CSS 文件。它可以在 <style> 标签内部或另一个 .css 文件的顶部使用。
base.css 文件:
/* base.css */
body {
margin: 0;
padding: 0;
}
main.css 文件:
/* main.css */
@import url("base.css"); /* 导入 base.css */
h1 {
font-family: 'Segoe UI', sans-serif;
color: #333;
}
index.html 文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>@import 示例</title>
<link rel="stylesheet" href="main.css"> <!-- 只引入 main.css -->
</head>
<body>
<h1>使用 @import 导入样式</h1>
</body>
</html>
@import 通常放在 CSS 文件的顶部。@import 可能会导致浏览器并行加载问题,通常不如 <link> 标签直接引用所有 CSS 文件效率高。在现代前端开发中,更推荐使用 <link> 标签引入所有主要的 CSS 文件,或者在构建工具(如Webpack)中使用 @import 或 ES Modules 语法进行 CSS 模块化导入。选择器是 CSS 的核心,它决定了你的样式会作用于哪些 HTML 元素。掌握选择器是高效编写 CSS 的第一步。
p { color: blue; } /* 所有 <p> 标签的文字变为蓝色 */
class 属性值选择元素。一个元素可以有多个类,一个类可以被多个元素使用。
.important { font-weight: bold; } /* 所有 class="important" 的元素加粗 */
<p class="important">重要段落</p>
id 属性值选择元素。一个 ID 在一个 HTML 文档中必须是唯一的。
#header { background-color: lightblue; } /* id="header" 的元素背景色为浅蓝 */
<div id="header">页面头部</div>
* { margin: 0; padding: 0; } /* 清除所有元素的默认外边距和内边距 */
, 分隔,表示为多个选择器应用相同的样式。
h1, h2, p { text-align: center; } /* h1, h2 和 p 标签都居中显示 */
分隔,表示选择某个元素的后代元素(可以是子元素、孙子元素等)。
div p { color: green; } /* 选择所有位于 <div> 内部的 <p> 标签 */
<div><p>内部段落</p><span><p>孙子段落</p></span></div>
> 分隔,表示选择某个元素的直接子元素。
div > p { border: 1px solid red; } /* 只选择直接位于 <div> 内部的 <p> 标签 */
<div><p>直接子段落</p><span><p>非直接子段落</p></span></div>
+ 分隔,表示选择紧接在第一个元素后的同级元素。
h1 + p { margin-top: 50px; } /* 选择紧接在 <h1> 后面的第一个 <p> 标签 */
<h1>标题</h1><p>第一个段落</p><p>第二个段落</p>
~ 分隔,表示选择位于第一个元素之后的所有同级元素。
h1 ~ p { background-color: #eee; } /* 选择 <h1> 后面的所有 <p> 标签 */
<h1>标题</h1><p>段落1</p><div>其他内容</div><p>段落2</p>
根据 HTML 元素的属性及其值来选择元素。在 CSS3 中,属性选择器得到了极大的增强。
[attr]:选择所有带有指定属性的元素。
a[title] { color: orange; } /* 所有带 title 属性的 <a> 标签 */
[attr=value]:选择属性值为指定值的元素。
input[type="text"] { border: 1px solid gray; } /* 所有 type="text" 的 <input> 标签 */
[attr~=value]:选择属性值中包含指定单词的元素,单词之间用空格分隔。
p[class~="highlight"] { background-color: yellow; } /* class 属性值包含 'highlight' 单词的 <p> */
<p class="large highlight">...</p>
[attr|=value]:选择属性值以指定值开头且后面跟着连字符 - 的元素(常用于语言属性)。
div[lang|="en"] { border: 2px solid blue; } /* lang="en", lang="en-us" 等 */
[attr^=value] (CSS3):选择属性值以指定值开头的元素。
a[href^="https"] { color: purple; } /* 所有 href 以 "https" 开头的 <a> */
[attr$=value] (CSS3):选择属性值以指定值结尾的元素。
img[src$=".png"] { border: 2px solid green; } /* 所有 src 以 ".png" 结尾的 <img> */
[attr*=value] (CSS3):选择属性值中包含指定子字符串的元素。
input[name*="user"] { background-color: lightgray; } /* 所有 name 包含 "user" 的 <input> */
伪类用于选择处于特定状态的元素,或者根据元素的在文档树中的位置来选择它们。它们以一个冒号 : 开头。
:link:未访问的链接。:visited:已访问的链接。:hover:鼠标指针悬停在元素上时。:active:元素被激活时(例如鼠标点击瞬间)。
a:link { color: blue; }
a:visited { color: purple; }
a:hover { text-decoration: underline; }
a:active { color: red; }
根据元素在父元素中的位置选择。非常强大,用于处理列表、表格等结构化内容。
:first-child:选择父元素的第一个子元素。:last-child:选择父元素的最后一个子元素。:nth-child(n):选择父元素的第 n 个子元素(n 可以是数字、关键字或公式)。
:nth-child(2):第二个子元素。:nth-child(odd) / :nth-child(2n+1):奇数行。:nth-child(even) / :nth-child(2n):偶数行。:nth-child(3n):每3个元素中的第3个。:nth-last-child(n):选择父元素的倒数第 n 个子元素。:first-of-type:选择父元素中第一个指定类型的子元素。:last-of-type:选择父元素中最后一个指定类型的子元素。:nth-of-type(n):选择父元素中第 n 个指定类型的子元素。:nth-last-of-type(n):选择父元素中倒数第 n 个指定类型的子元素。:only-child:如果元素是其父元素的唯一子元素。:only-of-type:如果元素是其父元素中指定类型的唯一子元素。:empty:选择没有子元素(包括文本节点)的元素。:root:选择文档的根元素(通常是 <html>)。
<ul>
<li>列表项 1</li>
<li>列表项 2</li>
<li>列表项 3</li>
<li>列表项 4</li>
</ul>
<div>
<p>段落 A</p>
<span>span B</span>
<p>段落 C</p>
</div>
li:first-child { color: red; } /* 列表项 1 变红 */
li:nth-child(even) { background-color: #f0f0f0; } /* 列表项 2, 4 等偶数行有背景色 */
p:first-of-type { font-weight: bold; } /* 段落 A 加粗 (div中的第一个p) */
:focus:元素获得焦点时(如输入框被点击)。:enabled:可用的表单元素。:disabled:被禁用的表单元素。:checked:被选中的复选框或单选按钮。:valid:内容合法的表单输入框(基于 HTML5 验证)。:invalid:内容非法的表单输入框。:required:带有 required 属性的表单输入框。:optional:不带 required 属性的表单输入框。:read-only:只读的表单输入框。:read-write:可写的表单输入框。:not(selector):选择不匹配给定选择器的元素。
div:not(.header) { border: 1px solid blue; } /* 除了 class="header" 的 div 之外的所有 div */
:target:当 URL 中的片段标识符(#id)与某个元素的 ID 匹配时。
<a href="#section2">跳转到第二节</a>
<section id="section2">...</section>
section:target { background-color: lightyellow; } /* 当 URL 是 #section2 时,该 section 背景色变黄 */
伪元素用于样式化元素的一部分,或者在元素内容的前后插入内容。它们以两个冒号 :: 开头(CSS3 推荐,CSS2 为一个冒号)。
::before:在元素内容之前插入生成的内容。常与 content 属性一起使用。::after:在元素内容之后插入生成的内容。常与 content 属性一起使用。
<p class="quote">CSS 是一门艺术。</p>
.quote::before {
content: "“";
font-size: 2em;
color: #ccc;
vertical-align: middle;
}
.quote::after {
content: "”";
font-size: 2em;
color: #ccc;
vertical-align: middle;
}
::first-letter:选择文本的第一个字母。::first-line:选择文本的第一行。::selection:选择用户高亮(选中)的文本。
p::selection {
background-color: #ffcc00;
color: #333;
}
::placeholder (CSS3):选择表单输入框的占位文本。
input::placeholder {
color: #999;
font-style: italic;
}
当多个 CSS 规则作用于同一个元素时,浏览器需要决定哪个规则的样式会生效。这个决定过程就是基于优先级 (Specificity)。
优先级是一个四位数的表示法:(a, b, c, d)
a (内联样式):如果样式是内联定义的(在 HTML 元素的 style 属性中),则 a=1,否则 a=0。b (ID 选择器):统计 ID 选择器(#id)的数量。c (类选择器、属性选择器、伪类):统计类选择器(.class)、属性选择器([attr])和伪类(:hover, :nth-child)的数量。d (元素选择器、伪元素):统计元素选择器(p, div)和伪元素(::before, ::after)的数量。!important:这是最高优先级。任何声明只要加了 !important 关键字,就会覆盖掉所有其他优先级低的规则。但应谨慎使用,因为它会打破正常的层叠规则,增加维护难度。
p { color: red !important; }
(1,0,0,0)。(0,1,0,0)。(0,0,1,0)。(0,0,0,1)。*)、继承的样式:优先级为 (0,0,0,0),最低。
/* 1. p { color: red; } */ /* 权重: (0,0,0,1) */
/* 2. .text { color: green; } */ /* 权重: (0,0,1,0) */
/* 3. #my-id { color: blue; } */ /* 权重: (0,1,0,0) */
/* 4. div p { color: purple; } */ /* 权重: (0,0,0,2) */
/* 5. p.text { color: orange; } */ /* 权重: (0,0,1,1) */
/* 6. [class="text"] { color: teal; } */ /* 权重: (0,0,1,0) */
假设有一个 HTML 元素:<p id="my-id" class="text">Hello World</p>
规则1 (p) vs 规则2 (.text): .text 胜出 (0,0,1,0 > 0,0,0,1)
规则2 (.text) vs 规则3 (#my-id): #my-id 胜出 (0,1,0,0 > 0,0,1,0)
规则3 (#my-id) vs 规则5 (p.text): #my-id 胜出 (0,1,0,0 > 0,0,1,1)
最终 <p> 元素的颜色会是 blue (来自 #my-id)。
!important 规则会覆盖所有常规规则。color, font-family)。理解盒模型是理解 CSS 布局的基石。在 CSS 中,每个 HTML 元素都被视为一个矩形的盒子 (box)。这个盒子由四个部分组成:内容区 (Content)、内边距 (Padding)、边框 (Border) 和外边距 (Margin)。
width 和 height 属性控制。
padding 属性控制。
border 属性控制。
margin 属性控制。
CSS 盒模型有两种主要类型:W3C 标准盒模型 (通常称为标准盒模型) 和 IE 盒模型 (或称怪异盒模型)。
这是 W3C 标准推荐的模型。在这种模型下,元素的 width 和 height 属性只包含内容区 (Content) 的尺寸。内边距 (padding) 和边框 (border) 会被添加到 width 和 height 之外。
计算公式:
宽度 = width + padding-left + padding-right + border-left-width + border-right-width
高度 = height + padding-top + padding-bottom + border-top-width + border-bottom-width
.box-standard {
width: 100px;
height: 100px;
padding: 20px;
border: 5px solid black;
margin: 10px;
background-color: lightblue;
}
这个 .box-standard 元素的实际渲染尺寸将是:
在旧版本的 IE 浏览器(IE6 以下,以及在 Quirks 模式下的所有 IE 版本)中,盒模型的计算方式有所不同。在这种模型下,元素的 width 和 height 属性包含了内容区、内边距和边框的尺寸。也就是说,内边距和边框会“挤压”内容区的空间,而不是增加盒子总尺寸。
计算公式:
宽度 = width (包含 content + padding + border)
高度 = height (包含 content + padding + border)
.box-quirks {
width: 100px;
height: 100px;
padding: 20px;
border: 5px solid black;
margin: 10px;
background-color: lightcoral;
}
这个 .box-quirks 元素的实际渲染尺寸将是:
为了解决两种盒模型并存的问题,CSS3 引入了 box-sizing 属性,它允许我们强制浏览器使用哪种盒模型来计算元素的宽度和高度。
box-sizing: content-box; (默认值):遵循 W3C 标准盒模型。元素的 width 和 height 只包含内容区。
box-sizing: border-box;:遵循怪异盒模型。元素的 width 和 height 包含了内容区、内边距和边框。
box-sizing 设置为 border-box:
/* 推荐的全局 box-sizing 设置 */
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit; /* 继承 html 的 box-sizing */
}
这样设置后,无论你给元素设置多少 padding 和 border,它的总尺寸都会保持你设置的 width/height,极大地简化了布局计算。
外边距折叠是一个在垂直方向上才会发生的现象,即当两个或更多垂直相邻的外边距相遇时,它们会合并成一个外边距。合并后的外边距的高度等于其中最大的那个外边距的高度。
发生场景:
margin-bottom 与第二个元素的 margin-top 相遇。
<p style="margin-bottom: 20px;">段落 1</p>
<p style="margin-top: 30px;">段落 2</p>
两个段落之间的实际间距将是 30px(取大值),而不是 20px + 30px = 50px。
margin-top 会与第一个子元素的 margin-top 折叠。margin-bottom 会与最后一个子元素的 margin-bottom 折叠。
<div style="margin-top: 50px;">
<p style="margin-top: 30px;">内部段落</p>
</div>
<div> 上方与父元素或其他兄弟元素之间的间距将是 50px,而不是 50px + 30px。
margin-top 和 margin-bottom,它们会折叠。
<p>上一段</p>
<div style="margin-top: 20px; margin-bottom: 30px;"></div>
<p>下一段</p>
空 <div> 将会被完全“吞噬”,它的 margin-top 和 margin-bottom 会和相邻的 <p> 标签的 margin-bottom 和 margin-top 折叠。
border 或 padding。overflow: hidden;。float)、绝对定位 (position: absolute)、或者使用 display: inline-block / flex / grid。<hr> 或其他非空元素。这部分我们将详细介绍一些最常用且对网页美观至关重要的 CSS 属性。
color:设置文本颜色。
p { color: #333; } /* 十六进制颜色 */
h1 { color: rgb(255, 0, 0); } /* RGB 颜色 */
a { color: hsl(240, 100%, 50%); } /* HSL 颜色 (CSS3) */
.alpha { color: rgba(0, 0, 0, 0.5); } /* 带透明度的 RGB (CSS3) */
.system-color { color: lightblue; } /* 命名颜色 */
font-size:设置字体大小。
p { font-size: 16px; }
h2 { font-size: 2em; } /* 相对于父元素字体大小 */
.large-text { font-size: 1.2rem; } /* 相对于根元素 (html) 字体大小 (CSS3) */
.responsive-text { font-size: 2vw; } /* 相对于视口宽度 (CSS3) */
font-family:设置字体家族。可以指定多个字体作为备用。
body { font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; }
sans-serif 是无衬线字体,serif 是衬线字体,它们是通用字体家族,作为所有自定义字体的最终备用方案。
font-weight:设置字体粗细。值可以是 normal (400), bold (700),或者 100 到 900 的数字值(步长为 100)。
strong { font-weight: bold; }
.thin-text { font-weight: 300; }
line-height:设置行高。可以是数字(倍数),长度单位或百分比。
p { line-height: 1.8; } /* 1.8倍于字体大小 */
h1 { line-height: 1.2em; }
text-align:设置文本水平对齐方式。left, right, center, justify (两端对齐)。
.center-text { text-align: center; }
text-decoration:设置文本装饰线。none, underline (下划线), overline (上划线), line-through (删除线)。
a { text-decoration: none; } /* 清除链接下划线 */
letter-spacing:设置字符间距。word-spacing:设置单词间距。text-indent:设置首行文本缩进。white-space:处理元素内的空白符。
normal:默认,合并空白符。nowrap:不换行,文本都在一行显示。pre:保留空白符,只在 <br> 处换行(类似 <pre> 标签)。pre-wrap:保留空白符,并在需要时换行。pre-line:合并空白符,但在换行符处换行。text-overflow (CSS3):如何显示溢出容器的文本。常与 white-space: nowrap; 和 overflow: hidden; 组合使用。
.single-line-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /* 溢出部分显示省略号 (...) */
}
word-break (CSS3):控制单词如何断行。break-all (任意字符处断行), keep-all (不拆分单词)。writing-mode (CSS3):设置文本的书写方向。horizontal-tb (水平,从左到右), vertical-rl (垂直,从右到左)。background 是一个缩写属性,可以设置以下所有属性:
background-color:背景颜色。background-image:背景图片。
.bg-image { background-image: url('images/bg.png'); }
background-repeat:背景图片重复方式。repeat (平铺), no-repeat (不重复), repeat-x (水平重复), repeat-y (垂直重复)。background-position:背景图片位置。可以是关键字 (center, top left), 像素值 (10px 20px), 百分比 (50% 50%)。background-size (CSS3):背景图片尺寸。
auto:默认,保持原始尺寸。cover:覆盖整个背景区域,可能会裁剪图片。contain:完整显示图片,可能会有空白区域。100px 50px (宽 高), 50% (相对于元素)。.hero-section {
background-image: url('hero.jpg');
background-size: cover; /* 保证图片覆盖整个区域 */
background-position: center center; /* 图片居中 */
background-repeat: no-repeat;
}
background-origin (CSS3):背景图片的定位区域。padding-box (从 padding box 左上角开始), border-box (从 border box 左上角开始), content-box (从 content box 左上角开始)。background-clip (CSS3):背景的绘制区域。border-box, padding-box, content-box, text (将背景裁剪为文本形状)。background-attachment:背景图片是否随页面滚动。scroll (默认,滚动), fixed (固定), local (随内容滚动)。
.multi-bg {
background-image: url('logo.png'), url('pattern.gif');
background-position: top left, bottom right;
background-repeat: no-repeat, repeat;
background-size: 50px, auto;
}
注意顺序: 第一个图片在最上层,最后一个在最下层。
border 是一个缩写属性,可以设置边框的宽度、样式和颜色。
border-width:边框宽度。thin, medium, thick 或具体数值 (1px, 2em)。border-style:边框样式。none, solid (实线), dashed (虚线), dotted (点线), double (双线) 等。border-color:边框颜色。border-radius (CSS3):圆角边框。用于创建圆角矩形。可以设置一个值(所有角相同)或四个值(左上、右上、右下、左下)。
.round-corners { border-radius: 8px; } /* 所有角半径 8px */
.pill-shape { border-radius: 999px; } /* 创建椭圆形或胶囊形 */
.custom-radius { border-radius: 10px 20px 30px 40px; } /* 四个角不同 */
.circle {
width: 100px;
height: 100px;
border-radius: 50%; /* 创建圆形,要求宽高相等 */
}
box-shadow (CSS3):盒子阴影。
.shadow-box {
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3); /* 水平偏移 垂直偏移 模糊半径 颜色 */
}
.inner-shadow {
box-shadow: inset 0 0 10px red; /* 内阴影 */
}
.multiple-shadows {
box-shadow: 5px 5px 10px rgba(0,0,0,0.5),
-5px -5px 10px rgba(255,255,255,0.5); /* 多个阴影,逗号分隔 */
}
border-image (CSS3):边框图像。允许使用图像来装饰元素的边框。它是一个强大的缩写属性,包括 border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat。
.image-border {
border: 15px solid transparent; /* 边框宽度必须够大 */
border-image: url('border.png') 30 round; /* 图片路径,切片值,重复方式 */
}
list-style-type (列表项标记类型), list-style-image (列表项标记图片), list-style-position (标记位置), list-style (缩写)。border-collapse (单元格边框合并), border-spacing (单元格边框间距), table-layout (表格布局算法)。outline (元素获得焦点时的轮廓,不占用空间,不触发回流)。
button:focus { outline: none; } /* 常见用于去除按钮默认焦点轮廓 */
opacity (0.0-1.0,完全透明到完全不透明)。会影响整个元素及其所有子元素。
.transparent-box { opacity: 0.7; }
visibility (visible, hidden, collapse)。hidden 隐藏元素但仍占用空间。overflow (visible, hidden, scroll, auto)。控制元素内容溢出容器时的处理方式。
.scroll-area {
width: 200px;
height: 150px;
overflow: auto; /* 内容超出时自动显示滚动条 */
}
cursor (pointer, default, text, wait 等)。
.clickable { cursor: pointer; }
布局是 CSS 的重中之重。在 CSS3 的 Flexbox 和 Grid 出现之前,我们主要依赖以下几种方式进行布局。
每个 HTML 元素都有一个默认的 display 属性值,它决定了元素在页面上的表现形式。
width, height, margin-top/bottom, padding-top/bottom。<div>, <p>, <h1>-<h6>, <ul>, <li>, <header>, <footer>, <section> 等。width, height。margin-top/bottom 和 padding-top/bottom 无效(或显示不正常)。<span>, <a>, <img>, <strong>, <em>, <input>, <label> 等。width, height, margin, padding。<img>, <input>, <button>, <select> (这些元素默认就是 inline-block,或者表现得像 inline-block)。display 属性是控制元素布局行为的关键。你可以通过它来改变元素的默认显示类型。
display: block;:将元素变为块级元素。display: inline;:将元素变为行内元素。display: inline-block;:将元素变为行内块级元素。display: none;:隐藏元素,并且不占用空间。与 visibility: hidden; 不同,后者隐藏元素但仍占用空间。display: flex; (CSS3):将元素设置为 Flex 容器,启用 Flexbox 布局。display: grid; (CSS3):将元素设置为 Grid 容器,启用 Grid 布局。
/* 将 span 变为块级元素,可以设置宽高 */
span.block-span {
display: block;
width: 100px;
height: 50px;
background-color: lightgray;
}
/* 将 div 变为行内块级元素,可以并排显示并设置宽高 */
div.inline-block-div {
display: inline-block;
width: 120px;
height: 80px;
margin: 5px;
background-color: lightgoldenrodyellow;
}
浮动 (float) 属性曾是实现多列布局和文本环绕图片的主要方式,但在 Flexbox 和 Grid 出现后,其布局能力逐渐被取代,更多用于简单的文本环绕图片效果。
float:
left:元素向左浮动。right:元素向右浮动。none:默认,不浮动。clear:
用于清除浮动的影响,使元素不会浮动到前一个浮动元素的旁边。
left:清除左浮动(元素下方不能有左浮动元素)。right:清除右浮动(元素下方不能有右浮动元素)。both:清除左右浮动。none:默认,不清除。
<style>
.container-float { border: 1px solid blue; padding: 10px; }
.box-float {
width: 100px;
height: 100px;
background-color: coral;
margin: 10px;
float: left; /* 浮动 */
}
.text-after-float {
background-color: lightgreen;
/* clear: both; */ /* 尝试取消注释看看效果 */
}
.clearfix::after { /* 清除浮动常用技巧 */
content: "";
display: block;
clear: both;
}
</style>
<div class="container-float clearfix">
<div class="box-float">Box 1</div>
<div class="box-float">Box 2</div>
<p class="text-after-float">这段文本紧跟在浮动元素之后。</p>
</div>
<div style="clear: both;"></div>。简单但增加了无语义 HTML。overflow: hidden; / auto; 法: 为浮动元素的父元素添加 overflow: hidden; 或 overflow: auto;。优点是代码简洁,但可能会隐藏溢出内容。::after 伪元素。这是目前最常用和推荐的方式。
.clearfix::after {
content: ""; /* 伪元素必须有内容 */
display: block; /* 伪元素变为块级元素 */
clear: both; /* 清除左右浮动 */
visibility: hidden; /* 隐藏伪元素但保留其影响 */
height: 0; /* 确保不占用高度 */
}
定位属性允许你精确控制元素在页面上的位置。
position: static; (默认值):
元素在正常文档流中,top, bottom, left, right 属性和 z-index 无效。
position: relative; (相对定位):
top, bottom, left, right 属性进行偏移。这些偏移是相对于元素自身原来的位置。
.relative-box {
position: relative;
top: 20px;
left: 30px;
background-color: lightblue;
width: 100px;
height: 100px;
}
这个盒子会向下偏移 20px,向右偏移 30px,但它在文档流中的位置仍保留,仿佛它还在原来的地方。
position: absolute; (绝对定位):
position 为 relative, absolute, fixed, sticky 的祖先元素) 进行定位。<body> 或 <html>) 进行定位。top, bottom, left, right 精确控制位置。
<style>
.parent {
position: relative; /* 提供定位上下文 */
width: 300px;
height: 200px;
border: 2px solid purple;
margin: 50px;
}
.child-absolute {
position: absolute;
top: 20px;
left: 20px;
background-color: yellow;
padding: 10px;
}
</style>
<div class="parent">
<div class="child-absolute">我被绝对定位在父元素内</div>
</div>
position: fixed; (固定定位):
.fixed-nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #333;
color: white;
padding: 10px 0;
text-align: center;
}
position: sticky; (粘性定位 - CSS3):
top, bottom, left, right 中的至少一个属性配合使用。
.sticky-header {
position: sticky;
top: 0; /* 当滚动到距离顶部 0px 时,元素开始固定 */
background-color: #f0f0f0;
padding: 10px;
border-bottom: 1px solid #ccc;
z-index: 100; /* 确保在其他内容之上 */
}
当定位元素(非 static)在页面上重叠时,z-index 属性决定了它们的堆叠顺序。拥有更高 z-index 值的元素会显示在拥有较低 z-index 值的元素之上。
z-index 只能应用于已定位的元素 (position 属性值不是 static 的元素)。z-index 默认值为 auto。z-index 的工作机制与层叠上下文密切相关。当一个元素创建了一个新的层叠上下文时,它的所有子元素的 z-index 只会在这个新的层叠上下文内部进行比较。常见的创建层叠上下文的属性包括:
<html>。position 值为 absolute 或 relative 且 z-index 不为 auto 的元素。position: fixed 或 sticky 的元素。opacity 小于 1 的元素。transform, filter, perspective, clip-path 等 CSS3 属性非默认值。flex 容器和 grid 容器的子项(当它们不是 flex/grid 项目时)。理解层叠上下文有助于解决元素重叠时 z-index 不生效的问题。
z-index 示例:
<style>
.box-z {
width: 100px;
height: 100px;
position: absolute;
}
.box-z.red {
background-color: red;
left: 50px; top: 50px;
z-index: 1; /* 在蓝色盒子之下 */
}
.box-z.blue {
background-color: blue;
left: 80px; top: 80px;
z-index: 2; /* 在红色盒子之上 */
}
</style>
<div style="position: relative; width: 200px; height: 200px; border: 1px solid #ccc;">
<div class="box-z red"></div>
<div class="box-z blue"></div>
</div>
蓝色盒子会覆盖在红色盒子之上,因为它有更高的 z-index。
CSS3 带来了大量的模块化新特性,极大地增强了网页的视觉表现力和交互性。这部分我们将逐一深入学习这些令人兴奋的特性。
border-radius:圆角边框border-radius 属性允许你为元素添加圆角。这在 CSS3 之前需要使用图片或复杂的布局技巧才能实现。
.box { border-radius: 10px; } /* 四个角都是 10px 的圆角 */
.box { border-radius: 10px 20px; }
.box { border-radius: 10px 20px 30px; }
.box { border-radius: 10px 20px 30px 40px; }
.circle {
width: 100px;
height: 100px;
border-radius: 50%; /* 宽高相等时,创建圆形 */
background-color: #f39c12;
}
.pill-button {
height: 40px;
border-radius: 20px; /* 或 999px,只要大于高度一半即可 */
background-color: #3498db;
color: white;
padding: 0 20px;
line-height: 40px;
display: inline-block;
}
border-radius: 水平半径 / 垂直半径;。
.ellipse-corners {
border-radius: 20px / 40px; /* 所有角都是水平半径20px,垂直半径40px的椭圆角 */
}
.complex-corners {
border-radius: 10px 20px 30px 40px / 50px 60px 70px 80px;
}
box-shadow:盒子阴影box-shadow 允许你为任何元素添加一个或多个阴影效果。其属性值顺序为:水平偏移 垂直偏移 模糊半径 扩散半径 颜色 内外阴影。
h-shadow (水平偏移):必填。正值向右,负值向左。v-shadow (垂直偏移):必填。正值向下,负值向上。blur-radius (模糊半径):可选。值越大,阴影越模糊。默认为 0 (无模糊)。spread-radius (扩散半径):可选。正值使阴影扩大,负值使阴影缩小。默认为 0。color (颜色):可选。默认为 currentColor。inset (内外阴影):可选。如果存在,阴影为内阴影 (inward shadow),否则为外阴影 (outward shadow)。box-shadow 示例:
.shadow-1 {
box-shadow: 5px 5px #888888; /* 简单阴影 */
}
.shadow-2 {
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.4); /* 带模糊的阴影 */
}
.shadow-3 {
box-shadow: 0px 0px 15px 5px rgba(0, 0, 0, 0.2) inset; /* 内阴影带扩散 */
}
.shadow-4 {
box-shadow: 2px 2px 5px rgba(0,0,0,0.3), /* 第一个阴影 */
-2px -2px 5px rgba(255,255,255,0.7); /* 第二个阴影(可用于模拟浮雕效果) */
}
border-image:边框图像border-image 属性允许你使用图像来绘制元素的边框,而不是简单的颜色或样式。它是一个复合属性,包括 border-image-source (图片来源), border-image-slice (图片切片), border-image-width (边框宽度), border-image-outset (边框外扩), border-image-repeat (图片重复方式)。
border-image 示例:
/* HTML 元素 */
.image-border-box {
width: 200px;
height: 100px;
border: 30px solid transparent; /* 边框宽度必须大于或等于 border-image-slice 的值 */
border-image-source: url('path/to/border-image.png'); /* 假设这张图片是一个边框纹理图 */
border-image-slice: 30; /* 图片从四边各向内切 30px,分出9个区域 */
border-image-repeat: round; /* 边角不变形,中间重复或拉伸 */
padding: 10px;
text-align: center;
background-color: #f0f0f0;
}
border-image-slice 理解:
它将源图像分成九个区域:四个角、四条边和中心区域。
fill 关键字,例如 border-image-slice: 30 fill;。
CSS3 对背景属性进行了多项增强,使得背景控制更加灵活和强大。
允许一个元素拥有多个背景图像,通过逗号 , 分隔。列表中的第一个图像在最上层,最后一个在最底层。
.multiple-backgrounds {
background-image: url('star.png'), url('gradient.png'); /* 星星在上面,渐变在下面 */
background-position: top left, center center;
background-repeat: no-repeat, repeat;
background-size: 50px, cover;
background-color: lightblue; /* 背景颜色在最底层 */
height: 200px;
border: 1px solid #ccc;
}
background-size:背景图片尺寸控制除了之前提到的 cover 和 contain,你还可以精确控制背景图片尺寸。
auto:默认值,保持图像原始尺寸。length:使用具体像素值或相对单位。
background-size: 100px 80px; /* 宽100px,高80px */
background-size: 50%; /* 宽度为元素宽度的50%,高度等比例缩放 */
background-size: 50% auto; /* 宽度为元素宽度的50%,高度自动等比例 */
background-origin 与 background-clip:背景区域控制这两个属性协同工作,用于控制背景图像的起始绘制位置和裁剪范围。
background-origin: 定义背景图片 position 属性的起始点。
padding-box (默认):背景图片从 padding box 的左上角开始定位。border-box:背景图片从 border box 的左上角开始定位。content-box:背景图片从 content box 的左上角开始定位。background-clip: 定义背景图像或背景颜色实际绘制的区域。
border-box (默认):背景延伸到边框外部边缘。padding-box:背景延伸到内边距外部边缘。content-box:背景只绘制在内容区域。text (实验性,需要前缀):背景被裁剪为文本的前景色。常用于文字图片效果。
.bg-clip-text {
background-image: linear-gradient(to right, #f32170, #ff6b08, #cf23cf, #eedd44);
-webkit-background-clip: text; /* 兼容性前缀 */
background-clip: text;
color: transparent; /* 将文字颜色设为透明,露出背景 */
font-size: 4em;
font-weight: bold;
text-align: center;
}
<h1 class="bg-clip-text">渐变文字</h1>
CSS3 带来了更多强大的文本样式控制,让文字表现力更强。
text-shadow:文本阴影与 box-shadow 类似,为文本添加阴影。属性值顺序为:水平偏移 垂直偏移 模糊半径 颜色。
.shadowed-text {
color: #fff;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); /* 黑色半透明阴影 */
}
.multi-shadow-text {
color: #e74c3c;
text-shadow: 1px 1px 0 #bdc3c7, /* 浅色边框效果 */
2px 2px 0 #95a5a6,
3px 3px 0 #7f8c8d; /* 多个阴影叠加实现3D效果 */
}
word-wrap / overflow-wrap:单词断行当单词过长,超出容器宽度时,控制单词如何断行。overflow-wrap 是 word-wrap 的新标准名称。
normal:只在允许的断点处(如空格)断行。break-word:在单词内部强行断行以防止溢出。
.break-text {
width: 100px;
border: 1px solid black;
word-wrap: break-word; /* 或 overflow-wrap: break-word; */
}
<div class="break-text">ThisIsAVeryLongWordWithoutAnySpacesThatNeedsToBreak.</div>
text-overflow: ellipsis:文本溢出显示省略号结合 white-space: nowrap; 和 overflow: hidden;,在文本超出容器时显示省略号。
.ellipsis-text {
width: 200px;
white-space: nowrap; /* 文本不换行 */
overflow: hidden; /* 溢出部分隐藏 */
text-overflow: ellipsis; /* 溢出部分显示省略号 */
border: 1px solid #ccc;
padding: 5px;
}
<div class="ellipsis-text">这是一段非常非常长的文本,它将超出容器并显示省略号。</div>
@font-face:自定义字体(Web Fonts)允许你在网页中嵌入自定义字体,即便用户的计算机上没有安装这些字体也能正确显示。
@font-face {
font-family: 'MyCustomFont'; /* 自定义字体名称 */
src: url('fonts/myfont.woff2') format('woff2'), /* 推荐 WOFF2 */
url('fonts/myfont.woff') format('woff'); /* WOFF 兼容性更广 */
font-weight: normal;
font-style: normal;
font-display: swap; /* 优化字体加载体验,先用系统字体,加载完再切换 */
}
body {
font-family: 'MyCustomFont', sans-serif; /* 先尝试自定义字体,失败则使用 sans-serif */
}
为了最佳兼容性和性能,通常会提供多种格式。
text-stroke:文本描边 (非标准/实验性,需前缀)虽然不是 W3C 标准属性,但 -webkit-text-stroke 在 Webkit 内核浏览器中广泛使用,用于实现文本描边效果。
.stroked-text {
color: white; /* 文本填充色 */
-webkit-text-stroke: 1px blue; /* 描边宽度 颜色 */
font-size: 3em;
font-weight: bold;
}
transform 属性允许你对元素进行平移、旋转、缩放、倾斜等操作。这是实现各种动画和视觉效果的基础。
可以应用一个或多个转换函数。多个函数之间用空格分隔。
translate(tx, ty):2D 平移。translateX(tx) / translateY(ty):单轴平移。translateZ(tz) / translate3d(tx, ty, tz):3D 平移 (需要父元素有 perspective)。.box { transform: translate(50px, 100px); } /* 向右平移50px,向下平移100px */
rotate(angle):2D 旋转 (顺时针)。rotateX(angle) / rotateY(angle) / rotateZ(angle):3D 旋转。rotate3d(x, y, z, angle):自定义轴的 3D 旋转。.box { transform: rotate(45deg); } /* 顺时针旋转45度 */
scale(sx, sy):2D 缩放。scaleX(sx) / scaleY(sy):单轴缩放。scaleZ(sz) / scale3d(sx, sy, sz):3D 缩放。.box { transform: scale(1.5, 0.8); } /* 宽度放大1.5倍,高度缩小0.8倍 */
skew(ax, ay):2D 倾斜。skewX(ax) / skewY(ay):单轴倾斜。.box { transform: skew(20deg, 10deg); } /* X轴倾斜20度,Y轴倾斜10度 */
这些是所有 2D/3D 变换的底层实现,通过矩阵乘法完成。通常用于更复杂的、自定义的变换,或由 JavaScript 动态计算。
矩阵乘法示例:一个点的坐标 $(x, y)$ 经过一个 2D 变换矩阵 $M$ 后的新坐标 $(x', y')$ 可以表示为:
$$
\begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix}
$$
其中,$M$ 就是 matrix(a, b, c, d, e, f) 函数的参数。
.box { transform: matrix(1, 0.5, -0.5, 1, 0, 0); } /* 这是一个复杂的变换 */
默认情况下,所有变换都围绕元素的中心点进行。transform-origin 属性允许你改变这个变换的原点。它可以是关键字 (top, left, center, right, bottom) 或长度/百分比值。
.box-rotate {
transform-origin: top left; /* 围绕左上角旋转 */
transform: rotate(45deg);
}
.box-scale {
transform-origin: 0 0; /* 围绕左上角缩放 */
transform: scale(2);
}
当在父元素上设置 transform-style: preserve-3d; 时,它的子元素将位于 3D 空间中,并且可以在 3D 空间中进行变换。如果没有这个属性,子元素的 3D 变换会扁平化 (flat) 到 2D 平面。
.container-3d {
perspective: 800px; /* 定义一个透视投影 */
transform-style: preserve-3d; /* 关键:子元素保持3D状态 */
}
.card {
width: 200px;
height: 300px;
transform: rotateY(45deg); /* 子元素在3D空间中旋转 */
transform-origin: center center;
}
perspective 属性用于为 3D 变换的元素定义透视效果,使其在 3D 空间中看起来有近大远小的感觉。它通常设置在 3D 变换元素的父元素上。
.stage {
perspective: 1000px; /* 在此元素及其子元素中创建 1000px 的透视深度 */
perspective-origin: center center; /* 透视原点 */
}
.cube {
transform: rotateY(45deg) rotateX(20deg);
}
在 3D 变换中,当元素旋转时,它会有一个正面和背面。backface-visibility 属性决定当元素的背面朝向用户时是否可见。
visible (默认):背面可见。hidden:背面不可见。常用于翻转卡片效果。
.card-flip-container {
perspective: 1000px;
width: 200px;
height: 300px;
}
.card-flip {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d; /* 允许子元素在3D空间中 */
transition: transform 0.6s;
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden; /* 关键:背面隐藏 */
}
.card-back {
transform: rotateY(180deg); /* 背面旋转180度,使其反面朝向我们 */
}
/* 当容器被hover时,卡片翻转 */
.card-flip-container:hover .card-flip {
transform: rotateY(180deg);
}
CSS 过渡允许你在元素属性改变时平滑地从一个状态变化到另一个状态,而不是立即发生。这使得动画效果无需 JavaScript 即可实现。
transition-property:指定应用过渡效果的 CSS 属性名称。
all (默认):所有可过渡的属性。none:没有属性会发生过渡。color, width, transform。transition-duration:过渡动画持续的时间。单位可以是秒 (s) 或毫秒 (ms)。
transition-duration: 0.5s; /* 动画持续 0.5 秒 */
transition-timing-function:指定过渡动画的速度曲线。
ease (默认):慢速开始,然后变快,然后慢速结束。linear:匀速。ease-in:慢速开始。ease-out:慢速结束。ease-in-out:慢速开始和结束。cubic-bezier(n, n, n, n):自定义贝塞尔曲线。steps(int, start|end):分步动画。transition-delay:过渡动画开始之前的延迟时间。transition (缩写):所有上述属性的缩写。
/* 完整写法 */
.button {
transition-property: background-color, transform;
transition-duration: 0.3s, 0.2s;
transition-timing-function: ease-out, linear;
transition-delay: 0s, 0.1s;
}
/* 缩写写法 (属性名 持续时间 动画曲线 延迟时间) */
.button-shorthand {
transition: background-color 0.3s ease-out, transform 0.2s linear 0.1s;
}
/* 针对所有属性 */
.button-all {
transition: all 0.5s ease; /* 所有可动画属性都将在0.5秒内平滑过渡 */
}
<style>
.btn {
background-color: #3498db;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease-out; /* 定义过渡 */
}
.btn:hover {
background-color: #2980b9; /* 鼠标悬停时改变背景色 */
transform: translateY(-3px); /* 向上轻微移动 */
}
.btn:active {
transform: translateY(0); /* 点击时回到原位 */
background-color: #1a5276;
}
</style>
<button class="btn">悬停并点击我</button>
CSS 动画比过渡更强大,它允许你定义一个复杂的动画序列,可以包含多个关键帧、循环播放、暂停等,而无需任何 JavaScript。
@keyframes 规则是 CSS 动画的核心,它定义了一个动画的名称和在不同时间点 (关键帧) 上元素应该呈现的样式。
0% 到 100%) 或关键字 (from 代表 0%,to 代表 100%)。
@keyframes slidein {
from {
transform: translateX(0%); /* 动画开始时 */
opacity: 0;
}
50% {
transform: translateX(50px); /* 动画进行到一半时 */
opacity: 0.5;
}
to {
transform: translateX(100%); /* 动画结束时 */
opacity: 1;
}
}
定义好 @keyframes 后,需要使用 animation 属性或其子属性将动画应用到元素上。
animation-name:动画名称 (与 @keyframes 后的名称对应)。animation-duration:动画持续时间。animation-timing-function:动画速度曲线 (与过渡的 transition-timing-function 相同)。animation-delay:动画开始前的延迟时间。animation-iteration-count:动画播放次数。可以是数字或 infinite (无限循环)。animation-direction:动画播放方向。
normal (默认):从 0% 到 100%。reverse:从 100% 到 0%。alternate:正向、反向交替播放。alternate-reverse:反向、正向交替播放。animation-fill-mode:动画停止时的状态。
none (默认):动画结束后回到原始状态。forwards:动画结束后停留在最后一帧的样式。backwards:动画开始前(延迟期间)就应用第一帧的样式。both:结合 forwards 和 backwards。animation-play-state:控制动画的播放/暂停。running (默认), paused。animation (缩写):所有上述属性的缩写。
/* 缩写写法: name duration timing-function delay iteration-count direction fill-mode play-state */
.animated-element {
animation: slidein 3s ease-in-out 1s infinite alternate both running;
}
<style>
.spinner {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite; /* 应用动画 */
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.fade-in {
opacity: 0;
animation: fadeInAnimation 2s ease-in forwards;
}
@keyframes fadeInAnimation {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
<div class="spinner"></div>
<p class="fade-in">这段文字会在页面加载后淡入显示。</p>
animation-play-state 属性来暂停/播放动画。
const mySpinner = document.querySelector('.spinner');
mySpinner.addEventListener('click', () => {
// 切换动画播放状态
const currentState = getComputedStyle(mySpinner).animationPlayState;
if (currentState === 'running') {
mySpinner.style.animationPlayState = 'paused';
} else {
mySpinner.style.animationPlayState = 'running';
}
});
Flexbox 是一种一维布局模式,它在行或列中排列项目。它使得容器中的项目可以自动伸缩、对齐、分配空间,极大地简化了复杂布局的实现。
当一个元素被设置为 display: flex; 或 display: inline-flex; 后,它就成为了 Flex 容器,其直接子元素成为 Flex 项目 (Flex Items)。所有 Flex 容器属性都作用于容器本身。
display: flex | inline-flex;:
flex:块级 Flex 容器。inline-flex:行内 Flex 容器。flex-direction:定义主轴的方向(以及 Flex 项目的排列方向)。
row (默认):水平方向,从左到右。row-reverse:水平方向,从右到左。column:垂直方向,从上到下。column-reverse:垂直方向,从下到上。flex-wrap:定义当一行/列无法容纳所有项目时,是否换行以及如何换行。
nowrap (默认):所有项目都在一行/列显示,可能会溢出。wrap:按主轴方向换行。wrap-reverse:按主轴方向反向换行。flex-flow:flex-direction 和 flex-wrap 的缩写。
flex-flow: row wrap; /* 等同于 flex-direction: row; flex-wrap: wrap; */
justify-content:定义 Flex 项目在主轴上的对齐方式。
flex-start (默认):向主轴起点对齐。flex-end:向主轴终点对齐。center:居中对齐。space-between:两端对齐,项目之间间距相等。space-around:每个项目两侧间距相等,所以项目之间间距是两侧间距的两倍。space-evenly:所有项目之间及项目与容器边缘之间间距相等。align-items:定义 Flex 项目在交叉轴上的对齐方式 (适用于单行或多行中的每一行)。
stretch (默认):项目被拉伸以适应容器,但仍会尊重 max-width/height。flex-start:向交叉轴起点对齐。flex-end:向交叉轴终点对齐。center:居中对齐。baseline:按项目内部文本的基线对齐。align-content:定义多行 Flex 容器中,各行在交叉轴上的对齐方式。只对多行 Flex 容器有效 (flex-wrap: wrap; 且有多行)。
stretch (默认):各行被拉伸以占据剩余空间。flex-start:所有行向交叉轴起点对齐。flex-end:所有行向交叉轴终点对齐。center:所有行居中对齐。space-between:各行两端对齐,行之间间距相等。space-around:各行两侧间距相等。space-evenly:所有行之间及行与容器边缘之间间距相等。这些属性应用于 Flex 容器的直接子元素。
order:定义项目的排列顺序。数值越小,排列越靠前。默认值为 0。
.item-1 { order: 2; }
.item-2 { order: 1; } /* item-2 会在 item-1 前面显示 */
flex-grow:定义项目的放大比例。当 Flex 容器有剩余空间时,项目会根据这个比例进行放大。默认值为 0 (不放大)。
.item-grow { flex-grow: 1; } /* 占据所有剩余空间 */
.item-grow-2 { flex-grow: 2; } /* 占据剩余空间的两倍 */
flex-shrink:定义项目的缩小比例。当 Flex 容器空间不足时,项目会根据这个比例进行缩小。默认值为 1 (会缩小)。
.item-no-shrink { flex-shrink: 0; } /* 不缩小 */
flex-basis:定义项目在分配多余空间之前,占据的主轴空间。默认值为 auto (基于内容或 width/height)。
.item-basis { flex-basis: 100px; } /* 项目初始尺寸为100px */
flex (缩写):flex-grow, flex-shrink, flex-basis 的缩写。
.item { flex: 1 1 0%; } /* 常见写法,等同于 grow:1, shrink:1, basis:0% */
.item-fill { flex: 1; } /* 等同于 flex: 1 1 0%; */
.item-fixed { flex: 0 0 200px; } /* 固定尺寸200px,不伸缩 */
align-self:允许单个 Flex 项目覆盖容器的 align-items 属性,在交叉轴上单独对齐。
.item-special { align-self: center; } /* 仅此项目在交叉轴上居中 */
<style>
.navbar {
display: flex; /* 开启 Flexbox */
justify-content: space-between; /* 左右两端对齐 */
align-items: center; /* 垂直居中 */
background-color: #333;
padding: 10px 20px;
color: white;
}
.navbar-brand {
font-size: 1.5em;
font-weight: bold;
}
.navbar-menu {
display: flex; /* 菜单项也 Flex 排列 */
list-style: none;
padding: 0;
margin: 0;
}
.navbar-menu li {
margin-left: 20px;
}
.navbar-menu a {
color: white;
text-decoration: none;
padding: 5px 10px;
transition: background-color 0.3s;
}
.navbar-menu a:hover {
background-color: #555;
border-radius: 4px;
}
</style>
<nav class="navbar">
<div class="navbar-brand">我的网站</div>
<ul class="navbar-menu">
<li><a href="#">首页</a></li>
<li><a href="#">关于我们</a></li>
<li><a href="#">服务</a></li>
<li><a href="#">联系</a></li>
</ul>
</nav>
CSS Grid Layout 是一种强大的二维布局系统,能够同时控制行和列的布局。它非常适合创建复杂的页面布局,例如整个页面的骨架。
当一个元素被设置为 display: grid; 或 display: inline-grid; 后,它就成为了 Grid 容器,其直接子元素成为 Grid 项目 (Grid Items)。所有 Grid 容器属性都作用于容器本身。
display: grid | inline-grid;:
grid:块级 Grid 容器。inline-grid:行内 Grid 容器。grid-template-columns / grid-template-rows:定义网格的列和行。
<length> / <percentage> / auto:指定固定大小。fr (fractional unit):弹性单位,表示可用空间的一小部分。
grid-template-columns: 100px 1fr 2fr; /* 第一列100px,第二列占1份剩余空间,第三列占2份 */
grid-template-rows: auto 50px; /* 第一行内容撑开,第二行50px高 */
repeat() 函数:重复定义列/行。
grid-template-columns: repeat(3, 1fr); /* 创建3个等宽的列 */
grid-template-rows: repeat(auto-fill, minmax(100px, auto)); /* 自动填充,每行最小100px高 */
minmax(min, max) 函数:定义轨道尺寸的最小值和最大值。grid-template-areas:通过名称定义网格区域。
.grid-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
grid-template-columns: 150px 1fr 1fr;
grid-template-rows: auto 1fr auto;
gap: 10px; /* 行列间距 */
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }
这个 Mermaid 图表示了网格区域的布局。实际在浏览器中,可以利用开发者工具的 Grid 检查器来直观查看网格线和区域。
grid-gap / gap:行与列的间距。
gap: 10px; /* 行间距和列间距都是10px */
row-gap: 20px; column-gap: 15px; /* 单独设置 */
justify-items, align-items, place-items:定义网格项目在各自网格单元格内的对齐方式。
justify-items:沿行轴(水平)对齐。align-items:沿列轴(垂直)对齐。place-items:align-items 和 justify-items 的缩写。start, end, center, stretch (默认)。justify-content, align-content, place-content:定义网格轨道在网格容器内的对齐方式。当网格总尺寸小于容器尺寸时生效。
justify-content:沿行轴(水平)对齐。align-content:沿列轴(垂直)对齐。place-content:align-content 和 justify-content 的缩写。start, end, center, space-between, space-around, space-evenly, stretch。grid-auto-columns, grid-auto-rows, grid-auto-flow:控制隐式网格 (Implicit Grid) 的行为。当项目放置在显式网格之外时,会自动创建隐式轨道。
grid-auto-flow: row dense; /* 尽可能紧密填充行 */
grid-auto-rows: minmax(50px, auto); /* 自动生成的行最小50px高 */
这些属性应用于 Grid 容器的直接子元素。
grid-column-start, grid-column-end, grid-row-start, grid-row-end:
定义项目在网格中的起始/结束位置,通过指定网格线号码或网格线名称。
.item-a {
grid-column-start: 1; /* 从第1条垂直网格线开始 */
grid-column-end: 3; /* 在第3条垂直网格线结束 (占据1、2列) */
grid-row-start: 1;
grid-row-end: 2;
}
grid-column, grid-row (缩写):
.item-b {
grid-column: 1 / span 2; /* 从第1列线开始,跨越2列 */
grid-row: 2 / 3; /* 从第2行线开始,到第3行线结束 (占据第2行) */
}
grid-area:
可以命名网格项目,然后直接将其放置在 grid-template-areas 定义的区域中,或者作为 grid-row-start / grid-column-start / grid-row-end / grid-column-end 的缩写。
.header-item { grid-area: header; } /* 放置在名为 'header' 的区域 */
.item-c { grid-area: 1 / 1 / 2 / 3; } /* 占据第1行、第1-2列 */
justify-self, align-self, place-self:
允许单个网格项目覆盖其父容器的 justify-items 或 align-items 属性,实现单独对齐。
.item-center { justify-self: center; align-self: end; }
<style>
.magazine-grid {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4列等宽 */
grid-template-rows: auto 200px 150px auto; /* 定义行高 */
gap: 15px; /* 行列间距 */
}
.grid-item {
background-color: #ecf0f1;
padding: 15px;
border-radius: 5px;
text-align: center;
}
/* 命名区域 */
.header { grid-area: 1 / 1 / 2 / 5; background-color: #3498db; color: white;} /* 跨越所有列 */
.feature-article { grid-area: 2 / 1 / 4 / 3; background-color: #27ae60; color: white;} /* 跨两行两列 */
.sidebar { grid-area: 2 / 3 / 3 / 5; background-color: #f1c40f;} /* 跨两列 */
.ad { grid-area: 3 / 3 / 4 / 5; background-color: #e67e22; color: white;}
.footer { grid-area: 4 / 1 / 5 / 5; background-color: #7f8c8d; color: white;}
</style>
<div class="magazine-grid">
<div class="grid-item header"><h2>杂志头部</h2></div>
<div class="grid-item feature-article"><h3>特色文章</h3><p>这篇特色文章占据了更大的空间,吸引读者眼球。</p></div>
<div class="grid-item sidebar"><h4>侧边栏新闻</h4><p>简短的新闻摘要。</p></div>
<div class="grid-item ad"><h4>广告位</h4><p>赞助内容。</p></div>
<div class="grid-item footer"><p>版权信息 © 2023</p></div>
</div>
多列布局允许你轻松地将内容划分为报纸或杂志式的多列,无需浮动或 Flexbox。
column-count:定义列数。
.multi-column-text { column-count: 3; } /* 分为3列 */
column-width:定义列的理想宽度。浏览器会根据容器宽度自动计算列数。
.multi-column-text { column-width: 200px; } /* 每列至少200px宽 */
columns (缩写):column-width 和 column-count 的缩写。
.multi-column-text { columns: 200px 3; } /* 3列,每列至少200px */
column-gap:列之间的间距。
column-gap: 30px;
column-rule:列之间的分隔线 (width style color)。
column-rule: 1px solid #ccc;
column-span:使元素跨越所有列。通常用于标题。
none (默认)all:元素跨越所有列。.full-width-heading { column-span: all; }
<style>
.article-columns {
columns: 2 250px; /* 至少两列,每列至少250px */
column-gap: 30px;
column-rule: 1px solid #eee;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}
.article-columns h3 {
column-span: all; /* 标题跨越所有列 */
text-align: center;
margin-bottom: 20px;
color: #34495e;
}
</style>
<div class="article-columns">
<h3>CSS3 多列布局的魅力</h3>
<p>CSS3 的多列布局模块提供了一种简单而强大的方式来创建类似报纸或杂志的文本布局。无需使用复杂的浮动或 JavaScript,您就可以将内容自动地分布到多个列中。这极大地简化了响应式设计中对文本内容的管理。</p>
<p>通过 `column-count` 属性,您可以指定希望内容分布到的列的数量。如果设置了 `column-width`,浏览器会根据容器的可用宽度自动计算列的数量,使其尽可能地符合指定的列宽。这两个属性可以单独使用,也可以通过 `columns` 缩写属性一起使用。</p>
<p>此外,您还可以使用 `column-gap` 来控制列之间的间距,以及 `column-rule` 来添加列之间的分隔线,进一步增强视觉效果。对于需要横跨所有列的标题或图片,`column-span: all;` 属性就显得非常有用。它允许您在多列布局中插入全宽内容,打破列的限制,使版面设计更加灵活多样。</p>
<p>尽管 Flexbox 和 Grid 已经成为主流的布局工具,多列布局在处理大量文本时仍有其独特的优势。例如,在一个博客文章或新闻报道中,如果希望文本在小屏幕上单列显示,在大屏幕上自动分为多列,那么多列布局无疑是最佳选择。它自动处理文本流,省去了手动计算和调整的麻烦。</p>
</div>
媒体查询允许你根据设备的特性(如屏幕宽度、高度、方向、分辨率等)来应用不同的 CSS 样式。它是实现响应式设计 (Responsive Web Design) 的核心技术。
基本语法:@media media_type and (media_feature) { /* CSS 规则 */ }
media_type (媒体类型):
all (默认):所有媒体类型。screen:计算机屏幕、平板电脑、智能手机等。print:打印机。speech:屏幕阅读器等。media_feature (媒体特性):
width / height:视口 (viewport) 的宽度/高度。min-width / max-width:最小/最大视口宽度 (最常用)。device-width / device-height:设备的物理屏幕宽度/高度。orientation:视口的朝向。portrait (肖像,高大于宽), landscape (横向,宽大于高)。resolution:设备分辨率 (如 min-resolution: 2dppx 用于 Retina 屏)。prefers-color-scheme (CSS4 草案):用户系统偏好的颜色方案(light 或 dark)。prefers-reduced-motion (CSS4 草案):用户偏好减少动画。and:逻辑与,所有条件都满足。or (现在用逗号 ,):逻辑或,只要有一个条件满足。not:逻辑非,取反。only:用于老旧浏览器不识别媒体查询时直接忽略。通常与 all 或 screen 一起使用:@media only screen and (...)。
/* 默认样式 (移动优先) */
body {
font-size: 14px;
background-color: #f0f8ff;
}
.container {
width: 90%;
margin: 0 auto;
}
/* 当屏幕宽度大于等于 768px 时 (平板电脑) */
@media screen and (min-width: 768px) {
body {
font-size: 16px;
background-color: #e6f7ff;
}
.container {
width: 720px;
}
}
/* 当屏幕宽度大于等于 1200px 时 (桌面电脑) */
@media screen and (min-width: 1200px) {
body {
font-size: 18px;
background-color: #d6f0ff;
}
.container {
width: 960px;
}
}
/* 打印样式 */
@media print {
body {
font-family: serif;
color: black;
background-color: white;
}
nav, footer {
display: none; /* 打印时隐藏导航和页脚 */
}
}
/* 暗黑模式适配 */
@media (prefers-color-scheme: dark) {
body {
background-color: #2c2c2c;
color: #e0e0e0;
}
.container {
background-color: #3a3a3a;
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.05);
}
h1, h2, h3, h4 {
color: #f8f8f8;
}
}
断点是媒体查询中定义样式变化的特定屏幕宽度。常见的断点包括:
< 576px 或 < 768px768px - 991px992px - 1199px>= 1200px强烈推荐使用“移动优先”的开发策略。这意味着首先为小屏幕(手机)设计和编写 CSS 样式,然后逐步使用 min-width 媒体查询为更大的屏幕添加和覆盖样式。
优点:
CSS3 渐变允许你在两个或多个颜色之间平滑过渡,创建美丽的背景效果,而无需使用图片。
颜色沿直线过渡。语法:linear-gradient(方向, 颜色1 [位置], 颜色2 [位置], ...)
to top, to bottom (默认), to left, to right。45deg (顺时针),-90deg (逆时针)。
.linear-gradient-1 {
background-image: linear-gradient(to right, red, yellow); /* 从左到右,红到黄 */
}
.linear-gradient-2 {
background-image: linear-gradient(45deg, blue 0%, green 50%, yellow 100%); /* 45度,蓝到绿再到黄 */
}
.linear-gradient-3 {
background-image: linear-gradient(to bottom, #f00 50%, #00f 50%); /* 50% 处颜色突变,创建分界线 */
}
颜色从中心点向外辐射。语法:radial-gradient([形状 大小] at 位置, 颜色1 [位置], 颜色2 [位置], ...)
circle (圆形), ellipse (椭圆形)。默认是 ellipse。closest-side, farthest-side, closest-corner, farthest-corner (默认)。100px 50px。center, top left) 或长度/百分比。
.radial-gradient-1 {
background-image: radial-gradient(circle at center, white, blue); /* 从中心白色到边缘蓝色 */
}
.radial-gradient-2 {
background-image: radial-gradient(ellipse at top left, yellow 0%, red 70%, black 100%);
}
在指定范围内重复线性或径向渐变,创建条纹或同心圆效果。
.striped-bg {
background-image: repeating-linear-gradient(
45deg,
#f0f0f0,
#f0f0f0 10px, /* 灰色 10px */
#ccc 10px,
#ccc 20px /* 深灰色 10px,总长度 20px */
);
}
.concentric-circles {
background-image: repeating-radial-gradient(
circle,
#f00,
#f00 5px,
#00f 5px,
#00f 10px
);
}
filter 属性允许你为元素应用各种图像效果,如模糊、灰度、亮度、对比度等,而无需修改原始图像文件。
blur(px):模糊效果。brightness(%):亮度调节。contrast(%):对比度调节。drop-shadow(h-shadow v-shadow blur spread color):与 box-shadow 类似,但可以应用于不规则形状。grayscale(%):灰度化。hue-rotate(deg):色相旋转。invert(%):反色。opacity(%):透明度 (与 opacity 属性类似,但滤镜版本的可能更高效)。saturate(%):饱和度调节。sepia(%):深褐色效果。url():引用 SVG 滤镜。
img.filtered {
filter: grayscale(100%) blur(2px) contrast(150%); /* 多个滤镜叠加 */
transition: filter 0.5s ease;
}
img.filtered:hover {
filter: none; /* 鼠标悬停时恢复正常 */
}
.blurred-background {
background-image: url('my-image.jpg');
/* backface-filter (实验性,通常需要前缀) 可以应用于元素后面的区域,实现毛玻璃效果 */
backdrop-filter: blur(5px) brightness(0.8);
}
CSS 遮罩和裁剪允许你以非矩形形状显示元素内容,或使用图像作为元素的透明度遮罩。这在创建复杂图形和艺术效果时非常有用。
mask 属性允许你使用图像或渐变作为元素的透明度遮罩,控制哪些部分可见,哪些部分透明。
mask-image:用作遮罩的图像。可以是 URL 或渐变。mask-mode:遮罩模式(亮度或Alpha)。mask-repeat, mask-position, mask-size:与背景属性类似。mask-composite:如何组合多个遮罩。假设有一个 SVG 文件 mask.svg,内容是一个星形:
<svg width="100" height="100">
<mask id="star-mask">
<polygon points="50,0 61.8,38.2 100,38.2 69.1,61.8 79.4,100 50,76.4 20.6,100 30.9,61.8 0,38.2 38.2,38.2" fill="white" />
</mask>
</svg>
然后在 CSS 中使用它:
.masked-image {
width: 200px;
height: 200px;
background-image: url('path/to/my-image.jpg');
-webkit-mask-image: url('#star-mask'); /* 引用 SVG 中的 mask ID,需要浏览器支持 */
mask-image: url('#star-mask'); /* 标准写法 */
-webkit-mask-size: cover;
mask-size: cover;
background-size: cover;
}
这样图片就会显示为星形。
clip-path 属性允许你将元素剪裁成任何你想要的形状,只显示形状内部的内容。
inset():矩形裁剪。circle():圆形裁剪。ellipse():椭圆形裁剪。polygon():多边形裁剪 (点坐标列表)。path():SVG 路径裁剪。url():引用 SVG 路径或 <clipPath> 元素。
.clipped-circle {
width: 200px;
height: 200px;
background-color: #3498db;
clip-path: circle(50% at 50% 50%); /* 裁剪成一个圆形 */
/* 兼容性前缀:-webkit-clip-path */
}
.clipped-polygon {
width: 250px;
height: 150px;
background-color: #e74c3c;
clip-path: polygon(50% 0%, 100% 100%, 0% 100%); /* 裁剪成一个三角形 */
}
clip-path 裁剪是可见区域,被裁剪的部分会完全消失,不占用空间。而 border-radius 只是视觉上的圆角,元素仍然是矩形。
这些单位是相对于视口(浏览器可见区域)的大小来计算的,对于响应式设计非常有用。
vh (viewport height):视口高度的 1%。
height: 100vh; /* 元素高度等于视口高度 */
vw (viewport width):视口宽度的 1%。
width: 50vw; /* 元素宽度等于视口宽度的一半 */
vmin (viewport minimum):视口宽度和高度中较小值的 1%。vmax (viewport maximum):视口宽度和高度中较大值的 1%。calc() 函数允许你在 CSS 中进行简单的数学运算(加、减、乘、除)。
宽度 = 100\% - 50px
.sidebar {
width: calc(100% - 200px - 20px); /* 容器宽度减去200px的固定宽度和20px的间距 */
float: left;
}
.header {
line-height: calc(1.5em + 10px); /* 字体大小的1.5倍再加10px */
}
+, -, *, /) 两侧必须有空格,特别是 + 和 -。
这些函数在更精细的响应式设计中提供了极大的灵活性。
min(val1, val2, ...):返回参数列表中最小的计算值。
width: min(50vw, 400px); /* 宽度取 视口宽度的一半 和 400px 中的较小值 */
/* 作用:元素最大宽度为 400px,但在小屏幕上会缩小 */
max(val1, val2, ...):返回参数列表中最大的计算值。
font-size: max(16px, 2vw); /* 字体大小取 16px 和 视口宽度的2% 中的较大值 */
/* 作用:字体最小为 16px,在大屏幕上会随之放大 */
clamp(min, preferred, max):将一个值限制在给定的最小值和最大值之间。
font-size: clamp(1rem, 2.5vw, 2.5rem); /* 字体大小:最小1rem,首选2.5vw,最大2.5rem */
/* 作用:字体在不同屏幕尺寸下动态调整,但不会小于或大于设定范围 */
理论知识是基础,但真正的掌握离不开实践。这部分我们将讨论在实际项目中如何运用 CSS3,以及一些提升开发效率和代码质量的最佳实践。
虽然现代浏览器对 CSS3 的支持越来越好,但为了兼容旧版本浏览器或某些特定浏览器,有时仍需要使用厂商前缀 (Vendor Prefixes)。
-webkit-:Chrome, Safari, Opera (旧版本), Android Browser。-moz-:Firefox。-o-:Opera (老版本)。-ms-:Internet Explorer (10 及以下)。
.transition-box {
-webkit-transition: all 0.3s ease; /* Webkit 浏览器 */
-moz-transition: all 0.3s ease; /* Firefox */
-o-transition: all 0.3s ease; /* Opera (旧版) */
transition: all 0.3s ease; /* 标准写法 */
}
.flex-container {
display: -webkit-box; /* 旧版 Flexbox 语法 */
display: -webkit-flex; /* Webkit 新版 Flexbox 语法 */
display: -ms-flexbox; /* IE 10 */
display: flex; /* 标准写法 */
}
手动添加和管理这些前缀非常繁琐且容易出错。推荐使用自动化工具来处理:
有了这些工具,你的主要精力可以放在编写标准、清晰的 CSS 上。
随着项目规模的增大,CSS 代码量会迅速增长,如果不合理组织,会变得难以维护和扩展。CSS 架构模式旨在提供一种结构化方法来编写可伸缩、可维护的 CSS。
一种流行的 CSS 类命名约定,旨在使 CSS 更模块化和可重用。
.button, .header)。.button__icon, .header__title)。通过双下划线 __ 连接。.button--primary, .button--disabled, .header__title--small)。通过双连字符 -- 连接。
<div class="card">
<img class="card__image" src="image.jpg" alt="Card Image">
<div class="card__content">
<h3 class="card__title card__title--large">卡片标题</h3>
<p class="card__text">这是卡片的内容。</p>
<button class="card__button card__button--primary">查看</button>
</div>
</div>
.card { /* Block */
/* ... 基础样式 ... */
}
.card__image { /* Element */
/* ... 图像样式 ... */
}
.card__title { /* Element */
/* ... 标题基础样式 ... */
}
.card__title--large { /* Modifier */
font-size: 1.8em;
}
.card__button { /* Element */
/* ... 按钮基础样式 ... */
}
.card__button--primary { /* Modifier */
background-color: blue;
color: white;
}
提倡将样式分解为可重用的“对象”,包括:
.button)和它的颜色(.blue-button)分开定义。
/* 结构对象 */
.media-object {
overflow: hidden; /* 清除浮动 */
}
.media-object__img {
float: left;
margin-right: 10px;
}
/* 皮肤对象 */
.border-thin { border: 1px solid #ccc; }
.bg-light-gray { background-color: #f0f0f0; }
<div class="media-object border-thin bg-light-gray">
<img class="media-object__img" src="...">
<div class="media-object__body">...</div>
</div>
将 CSS 规则分为五个类别:
body, h1, p)。.l-header, .l-sidebar)。.card, .button)。.is-hidden, .is-active)。为了解决原生 CSS 的一些局限性(如变量、嵌套、模块化),前端社区发展出了预处理器和后处理器。
预处理器(如 Sass, Less, Stylus)在 CSS 文件发布到浏览器之前对其进行编译。它们引入了编程语言的特性,使 CSS 编写更强大和高效。
$primary-color: #3498db;
nav {
ul {
margin: 0;
padding: 0;
li {
list-style: none;
a {
display: block;
padding: 10px 15px;
&:hover { /* & 代表父选择器 */
background-color: darken($primary-color, 10%);
}
}
}
}
}
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
.box {
@include border-radius(5px);
}
@import "filename"; 导入其他 Sass 文件,编译时会合并为一个 CSS 文件。后处理器是在 CSS 编译完成后(或者原生 CSS 编写完成后)对 CSS 进行处理的工具。它就像一个 CSS 的“插件系统”,可以执行各种任务。
一个工具,它允许你使用 JavaScript 插件来转换 CSS。它本身不做任何转换,但提供了一个 API 供插件使用。
高效的 CSS 不仅关乎代码质量,更影响网页的加载速度和渲染性能,从而直接影响用户体验。
将多张小图片合并成一张大图片,通过调整 background-position 来显示所需的图标。这样可以减少 HTTP 请求,提高加载速度。
.icon {
background-image: url('sprites.png'); /* 合并后的雪碧图 */
background-repeat: no-repeat;
width: 32px; /* 单个图标的尺寸 */
height: 32px;
}
.icon-home {
background-position: 0 0; /* 显示雪碧图左上角的图标 */
}
.icon-settings {
background-position: -32px 0; /* 显示雪碧图向右偏移32px的图标 */
}
某些 CSS 属性(如 transform, opacity, filter)可以被 GPU (图形处理器) 加速渲染,从而实现更流畅的动画效果。
通常,当浏览器检测到这些属性时,会自动将元素提升到单独的复合层 (Composite Layer) 进行渲染。
will-change 属性:
你可以使用 will-change 属性提前告知浏览器某个元素将要发生变化,从而让浏览器进行优化。
但不要滥用,因为这会消耗更多的内存和 CPU 资源,适得其反。
.animated-element {
will-change: transform, opacity; /* 告诉浏览器,transform 和 opacity 将会频繁变化 */
}
掌握 Flexbox 和 Grid 后,我们可以轻松实现各种经典的布局模式。
它们都是实现“两边固定,中间自适应三列布局”的经典方案。在 Flexbox 和 Grid 之前,主要依赖浮动和负外边距实现。现在,用 Flexbox 或 Grid 会简单得多。
<style>
.holy-grail-flex {
display: flex;
min-height: 100vh; /* 确保占满视口高度 */
flex-direction: column; /* 垂直方向排列 */
}
.hg-header, .hg-footer {
background-color: #34495e;
color: white;
padding: 15px;
text-align: center;
}
.hg-main {
display: flex; /* 主内容区内部也用 Flex */
flex: 1; /* 占据剩余空间 */
}
.hg-sidebar-left, .hg-sidebar-right {
width: 150px;
background-color: #ecf0f1;
padding: 15px;
}
.hg-content {
flex: 1; /* 内容区占据剩余空间 */
padding: 15px;
background-color: #ffffff;
}
</style>
<div class="holy-grail-flex">
<header class="hg-header">页眉</header>
<div class="hg-main">
<aside class="hg-sidebar-left">左侧边栏</aside>
<main class="hg-content">主内容区</main>
<aside class="hg-sidebar-right">右侧边栏</aside>
</div>
<footer class="hg-footer">页脚</footer>
</div>
项目高度不一,按列排列,下一项目填充上一列的空白。虽然 CSS Grid 原生有 `masonry` 值(草案中),但目前常通过 JavaScript 或使用 `column` 实现。
<style>
.masonry-columns {
columns: 3 300px; /* 至少3列,每列至少300px */
column-gap: 20px;
width: 90%;
margin: 20px auto;
}
.masonry-item {
background-color: #ecf0f1;
margin-bottom: 20px; /* 项目之间的垂直间距 */
padding: 15px;
border-radius: 5px;
break-inside: avoid-column; /* 避免在项目内部断列 */
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.masonry-item h4 {
margin-top: 0;
color: #2980b9;
}
/* 模拟不同高度 */
.item-h-1 { height: 120px; }
.item-h-2 { height: 200px; }
.item-h-3 { height: 80px; }
.item-h-4 { height: 150px; }
.item-h-5 { height: 100px; }
.item-h-6 { height: 180px; }
</style>
<div class="masonry-columns">
<div class="masonry-item item-h-1"><h4>卡片 1</h4><p>内容 1</p></div>
<div class="masonry-item item-h-2"><h4>卡片 2</h4><p>内容 2 长内容长内容长内容长内容长内容长内容。</p></div>
<div class="masonry-item item-h-3"><h4>卡片 3</h4><p>内容 3</p></div>
<div class="masonry-item item-h-4"><h4>卡片 4</h4><p>内容 4 较长内容。</p></div>
<div class="masonry-item item-h-5"><h4>卡片 5</h4><p>内容 5</p></div>
<div class="masonry-item item-h-6"><h4>卡片 6</h4><p>内容 6 很长很长很长很长很长内容。</p></div>
</div>
确保页脚始终位于页面底部,即使内容不足以撑满整个屏幕高度。
<style>
html, body {
height: 100%; /* 确保html和body高度为100% */
margin: 0;
}
.site {
display: flex;
flex-direction: column;
min-height: 100vh; /* 保证容器最小高度为视口高度 */
}
.site-content {
flex: 1; /* 主内容区占据所有剩余空间 */
padding: 20px;
background-color: #fff;
}
.site-footer {
background-color: #34495e;
color: white;
padding: 20px;
text-align: center;
}
</style>
<div class="site">
<header class="site-header">网站头部</header>
<main class="site-content">
<h2>主内容区域</h2>
<p>这里是网站的主要内容。如果内容很少,页脚也会粘在底部。</p>
<!-- 如果内容很多,滚动条出现,页脚自然向下 -->
</main>
<footer class="site-footer">网站页脚 © 2023</footer>
</div>
响应式设计不仅仅是媒体查询,它是一种整体设计思想。
如前所述,始终从移动设备开始设计和开发。使用 min-width 媒体查询逐步为更大屏幕增加样式。
/* Mobile base styles */
.grid-gallery {
display: grid;
grid-template-columns: 1fr; /* 手机上一列 */
gap: 10px;
}
/* Tablet styles */
@media (min-width: 768px) {
.grid-gallery {
grid-template-columns: repeat(2, 1fr); /* 平板两列 */
}
}
/* Desktop styles */
@media (min-width: 1024px) {
.grid-gallery {
grid-template-columns: repeat(3, 1fr); /* 桌面三列 */
}
}
max-width: 100%; height: auto;。
img { max-width: 100%; height: auto; display: block; }
<picture> 元素和 srcset 属性: 允许你根据屏幕尺寸、分辨率等提供不同版本的图片,以优化加载性能和视觉效果。
<picture>
<source srcset="large.jpg" media="(min-width: 1200px)">
<source srcset="medium.jpg" media="(min-width: 768px)">
<img src="small.jpg" alt="Responsive Image">
</picture>
<!-- srcset 用于不同分辨率的同一图片 -->
<img srcset="photo-1x.jpg 1x, photo-2x.jpg 2x"
src="photo-1x.jpg" alt="High-Res Image">
<iframe> 嵌入视频时,可以使用 CSS 的宽高比技巧。
.video-container {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 比例 (9 / 16 = 0.5625) */
height: 0;
overflow: hidden;
}
.video-container iframe,
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
CSS 动画和过渡能够极大地提升用户体验,增加页面的生动性。
使用 CSS 动画制作简单的加载指示器。
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid rgba(0, 0, 0, 0.1);
border-left-color: #3498db;
border-radius: 50%;
animation: spinner 0.8s linear infinite;
}
@keyframes spinner {
to { transform: rotate(360deg); }
}
背景图像以不同于前景内容的速度滚动,创造深度感。通常通过 background-attachment: fixed; 结合背景图或使用 JavaScript 实现。
.parallax-section {
background-image: url('parallax-bg.jpg');
background-attachment: fixed; /* 背景图固定 */
background-position: center;
background-repeat: no-repeat;
background-size: cover;
height: 400px; /* 视差区域高度 */
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 2em;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
使用 max-height 或 transform 结合 transition 实现平滑的展开/收缩效果。
.dropdown-menu {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out; /* 关键:过渡 max-height */
}
.dropdown-parent:hover .dropdown-menu {
max-height: 200px; /* 展开后的最大高度 */
}
/* 或者使用 transform */
.slide-menu {
transform: translateY(-100%);
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.is-active .slide-menu {
transform: translateY(0);
opacity: 1;
}
CSS 自定义属性(又称 CSS 变量或原生 CSS 变量)允许你在 CSS 中定义自己的变量,并在整个样式表中重复使用。它们是 CSS3 带来的一个重大改进。
-- 作为前缀来定义变量。
:root { /* 通常在 :root 伪类中定义全局变量 */
--primary-color: #3498db;
--font-size-base: 16px;
--spacing-unit: 10px;
}
.card {
--card-bg-color: #fff; /* 也可以在特定选择器中定义局部变量 */
}
var() 函数来引用变量。
body {
background-color: var(--primary-color);
font-size: var(--font-size-base);
}
.button {
background-color: var(--primary-color);
padding: var(--spacing-unit) calc(var(--spacing-unit) * 2);
}
var() 函数的第二个参数:
var(--my-variable, fallback-value),当变量未定义时,使用 fallback-value。
color: var(--undefined-color, red); /* 如果 --undefined-color 未定义,则使用红色 */
CSS 变量遵循正常的 CSS 级联规则。变量可以在任何选择器中定义,并且其作用域会向下传递给子元素。
:root { --main-color: blue; } /* 全局 */
.dark-theme { --main-color: black; } /* .dark-theme 及其子元素使用黑色 */
div { color: var(--main-color); }
$ 变量):
<style>
:root {
--bg-color: #f0f7f6;
--text-color: #333;
--primary-accent: #3498db;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
.accent-button {
background-color: var(--primary-accent);
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.theme-switcher {
margin-top: 20px;
padding: 10px;
border: 1px solid var(--text-color);
border-radius: 5px;
}
</style>
<body>
<h2>使用 CSS 变量实现主题切换</h2>
<p>点击按钮切换页面主题颜色。</p>
<button class="accent-button" id="toggleThemeBtn">切换主题</button>
<script>
document.getElementById('toggleThemeBtn').addEventListener('click', function() {
const root = document.documentElement; // 获取 :root 元素
const currentBg = getComputedStyle(root).getPropertyValue('--bg-color').trim();
if (currentBg === '#f0f7f6') { // 当前是浅色主题
root.style.setProperty('--bg-color', '#2c2c2c');
root.style.setProperty('--text-color', '#e0e0e0');
root.style.setProperty('--primary-accent', '#8e44ad');
} else { // 当前是深色主题
root.style.setProperty('--bg-color', '#f0f7f6');
root.style.setProperty('--text-color', '#333');
root.style.setProperty('--primary-accent', '#3498db');
}
});
</script>
</body>
传统的媒体查询是基于视口(Viewport)大小来调整页面布局的。而容器查询 (@container) 允许你根据父容器的大小来调整其内容样式。这对于构建可重用的组件非常重要,因为组件不再需要知道整个页面的视口大小。
.card-wrapper {
container-type: inline-size; /* 声明这是一个容器查询的上下文,基于行内尺寸(宽度)*/
}
.card {
/* 默认样式 */
display: flex;
flex-direction: column;
}
@container (min-width: 400px) { /* 当 .card-wrapper 宽度大于等于 400px 时 */
.card {
flex-direction: row; /* 卡片内容变为水平排列 */
align-items: center;
}
.card__image {
width: 100px;
height: 100px;
margin-right: 15px;
}
}
这个例子中,无论 .card-wrapper 在哪个媒体查询断点下,只要它自身的宽度超过 400px,.card 内部的布局就会从垂直变为水平。
在第 10 章的媒体查询中已经提到,这是一个非常重要的媒体特性,用于适配操作系统的暗色/亮色模式设置。
/* 默认亮色主题 */
body {
background-color: white;
color: black;
}
/* 用户系统偏好暗色主题时 */
@media (prefers-color-scheme: dark) {
body {
background-color: #1a1a1a;
color: #e0e0e0;
}
}
这个媒体特性用于检测用户是否在操作系统设置中开启了“减少动态效果”或“减少动画”选项。这对于关心可访问性的开发者非常重要。
.hero-animation {
animation: fadeIn 1s ease-out forwards;
}
@media (prefers-reduced-motion: reduce) {
.hero-animation {
animation: none; /* 如果用户偏好减少动画,则直接禁用动画 */
transition: none; /* 禁用过渡 */
}
/* 或者提供一个更简洁、不那么花哨的动画 */
.hero-animation-alt {
opacity: 1; /* 直接显示 */
}
}
可缩放矢量图形 (SVG) 是基于 XML 的 2D 矢量图形格式。CSS 可以很好地控制 SVG 的样式。
<svg width="100" height="100">
<style>
rect {
fill: blue;
stroke: black;
stroke-width: 2;
}
.my-circle {
fill: green;
}
</style>
<rect x="10" y="10" width="80" height="80" />
<circle cx="50" cy="50" r="40" class="my-circle" />
</svg>
如果 SVG 是作为 <img>, <object> 或 <iframe> 引入,则外部 CSS 无法直接控制 SVG 内部元素的样式。
但如果是直接内联在 HTML 中的 SVG (inline SVG),则可以像控制普通 HTML 元素一样控制其样式。
<style>
#mySvgIcon circle {
fill: red; /* 改变圆形的颜色 */
transition: fill 0.3s ease;
}
#mySvgIcon:hover circle {
fill: orange; /* 悬停时改变颜色 */
}
</style>
<svg id="mySvgIcon" width="50" height="50" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40"/>
</svg>
如前面章节所述,可以将 SVG 定义的复杂形状用作元素的 mask 或 clip-path。
SVG 自身提供了一套强大的滤镜功能 (<filter> 元素),可以通过 CSS 的 filter: url(#filterID); 属性引用。这允许你实现 CSS filter 无法做到的更复杂的图像处理效果。
CSS 仍在不断发展,一些新的特性正在被提案和实现。了解它们能让你保持前瞻性。
一套低级 API,暴露了 CSS 引擎的各个部分,允许开发者扩展 CSS 本身的能力。例如,你可以编写 JavaScript 来定义新的 CSS 属性,或者创建自定义的布局和绘制行为。
// JS 中注册一个 CSS 变量
CSS.registerProperty({
name: '--my-color',
syntax: '<color>',
inherits: false,
initialValue: 'blue',
});
Houdini 是对 CSS 扩展性的一次革命,但目前浏览器支持度仍在发展中。
CSS 最受期待的特性之一。它允许你选择一个元素,如果它包含(或不包含)符合特定条件的其他元素。这意味着 CSS 终于有了“父选择器”的功能。
/* 选择所有包含图片的文章 */
article:has(img) {
border: 2px solid green;
}
/* 选择那些不是第一个子元素的,且其前面有一个 h2 的 p 元素 */
p:has(~ h2) { /* 这不是父选择器,而是兄弟选择器的复杂应用 */
margin-top: 2em;
}
/* 选择包含 .error 类的表单 (Form validation) */
form:has(.error) button[type="submit"] {
background-color: red; /* 如果表单中有错误,提交按钮变红 */
}
/* 如果 .card 内部有 .card__image 但没有 .card__text,则 .card 样式 */
.card:has(.card__image):not(:has(.card__text)) {
/* ... 样式 ... */
}
CSS Working Group 正在开发原生的 CSS 嵌套语法,这意味着你将来可以在原生 CSS 中直接进行选择器嵌套,就像在 Sass/Less 中一样。
@scope 或 @layer 上下文):
.card {
/* 基础样式 */
& .title { /* 嵌套 .title 类,等同于 .card .title */
font-size: 1.2em;
}
&:hover { /* 嵌套伪类,等同于 .card:hover */
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.image { /* 如果没有 &,默认是后代选择器 */
max-width: 100%;
}
@media (max-width: 600px) { /* 在内部嵌套媒体查询 */
padding: 10px;
}
}
CSS 未来将支持更广阔的色彩空间,如 LCH (Luminance, Chroma, Hue) 和 OKLCH。这些色彩空间更符合人类感知,使得颜色管理更加直观和强大,能表示更鲜艳、更真实的颜色,并更好地进行颜色混合和变亮变暗操作。
.color-lch {
color: lch(50% 80 120); /* 亮度 50%, 色度 80, 色相 120 (绿色调) */
}
.color-oklch {
color: oklch(70% 0.15 250); /* 新一代的 LCH 变体,感知更均匀 */
}
恭喜您,完成了 CSS3 从入门到精通的全部内容! 这份教程涵盖了 CSS 的核心概念、CSS3 的主要新特性、以及在实际开发中的应用和最佳实践。从盒模型到 Flexbox 和 Grid,从过渡动画到响应式设计,您已经建立了一个扎实的 CSS 知识体系。
学习无止境: CSS 是一个不断发展的领域。建议您在日常开发中多加练习,尝试实现各种效果和布局。同时,关注 CSS Working Group 的最新进展,探索新的属性和特性,保持对前端技术的热情和好奇心。
感谢您的学习,祝您在前端开发的道路上越走越远!