CSS3 从入门到精通
目录
简介
CSS3 是层叠样式表(Cascading Style Sheets)的第三个主要版本。与 CSS2.1 相比,CSS3 引入了大量新特性,极大地增强了网页的视觉表现力和布局能力。CSS3 采用了模块化设计,各个功能被划分为独立的模块,如选择器模块、盒模型模块、背景模块、动画模块等,每个模块可以独立发展和实现。
CSS3 的核心改进:
- 更强大的选择器系统
- 全新的布局模式(Flexbox、Grid)
- 过渡和动画效果
- 2D/3D 变换
- 响应式设计支持
- 自定义属性(CSS 变量)
- 阴影、渐变、滤镜等视觉效果
学习前置知识:
- HTML 基础
- CSS1/CSS2 基本语法
- 了解选择器、盒模型等基本概念
CSS3 选择器
CSS3 大幅扩展了选择器系统,提供了更精确、更灵活的元素选择方式。
属性选择器
/* 存在属性 */
[data-role] {
background: #f0f0f0;
}
/* 属性值精确匹配 */
[data-status="active"] {
color: green;
}
/* 属性值包含指定单词(空格分隔) */
[class~="highlight"] {
background: yellow;
}
/* 属性值以指定字符串开头 */
[href^="https://"] {
color: green;
}
/* 属性值以指定字符串结尾 */
[href$=".pdf"] {
color: red;
}
/* 属性值包含指定字符串 */
[href*="example"] {
text-decoration: underline;
}
/* 属性值以指定字符串开头(连字符分隔) */
[lang|="zh"] {
font-family: "Microsoft YaHei", sans-serif;
}
<!-- 属性选择器示例 -->
<div data-role="admin" data-status="active">管理员面板</div>
<a href="https://example.com">安全链接</a>
<a href="/files/report.pdf">下载 PDF</a>
<span lang="zh-CN">中文内容</span>
结构伪类选择器
/* :first-child - 第一个子元素 */
li:first-child {
font-weight: bold;
}
/* :last-child - 最后一个子元素 */
li:last-child {
border-bottom: none;
}
/* :nth-child(n) - 第 n 个子元素 */
tr:nth-child(odd) {
background: #f9f9f9;
}
/* :nth-child(2n) - 偶数行 */
tr:nth-child(2n) {
background: #fff;
}
/* :nth-child(3n+1) - 每隔两个选一个 */
.item:nth-child(3n+1) {
color: red;
}
/* :nth-last-child(n) - 从后往前数 */
li:nth-last-child(2) {
color: blue;
}
/* :nth-of-type(n) - 同类型中的第 n 个 */
p:nth-of-type(2) {
font-style: italic;
}
/* :first-of-type / :last-of-type */
h2:first-of-type {
margin-top: 0;
}
/* :only-child - 唯一的子元素 */
div:only-child {
background: lightblue;
}
/* :only-of-type - 同类型中唯一的元素 */
p:only-of-type {
font-size: 1.2em;
}
/* :empty - 空元素 */
div:empty {
display: none;
}
/* :not() - 否定选择器 */
li:not(.special) {
color: #666;
}
/* :has() - 父元素选择器(较新) */
div:has(> img) {
padding: 10px;
}
article:has(h2) {
border-left: 3px solid #3498db;
}
伪元素
/* ::before 和 ::after */
.quote::before {
content: '"';
font-size: 2em;
color: #3498db;
vertical-align: middle;
}
.quote::after {
content: '"';
font-size: 2em;
color: #3498db;
}
/* ::first-line - 首行 */
p::first-line {
font-weight: bold;
color: #333;
}
/* ::first-letter - 首字母 */
.article p::first-letter {
font-size: 3em;
float: left;
line-height: 1;
margin-right: 10px;
color: #e74c3c;
font-family: Georgia, serif;
}
/* ::selection - 选中文本 */
::selection {
background: #3498db;
color: white;
}
/* ::placeholder - 占位符文本 */
input::placeholder {
color: #999;
font-style: italic;
}
/* ::marker - 列表标记 */
li::marker {
color: #e74c3c;
font-size: 1.2em;
}
/* 实用示例:清除浮动 */
.clearfix::after {
content: '';
display: table;
clear: both;
}
/* 实用示例:渐变边框 */
.gradient-border {
position: relative;
padding: 20px;
}
.gradient-border::before {
content: '';
position: absolute;
inset: 0;
padding: 3px;
background: linear-gradient(135deg, #e74c3c, #3498db);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
border-radius: inherit;
}
逻辑组合选择器
/* :is() - 匹配任意一个选择器 */
:is(h1, h2, h3) {
color: #2c3e50;
font-family: Georgia, serif;
}
/* 等价于 */
/* h1, h2, h3 { ... } */
/* :is() 的优先级取决于参数中优先最高的选择器 */
:is(#special, .highlight) p {
font-weight: bold;
}
/* :where() - 与 :is() 类似但优先级为 0 */
:where(h1, h2, h3) {
margin-top: 0;
}
/* :not() 可以接受多个选择器 */
:not(h1, h2, h3) {
font-weight: normal;
}
/* 组合使用 */
article:is(.featured, .trending) :where(h2, h3) {
color: #e74c3c;
}
/* :has() 组合 */
.card:has(img):has(.title) {
display: grid;
grid-template-columns: auto 1fr;
}
盒模型深入理解
标准盒模型 vs IE 盒模型
/* 标准盒模型(默认) */
/* width/height = 内容区域的宽高 */
/* 总宽度 = width + padding + border + margin */
.standard-box {
box-sizing: content-box; /* 默认值 */
width: 200px;
padding: 20px;
border: 5px solid #333;
margin: 10px;
/* 实际占据宽度 = 200 + 20*2 + 5*2 + 10*2 = 270px */
}
/* IE 盒模型 */
/* width/height = 内容 + padding + border 的总宽高 */
/* 总宽度 = width + margin */
.ie-box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid #333;
margin: 10px;
/* 实际占据宽度 = 200 + 10*2 = 220px */
/* 内容区域 = 200 - 20*2 - 5*2 = 150px */
}
/* 推荐:全局设置 border-box */
*, *::before, *::after {
box-sizing: border-box;
}
外边距合并
/* 垂直外边距合并:相邻元素的垂直外边距会合并为较大的那个值 */
.box1 {
margin-bottom: 30px;
background: #3498db;
padding: 20px;
}
.box2 {
margin-top: 20px;
background: #e74c3c;
padding: 20px;
}
/* 实际间距为 30px(较大的值),而非 50px(30+20) */
/* 阻止外边距合并的方法 */
.parent {
/* 方法1:创建 BFC */
overflow: hidden;
}
.parent {
/* 方法2:使用 padding 代替 margin */
padding-top: 1px;
}
/* 父子元素的外边距合并 */
/* 子元素的 margin-top 会与父元素的 margin-top 合并 */
.parent {
margin-top: 20px;
}
.child {
margin-top: 30px; /* 这个 margin 会穿透到父元素外面 */
}
/* 解决方案 */
.parent-fixed {
padding-top: 1px; /* 或 border-top、overflow: hidden 等 */
margin-top: 20px;
}
CSS 变量(自定义属性)
/* 定义 CSS 变量 */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--danger-color: #e74c3c;
--text-color: #333;
--bg-color: #fff;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--font-size-base: 16px;
--border-radius: 8px;
--shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
/* 使用 CSS 变量 */
.button {
background: var(--primary-color);
color: white;
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
font-size: var(--font-size-base);
box-shadow: var(--shadow);
transition: var(--transition);
border: none;
cursor: pointer;
}
.button:hover {
background: color-mix(in srgb, var(--primary-color) 80%, black);
}
/* 变量作用域 */
.card {
--card-bg: #f8f9fa;
background: var(--card-bg);
padding: var(--spacing-lg);
}
.card.highlight {
--card-bg: #fff3cd;
/* 局部变量覆盖 */
}
/* 媒体查询中修改变量 */
@media (prefers-color-scheme: dark) {
:root {
--text-color: #f0f0f0;
--bg-color: #1a1a2e;
}
}
/* JavaScript 操作 CSS 变量 */
/*
const root = document.documentElement;
root.style.setProperty('--primary-color', '#e74c3c');
const value = getComputedStyle(root).getPropertyValue('--primary-color');
*/
Flexbox 弹性盒子布局
Flexbox 是一种一维布局模型,非常适合在行或列方向上分配空间。
基本概念
/* 容器属性 */
.flex-container {
display: flex;
/* 主轴方向 */
flex-direction: row; /* 默认:从左到右 */
/* flex-direction: row-reverse; 从右到左 */
/* flex-direction: column; 从上到下 */
/* flex-direction: column-reverse; 从下到上 */
/* 换行 */
flex-wrap: nowrap; /* 默认:不换行 */
/* flex-wrap: wrap; 换行 */
/* flex-wrap: wrap-reverse; 反向换行 */
/* 简写 */
/* flex-flow: row wrap; */
/* 主轴对齐 */
justify-content: flex-start; /* 默认:起始对齐 */
/* justify-content: flex-end; 末尾对齐 */
/* justify-content: center; 居中 */
/* justify-content: space-between; 两端对齐 */
/* justify-content: space-around; 等间距(两倍) */
/* justify-content: space-evenly; 完全等间距 */
/* 交叉轴对齐(单行) */
align-items: stretch; /* 默认:拉伸 */
/* align-items: flex-start; 起始对齐 */
/* align-items: flex-end; 末尾对齐 */
/* align-items: center; 居中 */
/* align-items: baseline; 基线对齐 */
/* 交叉轴对齐(多行) */
align-content: flex-start; /* 与 justify-content 类似 */
/* 间距 */
gap: 10px;
/* row-gap: 10px; 行间距 */
/* column-gap: 20px; 列间距 */
}
/* 项目属性 */
.flex-item {
/* 排列顺序 */
order: 0; /* 默认:0,数值越小越靠前 */
/* 放大比例 */
flex-grow: 0; /* 默认:0,不放大 */
/* flex-grow: 1; 占据剩余空间 */
/* 缩小比例 */
flex-shrink: 1; /* 默认:1,空间不足时缩小 */
/* flex-shrink: 0; 不缩小 */
/* 基础大小 */
flex-basis: auto; /* 默认:auto,根据内容决定 */
/* flex-basis: 200px; */
/* flex-basis: 0; 忽略内容大小 */
/* 简写 */
flex: 0 1 auto; /* grow shrink basis */
/* flex: 1; 等同于 flex: 1 1 0% */
/* flex: auto; 等同于 flex: 1 1 auto */
/* flex: none; 等同于 flex: 0 0 auto */
/* 单独对齐 */
align-self: auto; /* 继承容器的 align-items */
/* align-self: flex-start; */
/* align-self: center; */
}
Flex 布局实战
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Flexbox 布局实战</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
.example { margin-bottom: 40px; background: white; padding: 20px; border-radius: 8px; }
.example h2 { margin-bottom: 15px; color: #333; }
/* 1. 水平垂直居中 */
.center-box {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
background: #ecf0f1;
border-radius: 8px;
}
.center-box .content {
padding: 20px;
background: #3498db;
color: white;
border-radius: 8px;
}
/* 2. 等高卡片布局 */
.card-row {
display: flex;
gap: 20px;
}
.card {
flex: 1;
padding: 20px;
background: #f8f9fa;
border: 1px solid #ddd;
border-radius: 8px;
}
.card h3 { margin-bottom: 10px; color: #2c3e50; }
/* 3. 固定 + 弹性布局 */
.layout {
display: flex;
gap: 20px;
min-height: 300px;
}
.sidebar {
width: 250px;
background: #2c3e50;
color: white;
padding: 20px;
border-radius: 8px;
}
.main-content {
flex: 1;
background: white;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
/* 4. 导航栏 */
.navbar {
display: flex;
align-items: center;
padding: 10px 20px;
background: #2c3e50;
border-radius: 8px;
}
.navbar .logo { color: white; font-size: 24px; font-weight: bold; }
.navbar .nav-links {
display: flex;
gap: 20px;
list-style: none;
margin-left: auto;
}
.navbar .nav-links a { color: white; text-decoration: none; }
/* 5. 圣杯布局 */
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.hg-header { background: #3498db; color: white; padding: 20px; text-align: center; }
.hg-body { display: flex; flex: 1; }
.hg-nav { width: 200px; background: #ecf0f1; padding: 20px; }
.hg-main { flex: 1; padding: 20px; }
.hg-aside { width: 200px; background: #ecf0f1; padding: 20px; }
.hg-footer { background: #2c3e50; color: white; padding: 20px; text-align: center; }
/* 6. 底部固定 */
.page-wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.page-content { flex: 1; }
.page-footer { /* 自动推到底部 */ }
/* 7. 响应式导航 */
.responsive-nav {
display: flex;
flex-wrap: wrap;
align-items: center;
padding: 10px 20px;
background: #8e44ad;
border-radius: 8px;
}
.responsive-nav .brand { color: white; font-weight: bold; }
.responsive-nav .menu {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-left: auto;
}
.responsive-nav .menu a {
color: white;
text-decoration: none;
padding: 5px 10px;
border-radius: 4px;
}
.responsive-nav .menu a:hover { background: rgba(255,255,255,0.2); }
</style>
</head>
<body>
<!-- 1. 居中 -->
<div class="example">
<h2>1. 水平垂直居中</h2>
<div class="center-box">
<div class="content">居中内容</div>
</div>
</div>
<!-- 2. 等高卡片 -->
<div class="example">
<h2>2. 等高卡片布局</h2>
<div class="card-row">
<div class="card">
<h3>卡片 1</h3>
<p>简短内容</p>
</div>
<div class="card">
<h3>卡片 2</h3>
<p>这是一段比较长的内容,用于演示等高效果。Flex 布局会自动让同一行的卡片保持相同高度。</p>
</div>
<div class="card">
<h3>卡片 3</h3>
<p>中等长度的内容</p>
</div>
</div>
</div>
<!-- 3. 固定+弹性布局 -->
<div class="example">
<h2>3. 固定侧边栏 + 弹性主内容</h2>
<div class="layout">
<div class="sidebar">侧边栏(固定宽度 250px)</div>
<div class="main-content">主内容区域(自动填充剩余空间)</div>
</div>
</div>
<!-- 4. 导航栏 -->
<div class="example">
<h2>4. 导航栏</h2>
<nav class="navbar">
<span class="logo">Brand</span>
<ul class="nav-links">
<li><a href="#">首页</a></li>
<li><a href="#">产品</a></li>
<li><a href="#">关于</a></li>
<li><a href="#">联系</a></li>
</ul>
</nav>
</div>
<!-- 5. 响应式导航 -->
<div class="example">
<h2>5. 响应式导航</h2>
<nav class="responsive-nav">
<span class="brand">网站名称</span>
<div class="menu">
<a href="#">首页</a>
<a href="#">产品</a>
<a href="#">服务</a>
<a href="#">博客</a>
<a href="#">联系我们</a>
</div>
</nav>
</div>
</body>
</html>
Flex 常见模式
/* 粘性底部 */
.sticky-footer {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.sticky-footer main { flex: 1; }
/* 等宽分栏 */
.equal-columns {
display: flex;
}
.equal-columns > * { flex: 1; }
/* 固定宽度 + 自适应 */
.fixed-fluid {
display: flex;
}
.fixed-fluid .fixed { width: 300px; flex-shrink: 0; }
.fixed-fluid .fluid { flex: 1; min-width: 0; }
/* 居中 */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* 两端对齐,垂直居中 */
.between-center {
display: flex;
justify-content: space-between;
align-items: center;
}
/* 自动 margin */
.push-right {
margin-left: auto;
}
/* 媒体查询响应式 */
@media (max-width: 768px) {
.flex-container {
flex-direction: column;
}
}
Grid 网格布局
CSS Grid 是一种二维布局系统,可以同时控制行和列。
基本语法
.grid-container {
display: grid;
/* 定义列 */
grid-template-columns: 200px 1fr 200px;
/* 三种方式:固定值、分数fr、auto */
/* 定义行 */
grid-template-rows: auto 1fr auto;
/* 间距 */
gap: 20px;
/* row-gap: 20px; */
/* column-gap: 20px; */
/* 命名区域 */
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
/* 使用命名区域放置子元素 */
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* 子元素放置 */
.grid-item {
/* 指定位置 */
grid-column: 1 / 3; /* 从第1条列线到第3条列线 */
grid-row: 1 / 2; /* 从第1条行线到第2条行线 */
/* 简写 */
grid-area: 1 / 1 / 2 / 3; /* row-start / col-start / row-end / col-end */
/* 跨越 */
grid-column: span 2; /* 跨越2列 */
grid-row: span 3; /* 跨越3行 */
}
Grid 实战示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Grid 布局实战</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
.example { margin-bottom: 40px; background: white; padding: 20px; border-radius: 8px; }
.example h2 { margin-bottom: 15px; }
.grid-item {
padding: 20px;
background: #3498db;
color: white;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
}
/* 1. 基本网格 */
.basic-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
/* 2. 响应式网格 */
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
/* 3. 经典布局 */
.classic-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 400px;
gap: 10px;
}
.classic-layout .header { grid-area: header; background: #2c3e50; }
.classic-layout .sidebar { grid-area: sidebar; background: #34495e; }
.classic-layout .main { grid-area: main; background: #ecf0f1; color: #333; }
.classic-layout .footer { grid-area: footer; background: #2c3e50; }
/* 4. 瀑布流 */
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 50px;
gap: 10px;
}
.masonry .item:nth-child(1) { grid-row: span 3; background: #e74c3c; }
.masonry .item:nth-child(2) { grid-row: span 2; background: #3498db; }
.masonry .item:nth-child(3) { grid-row: span 4; background: #2ecc71; }
.masonry .item:nth-child(4) { grid-row: span 2; background: #f39c12; }
.masonry .item:nth-child(5) { grid-row: span 3; background: #9b59b6; }
.masonry .item:nth-child(6) { grid-row: span 2; background: #1abc9c; }
/* 5. 仪表盘布局 */
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
gap: 15px;
}
.dashboard .stat { background: #3498db; padding: 20px; border-radius: 8px; color: white; }
.dashboard .chart { grid-column: span 2; background: #ecf0f1; padding: 20px; border-radius: 8px; min-height: 200px; color: #333; }
.dashboard .full-width { grid-column: 1 / -1; }
/* 6. 居中 */
.grid-center {
display: grid;
place-items: center; /* 简写:align-items + justify-items */
height: 300px;
background: #ecf0f1;
border-radius: 8px;
}
</style>
</head>
<body>
<!-- 1. 基本网格 -->
<div class="example">
<h2>1. 基本网格</h2>
<div class="basic-grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
</div>
<!-- 2. 响应式网格 -->
<div class="example">
<h2>2. 响应式网格(auto-fit + minmax)</h2>
<div class="responsive-grid">
<div class="grid-item">卡片 1</div>
<div class="grid-item">卡片 2</div>
<div class="grid-item">卡片 3</div>
<div class="grid-item">卡片 4</div>
<div class="grid-item">卡片 5</div>
</div>
</div>
<!-- 3. 经典布局 -->
<div class="example">
<h2>3. 经典布局</h2>
<div class="classic-layout">
<div class="grid-item header">Header</div>
<div class="grid-item sidebar">Sidebar</div>
<div class="grid-item main">Main Content</div>
<div class="grid-item footer">Footer</div>
</div>
</div>
<!-- 4. 瀑布流 -->
<div class="example">
<h2>4. 瀑布流布局</h2>
<div class="masonry">
<div class="grid-item item">1</div>
<div class="grid-item item">2</div>
<div class="grid-item item">3</div>
<div class="grid-item item">4</div>
<div class="grid-item item">5</div>
<div class="grid-item item">6</div>
</div>
</div>
<!-- 5. 居中 -->
<div class="example">
<h2>5. Grid 居中</h2>
<div class="grid-center">
<div class="grid-item">完美居中</div>
</div>
</div>
</body>
</html>
Grid 函数与关键字
.grid {
/* repeat() */
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(2, 100px 1fr);
/* minmax() */
grid-template-columns: minmax(200px, 1fr);
grid-template-columns: minmax(auto, 300px);
/* auto-fill 和 auto-fit */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* fr 单位 */
grid-template-columns: 1fr 2fr 1fr; /* 比例 1:2:1 */
/* min-content 和 max-content */
grid-template-columns: min-content 1fr max-content;
/* fit-content */
grid-template-columns: fit-content(200px) 1fr;
/* dense 填充算法 */
grid-auto-flow: dense;
}
过渡与动画
过渡(Transition)
/* 基本过渡 */
.box {
background: #3498db;
width: 100px;
height: 100px;
transition: all 0.3s ease;
}
.box:hover {
background: #e74c3c;
width: 200px;
height: 200px;
}
/* 分别指定过渡属性 */
.button {
background: #3498db;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
/* 详细写法 */
transition-property: background-color, transform, box-shadow;
transition-duration: 0.3s, 0.2s, 0.3s;
transition-timing-function: ease;
transition-delay: 0s;
/* 简写 */
/* transition: background-color 0.3s ease, transform 0.2s ease; */
}
.button:hover {
background: #2980b9;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.4);
}
/* 缓动函数 */
.ease { transition-timing-function: ease; }
.linear { transition-timing-function: linear; }
.ease-in { transition-timing-function: ease-in; }
.ease-out { transition-timing-function: ease-out; }
.ease-in-out { transition-timing-function: ease-in-out; }
.cubic { transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); }
/* 实用示例:卡片翻转 */
.flip-card {
perspective: 1000px;
width: 200px;
height: 300px;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
.flip-card:hover .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front, .flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
动画(Animation)
/* 定义关键帧 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-30px);
}
60% {
transform: translateY(-15px);
}
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* 应用动画 */
.fade-in {
animation: fadeIn 0.5s ease-in;
}
.slide-in {
animation: slideIn 0.5s ease-out;
}
.bounce {
animation: bounce 2s infinite;
}
.pulse {
animation: pulse 2s ease-in-out infinite;
}
.loader {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: rotate 1s linear infinite;
}
.skeleton {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
/* 动画属性详解 */
.animated-element {
animation-name: fadeIn;
animation-duration: 1s;
animation-timing-function: ease;
animation-delay: 0.5s;
animation-iteration-count: infinite; /* 1, 2, infinite */
animation-direction: alternate; /* normal, reverse, alternate, alternate-reverse */
animation-fill-mode: forwards; /* none, forwards, backwards, both */
animation-play-state: running; /* running, paused */
/* 简写 */
animation: fadeIn 1s ease 0.5s infinite alternate forwards;
}
/* 多个动画 */
.multi-animation {
animation:
fadeIn 0.5s ease,
slideIn 0.5s ease 0.3s,
pulse 2s ease-in-out 1s infinite;
}
/* 实用示例:打字效果 */
.typewriter {
overflow: hidden;
border-right: 2px solid;
white-space: nowrap;
animation:
typing 3s steps(30) forwards,
blink 0.7s step-end infinite;
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink {
50% { border-color: transparent; }
}
变换 Transform
/* 2D 变换 */
.transform-2d {
/* 平移 */
transform: translate(50px, 100px);
transform: translateX(50px);
transform: translateY(100px);
/* 旋转 */
transform: rotate(45deg);
transform: rotate(-30deg);
/* 缩放 */
transform: scale(1.5);
transform: scale(1.5, 2); /* scaleX, scaleY */
transform: scaleX(1.5);
/* 倾斜 */
transform: skew(10deg, 20deg);
transform: skewX(10deg);
/* 组合变换(从右到左应用) */
transform: translate(50px, 50px) rotate(45deg) scale(1.2);
}
/* 3D 变换 */
.transform-3d {
/* 需要设置透视 */
perspective: 1000px;
/* 3D 平移 */
transform: translate3d(50px, 50px, 100px);
transform: translateZ(100px);
/* 3D 旋转 */
transform: rotateX(45deg);
transform: rotateY(45deg);
transform: rotateZ(45deg);
transform: rotate3d(1, 1, 0, 45deg);
/* 3D 缩放 */
transform: scale3d(1.5, 1.5, 2);
transform: scaleZ(2);
/* 变换原点 */
transform-origin: center center;
transform-origin: 0 0;
transform-origin: 50% 50% 0;
/* 背面可见性 */
backface-visibility: visible; /* visible, hidden */
}
响应式设计
媒体查询
/* 基本媒体查询 */
@media screen and (max-width: 768px) {
body { font-size: 14px; }
}
@media screen and (min-width: 769px) and (max-width: 1024px) {
body { font-size: 16px; }
}
@media screen and (min-width: 1025px) {
body { font-size: 18px; }
}
/* 常用断点 */
/* 手机:< 576px */
/* 平板:576px - 768px */
/* 小桌面:769px - 1024px */
/* 大桌面:1025px - 1200px */
/* 超大:> 1200px */
/* 移动优先 */
.container {
width: 100%;
padding: 0 15px;
}
@media (min-width: 576px) {
.container { max-width: 540px; margin: 0 auto; }
}
@media (min-width: 768px) {
.container { max-width: 720px; }
}
@media (min-width: 1024px) {
.container { max-width: 960px; }
}
@media (min-width: 1200px) {
.container { max-width: 1140px; }
}
/* 响应式字体 */
html {
font-size: 14px;
}
@media (min-width: 576px) { html { font-size: 15px; } }
@media (min-width: 768px) { html { font-size: 16px; } }
@media (min-width: 1024px) { html { font-size: 17px; } }
/* 或使用 clamp() */
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
}
p {
font-size: clamp(0.875rem, 2vw, 1.125rem);
}
/* 容器查询 */
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: flex;
gap: 20px;
}
}
@container card (min-width: 600px) {
.card {
font-size: 1.125rem;
}
}
预处理器 Sass
变量与嵌套
// 变量
$primary-color: #3498db;
$secondary-color: #2ecc71;
$font-stack: 'Segoe UI', Arial, sans-serif;
$border-radius: 8px;
$spacing: 16px;
// 嵌套
.navbar {
background: $primary-color;
padding: $spacing;
.logo {
font-size: 24px;
font-weight: bold;
}
.nav-links {
display: flex;
gap: $spacing;
a {
color: white;
text-decoration: none;
&:hover {
text-decoration: underline;
}
&.active {
font-weight: bold;
}
}
}
}
// 父选择器 &
.button {
background: $primary-color;
color: white;
&--primary { background: $primary-color; }
&--secondary { background: $secondary-color; }
&--disabled { opacity: 0.5; cursor: not-allowed; }
&:hover { opacity: 0.9; }
&:active { transform: scale(0.98); }
}
Mixin 与函数
// Mixin
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
@mixin responsive($breakpoint) {
@if $breakpoint == sm {
@media (min-width: 576px) { @content; }
} @else if $breakpoint == md {
@media (min-width: 768px) { @content; }
} @else if $breakpoint == lg {
@media (min-width: 1024px) { @content; }
}
}
@mixin truncate($lines: 1) {
@if $lines == 1 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} @else {
display: -webkit-box;
-webkit-line-clamp: $lines;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
// 使用
.hero {
@include flex-center;
height: 100vh;
background: linear-gradient(135deg, $primary-color, $secondary-color);
h1 {
font-size: 2rem;
@include responsive(md) {
font-size: 3rem;
}
}
}
.card-title {
@include truncate(2);
}
// 函数
@function calculate-width($col, $total: 12) {
@return percentage($col / $total);
}
.col-6 { width: calculate-width(6); }
.col-4 { width: calculate-width(4); }
.col-3 { width: calculate-width(3); }
// 循环
@for $i from 1 through 12 {
.col-#{$i} {
width: calculate-width($i);
}
}
继承与导入
// 继承 %placeholder
%message-shared {
padding: 10px 15px;
border-radius: 4px;
margin-bottom: 10px;
}
.success { @extend %message-shared; background: #d4edda; color: #155724; }
.error { @extend %message-shared; background: #f8d7da; color: #721c24; }
.warning { @extend %message-shared; background: #fff3cd; color: #856404; }
// 模块化
// _variables.scss
// _mixins.scss
// _reset.scss
// main.scss
@import 'variables';
@import 'mixins';
@import 'reset';
实战项目
项目:响应式产品展示页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品展示页面</title>
<style>
/* CSS 变量 */
:root {
--primary: #6c5ce7;
--primary-dark: #5a4bd1;
--text: #2d3436;
--text-light: #636e72;
--bg: #f8f9fa;
--white: #ffffff;
--shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
--radius: 12px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; color: var(--text); background: var(--bg); }
/* 容器 */
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 导航 */
.navbar {
background: var(--white);
box-shadow: var(--shadow);
position: sticky;
top: 0;
z-index: 100;
}
.navbar .container {
display: flex;
align-items: center;
justify-content: space-between;
height: 70px;
}
.navbar .logo {
font-size: 24px;
font-weight: 800;
color: var(--primary);
text-decoration: none;
}
.navbar .nav-links {
display: flex;
gap: 30px;
list-style: none;
}
.navbar .nav-links a {
color: var(--text);
text-decoration: none;
font-weight: 500;
transition: var(--transition);
}
.navbar .nav-links a:hover { color: var(--primary); }
/* Hero */
.hero {
padding: 100px 0;
text-align: center;
background: linear-gradient(135deg, #6c5ce7 0%, #a29bfe 100%);
color: white;
}
.hero h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
margin-bottom: 20px;
}
.hero p {
font-size: clamp(1rem, 2vw, 1.25rem);
opacity: 0.9;
max-width: 600px;
margin: 0 auto 30px;
}
.hero .cta-button {
display: inline-block;
padding: 15px 40px;
background: white;
color: var(--primary);
border-radius: 50px;
font-size: 18px;
font-weight: 600;
text-decoration: none;
transition: var(--transition);
}
.hero .cta-button:hover {
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
/* 产品网格 */
.products { padding: 80px 0; }
.products h2 {
text-align: center;
font-size: 2.5rem;
margin-bottom: 50px;
}
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
}
.product-card {
background: var(--white);
border-radius: var(--radius);
overflow: hidden;
box-shadow: var(--shadow);
transition: var(--transition);
}
.product-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.product-card .image {
height: 200px;
background: linear-gradient(135deg, #a29bfe, #6c5ce7);
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
}
.product-card .info { padding: 25px; }
.product-card .info h3 { font-size: 1.25rem; margin-bottom: 10px; }
.product-card .info p { color: var(--text-light); line-height: 1.6; margin-bottom: 15px; }
.product-card .price {
font-size: 1.5rem;
font-weight: 700;
color: var(--primary);
}
/* 特性 */
.features { padding: 80px 0; background: var(--white); }
.features h2 { text-align: center; font-size: 2.5rem; margin-bottom: 50px; }
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 40px;
}
.feature-item {
text-align: center;
padding: 30px;
}
.feature-item .icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary), #a29bfe);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 36px;
margin: 0 auto 20px;
}
.feature-item h3 { margin-bottom: 10px; }
.feature-item p { color: var(--text-light); line-height: 1.6; }
/* Footer */
.footer {
background: var(--text);
color: white;
padding: 60px 0 30px;
}
.footer-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 40px;
margin-bottom: 40px;
}
.footer h3 { margin-bottom: 20px; }
.footer a { color: #b2bec3; text-decoration: none; display: block; margin-bottom: 10px; }
.footer a:hover { color: white; }
.footer-bottom {
text-align: center;
padding-top: 30px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
color: #b2bec3;
}
/* 响应式 */
@media (max-width: 768px) {
.navbar .nav-links { display: none; }
.hero { padding: 60px 0; }
.products, .features { padding: 50px 0; }
}
</style>
</head>
<body>
<nav class="navbar">
<div class="container">
<a href="#" class="logo">🛍️ ShopUI</a>
<ul class="nav-links">
<li><a href="#">首页</a></li>
<li><a href="#">产品</a></li>
<li><a href="#">关于我们</a></li>
<li><a href="#">联系</a></li>
</ul>
</div>
</nav>
<section class="hero">
<div class="container">
<h1>发现精选好物</h1>
<p>我们精选全球优质产品,为您带来极致的购物体验</p>
<a href="#products" class="cta-button">开始选购</a>
</div>
</section>
<section class="products" id="products">
<div class="container">
<h2>热门产品</h2>
<div class="product-grid">
<div class="product-card">
<div class="image">🎧</div>
<div class="info">
<h3>无线降噪耳机</h3>
<p>主动降噪技术,40小时续航,佩戴舒适</p>
<span class="price">¥899</span>
</div>
</div>
<div class="product-card">
<div class="image">⌚</div>
<div class="info">
<h3>智能手表 Pro</h3>
<p>健康监测、运动追踪、消息提醒一应俱全</p>
<span class="price">¥1,299</span>
</div>
</div>
<div class="product-card">
<div class="image">📱</div>
<div class="info">
<h3>折叠屏手机</h3>
<p>创新折叠设计,展开即平板,折叠便携</p>
<span class="price">¥6,999</span>
</div>
</div>
</div>
</div>
</section>
<section class="features">
<div class="container">
<h2>我们的优势</h2>
<div class="feature-grid">
<div class="feature-item">
<div class="icon">🚚</div>
<h3>免费配送</h3>
<p>全场满99元免运费,全国范围配送</p>
</div>
<div class="feature-item">
<div class="icon">🔒</div>
<h3>安全支付</h3>
<p>支持多种支付方式,资金安全保障</p>
</div>
<div class="feature-item">
<div class="icon">↩️</div>
<h3>无忧退换</h3>
<p>7天无理由退换,让您购物无后顾之忧</p>
</div>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div>
<h3>关于我们</h3>
<p style="color: #b2bec3; line-height: 1.6;">致力于为用户提供最优质的产品和最贴心的服务</p>
</div>
<div>
<h3>产品</h3>
<a href="#">电子产品</a>
<a href="#">生活用品</a>
<a href="#">服饰配件</a>
</div>
<div>
<h3>帮助</h3>
<a href="#">常见问题</a>
<a href="#">配送说明</a>
<a href="#">退换政策</a>
</div>
<div>
<h3>联系</h3>
<a href="#">service@example.com</a>
<a href="#">400-123-4567</a>
</div>
</div>
<div class="footer-bottom">
<p>© 2024 ShopUI. All rights reserved.</p>
</div>
</div>
</footer>
</body>
</html>
常见问题与解决方案
Q1: Flexbox 和 Grid 如何选择?
- Flexbox:一维布局,适合行或列方向的布局
- Grid:二维布局,适合同时控制行和列
- 实际开发中常结合使用
Q2: 如何实现 CSS 动画性能优化?
/* 使用 transform 和 opacity 做动画,避免触发重排 */
/* 好的做法 */
.animate { transition: transform 0.3s, opacity 0.3s; }
/* 不好的做法 */
/* transition: width 0.3s, height 0.3s; 触发重排 */
/* 使用 will-change 提示浏览器 */
.optimized { will-change: transform; }
Q3: 响应式图片如何处理?
img {
max-width: 100%;
height: auto;
object-fit: cover; /* cover, contain, fill */
}
Q4: 如何处理浏览器兼容性?
/* 使用 @supports 检测特性支持 */
@supports (display: grid) {
.layout { display: grid; }
}
@supports not (display: grid) {
.layout { display: flex; }
}
/* 使用 autoprefixer 自动添加前缀 */
总结
CSS3 为 Web 开发带来了革命性的变化。掌握这些核心特性将帮助你构建现代化、响应式的网页:
- 选择器:更精确地定位元素
- 盒模型:理解 border-box 的重要性
- Flexbox:一维布局的首选方案
- Grid:二维布局的强大工具
- 过渡与动画:增强用户体验
- 响应式设计:适配各种设备
- Sass:提高 CSS 开发效率
建议通过实际项目来巩固所学知识,逐步探索更多高级特性。