五、CSS盒模型
CSS盒模型是CSS布局的基础,描述了元素在网页上占据空间的方式。理解盒模型对于准确控制元素尺寸和布局至关重要。
盒模型组成
每个HTML元素在页面上都被表示为一个矩形盒子,这个盒子由以下部分组成:
1. 内容区域(Content)
包含元素的实际内容,如文本、图像或其他媒体。内容区域的尺寸由width和height属性定义。
div {
/* 设置内容区域大小 */
width: 300px;
height: 200px;
}
2. 内边距(Padding)
内容区域与边框之间的空间。内边距清除了内容周围的区域,是盒子内部的空白。
div {
/* 设置四个方向的内边距 */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
/* 简写形式 */
padding: 10px 20px; /* 上下10px, 左右20px */
/* 另一种简写形式 */
padding: 10px 20px 15px 25px; /* 上、右、下、左 (顺时针) */
}
3. 边框(Border)
围绕内容和内边距的线条。边框可以有不同的样式、宽度和颜色。
div {
/* 完整的边框属性 */
border-width: 2px;
border-style: solid;
border-color: #333;
/* 简写形式 */
border: 2px solid #333;
/* 单一边的边框设置 */
border-top: 1px dotted red;
border-right: 2px dashed blue;
border-bottom: 3px double green;
border-left: 4px groove orange;
/* 圆角边框 */
border-radius: 8px; /* 所有角都是8px */
border-radius: 8px 4px 12px 0; /* 左上、右上、右下、左下 */
}
4. 外边距(Margin)
盒子与其他元素之间的空间。外边距是透明的,不会影响盒子的背景色。
div {
/* 设置四个方向的外边距 */
margin-top: 20px;
margin-right: 15px;
margin-bottom: 20px;
margin-left: 15px;
/* 简写形式 */
margin: 20px 15px; /* 上下20px, 左右15px */
/* 另一种简写形式 */
margin: 20px 15px 30px 10px; /* 上、右、下、左 (顺时针) */
/* 自动居中 */
margin: 0 auto; /* 上下为0, 左右自动计算使元素居中 */
/* 负外边距(可用于特殊布局效果) */
margin-top: -10px;
}
盒模型类型
CSS有两种盒模型类型,它们计算元素总宽度和高度的方式不同。
1. 标准盒模型
在标准盒模型中,width和height仅定义内容区域的尺寸,不包括内边距、边框和外边距。
元素总宽度 = width + padding-left + padding-right + border-left + border-right
元素总高度 = height + padding-top + padding-bottom + border-top + border-bottom
.box-standard {
box-sizing: content-box; /* 标准盒模型(默认) */
width: 300px;
height: 200px;
padding: 20px;
border: 10px solid black;
margin: 30px;
/* 实际宽度 = 300px + 20px*2 + 10px*2 = 360px */
/* 实际高度 = 200px + 20px*2 + 10px*2 = 260px */
}
2. 替代盒模型(IE盒模型)
在替代盒模型中,width和height包含内容区域、内边距和边框,但不包括外边距。
元素总宽度 = width(包含内容、内边距和边框)
元素总高度 = height(包含内容、内边距和边框)
.box-alternative {
box-sizing: border-box; /* 替代盒模型 */
width: 300px;
height: 200px;
padding: 20px;
border: 10px solid black;
margin: 30px;
/* 内容宽度 = 300px - 20px*2 - 10px*2 = 240px */
/* 内容高度 = 200px - 20px*2 - 10px*2 = 140px */
/* 实际宽度 = 300px (已经包含内边距和边框) */
/* 实际高度 = 200px (已经包含内边距和边框) */
}
3. 全局设置盒模型
通常,为了一致性和易用性,开发者会在整个项目中使用替代盒模型:
/* 应用替代盒模型到所有元素 */
* {
box-sizing: border-box;
}
/* 或更精细的设置 */
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
盒模型特性与技巧
1. 外边距合并
垂直方向上相邻元素的外边距会合并(取最大值),而不是累加。
/* 示例 */
.paragraph1 {
margin-bottom: 20px;
}
.paragraph2 {
margin-top: 30px;
}
/* 两段落之间的实际间距是30px,而不是50px */
解决方法:
- 使用内边距代替外边距
- 为一个元素添加边框或内边距
- 使用不同的布局上下文(如flexbox)
2. 百分比值
在盒模型中,百分比值的参考是不同的:
-
width百分比基于父元素的内容宽度 -
height百分比基于父元素的内容高度 -
padding和margin的百分比基于父元素的宽度
.parent {
width: 400px;
}
.child {
width: 50%; /* 200px (父元素宽度的50%) */
padding: 10%; /* 40px (父元素宽度的10%) */
margin-top: 5%; /* 20px (父元素宽度的5%) */
}
3. 最大和最小尺寸
可以设置元素尺寸的上下限,对于响应式设计非常有用:
.responsive-element {
width: 70%;
min-width: 300px; /* 至少300px宽 */
max-width: 800px; /* 最多800px宽 */
height: auto;
min-height: 200px; /* 至少200px高 */
max-height: 600px; /* 最多600px高 */
}
4. 溢出控制
当内容超出元素的内容区域时,可以控制其行为:
.container {
width: 300px;
height: 200px;
/* 溢出内容被隐藏 */
overflow: hidden;
/* 显示滚动条(仅在需要时) */
overflow: auto;
/* 始终显示滚动条 */
overflow: scroll;
/* 默认行为,内容溢出盒子 */
overflow: visible;
/* 分别控制水平和垂直方向 */
overflow-x: hidden;
overflow-y: auto;
}
5. 盒阴影
为元素添加阴影效果,不占用空间(不影响盒模型):
.shadow-box {
/* 水平偏移, 垂直偏移, 模糊半径, 扩散半径, 颜色 */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
/* 多个阴影 */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2),
0 8px 16px rgba(0, 0, 0, 0.1);
/* 内阴影 */
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
}
盒模型实践应用
1. 创建卡片组件
.card {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin: 15px;
background-color: white;
}
.card__title {
margin-top: 0;
margin-bottom: 10px;
}
.card__content {
margin-bottom: 0;
}
2. 固定宽高比容器
使用内边距技巧创建具有固定宽高比的容器:
.aspect-ratio-box {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 宽高比 (9/16 = 0.5625) */
overflow: hidden;
}
.aspect-ratio-box-content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
/* 其他常见的宽高比 */
.ratio-square {
padding-top: 100%; /* 1:1 */
}
.ratio-4-3 {
padding-top: 75%; /* 4:3 */
}
3. 间距系统
使用盒模型创建一致的间距系统:
/* 间距工具类 */
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 0.25rem; } /* 4px 假设 1rem = 16px */
.mb-2 { margin-bottom: 0.5rem; } /* 8px */
.mb-3 { margin-bottom: 1rem; } /* 16px */
.mb-4 { margin-bottom: 1.5rem; } /* 24px */
.mb-5 { margin-bottom: 3rem; } /* 48px */
/* 内边距工具类 */
.p-0 { padding: 0; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-3 { padding: 1rem; }
.p-4 { padding: 1.5rem; }
.p-5 { padding: 3rem; }
/* 组合使用 */
<div class="card p-3 mb-4">
Card with padding inside and margin bottom
</div>
4. 溢出容器与截断文本
/* 固定高度容器,超出显示滚动条 */
.scroll-container {
height: 300px;
overflow-y: auto;
padding: 15px;
border: 1px solid #ddd;
}
/* 单行文本截断,显示省略号 */
.text-truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 多行文本截断 */
.text-truncate-multiline {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
5. 自定义滚动条
/* 自定义滚动条 */
.custom-scrollbar {
/* 滚动条宽度 */
scrollbar-width: thin; /* Firefox */
}
/* 对于Webkit浏览器 */
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: #f1f1f1;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: #555;
}
六、布局技术
CSS布局技术用于控制网页中元素的排列和定位方式。随着Web技术的发展,CSS布局系统已经从简单的文档流发展到复杂的弹性和网格系统。
传统布局方法
1. 正常文档流
默认情况下,HTML元素按照它们在文档中出现的顺序从上到下、从左到右排列。
块级元素(如div, p, h1-h6, ul, li等):
- 独占一行
- 默认宽度为父容器的100%
- 可以设置宽度、高度、内边距和外边距
内联元素(如span, a, strong, em等):
- 在一行内显示
- 宽度由内容决定
- 无法设置宽度和高度
- 水平方向的内边距和外边距有效,垂直方向无效
/* 块级元素 */
.block {
display: block;
width: 80%;
margin: 20px auto;
padding: 15px;
background-color: #f0f0f0;
}
/* 内联元素 */
.inline {
display: inline;
color: blue;
padding: 0 5px; /* 只有水平内边距有效 */
margin: 0 10px; /* 只有水平外边距有效 */
background-color: yellow; /* 背景只覆盖内容区域和内边距 */
}
/* 内联块元素 */
.inline-block {
display: inline-block; /* 结合内联和块级特性 */
width: 200px;
height: 100px;
padding: 10px;
vertical-align: middle;
background-color: lightgreen;
}
2. 浮动(Float)
浮动最初是为了实现文本环绕图片而设计的,后来被用于创建多列布局。
/* 基本浮动 */
.float-left {
float: left;
width: 200px;
margin-right: 20px;
}
.float-right {
float: right;
width: 200px;
margin-left: 20px;
}
/* 清除浮动 */
.clear {
clear: both; /* 也可以是 left 或 right */
}
/* 包含浮动(防止容器塌陷) */
.clearfix::after {
content: "";
display: block;
clear: both;
}
浮动布局示例:创建三列布局
.column {
float: left;
width: 33.33%;
padding: 15px;
box-sizing: border-box;
}
.row::after {
content: "";
display: table;
clear: both;
}
<div class="row">
<div class="column">列 1</div>
<div class="column">列 2</div>
<div class="column">列 3</div>
</div>
使用场景:
- 文本环绕图片或其他元素
- 简单的多列布局
- 传统网格系统
缺点:
- 脱离正常文档流,容易导致布局问题
- 需要清除浮动以防止容器崩塌
- 难以创建复杂的等高列布局
- 响应式设计实现较复杂
3. 定位(Position)
定位属性允许精确控制元素在页面上的位置。
position属性值:
a. static(默认值)
元素按照正常文档流定位,top, right, bottom, left属性无效。
.static {
position: static;
}
b. relative(相对定位)
相对于元素正常位置进行定位,不脱离文档流。
.relative {
position: relative;
top: 20px;
left: 30px; /* 相对于原位置向下20px、向右30px */
}
使用场景:
- 微调元素位置
- 创建绝对定位元素的定位上下文
- 在不影响其他元素布局的情况下移动元素
c. absolute(绝对定位)
相对于最近的非static定位祖先元素进行定位,脱离文档流。
.container {
position: relative; /* 创建定位上下文 */
width: 500px;
height: 300px;
}
.absolute {
position: absolute;
top: 20px;
right: 30px; /* 距离容器顶部20px、右侧30px */
width: 100px;
height: 100px;
}
使用场景:
- 创建弹出层、模态框
- 精确定位元素
- 创建重叠元素
- 实现复杂的UI组件(如下拉菜单、工具提示)
d. fixed(固定定位)
相对于视口(浏览器窗口)进行定位,即使页面滚动也保持位置不变。
.fixed-header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background-color: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
z-index: 100;
}
.fixed-button {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: blue;
color: white;
}
使用场景:
- 固定导航栏
- 返回顶部按钮
- 始终可见的聊天窗口
- 固定的侧边栏
e. sticky(粘性定位)
基于用户滚动位置定位。元素在跨越特定阈值前为相对定位,之后为固定定位。
.sticky-header {
position: sticky;
top: 0; /* 当元素距离视口顶部为0px时变为固定定位 */
background-color: white;
padding: 10px;
border-bottom: 1px solid #ddd;
z-index: 10;
}
使用场景:
- 在滚动时固定的表头
- 吸顶导航
- 滚动到一定位置固定的元素
4. z-index和堆叠上下文
z-index属性控制元素在Z轴上的位置(即重叠元素的堆叠顺序)。
.back {
position: relative;
z-index: 1;
}
.middle {
position: absolute;
z-index: 2;
}
.front {
position: absolute;
z-index: 3; /* 值越大,越靠前显示 */
}
堆叠上下文:
某些CSS属性会创建新的堆叠上下文,影响子元素的z-index行为。
创建堆叠上下文的常见情况:
- 元素具有非
static的position值且设置了z-index - 元素设置了
opacity小于1 - 元素设置了
transform,filter,will-change等属性
.stacking-context {
position: relative;
z-index: 1;
/* 创建新的堆叠上下文 */
}
.stacking-context .child {
position: absolute;
z-index: 999; /* 只在父元素创建的堆叠上下文中比较 */
}
现代布局方法
1. 弹性盒子(Flexbox)
Flexbox是一维布局系统,设计用于沿一个轴线(主轴或交叉轴)分配空间和对齐项目。
a. 基本概念
-
Flex容器:应用
display: flex的元素 - Flex项目:Flex容器的直接子元素
-
主轴:默认为水平方向,由
flex-direction定义 - 交叉轴:与主轴垂直的轴
b. 容器属性
.flex-container {
display: flex; /* 或 display: inline-flex; */
/* 主轴方向 */
flex-direction: row; /* 默认值,从左到右 */
/* 其他可选值: row-reverse, column, column-reverse */
/* 是否换行 */
flex-wrap: nowrap; /* 默认值,不换行 */
/* 其他可选值: wrap, wrap-reverse */
/* flex-direction 和 flex-wrap 的简写 */
flex-flow: row nowrap;
/* 主轴对齐方式 */
justify-content: flex-start; /* 默认值,左对齐 */
/* 其他可选值: flex-end, center, space-between, space-around, space-evenly */
/* 交叉轴对齐方式 */
align-items: stretch; /* 默认值,拉伸填满 */
/* 其他可选值: flex-start, flex-end, center, baseline */
/* 多行交叉轴对齐 */
align-content: stretch; /* 默认值 */
/* 其他可选值: flex-start, flex-end, center, space-between, space-around */
}
c. 项目属性
.flex-item {
/* 顺序,数值越小越靠前 */
order: 0; /* 默认值 */
/* 放大比例,默认为0(不放大) */
flex-grow: 0;
/* 缩小比例,默认为1(允许缩小) */
flex-shrink: 1;
/* 初始大小,可以是长度值、百分比或auto */
flex-basis: auto;
/* flex-grow, flex-shrink, flex-basis的简写 */
flex: 0 1 auto; /* 默认值 */
/* 常见预设: flex: 1; (1 1 0%) 可自适应空间 */
/* 单个项目的交叉轴对齐方式,覆盖align-items */
align-self: auto; /* 默认值,继承容器的align-items */
/* 其他可选值: flex-start, flex-end, center, baseline, stretch */
}
d. 常见Flexbox布局模式
均匀分布的导航:
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 60px;
background-color: #333;
}
.nav-links {
display: flex;
gap: 20px; /* 现代浏览器支持 */
}
卡片网格:
.card-grid {
display: flex;
flex-wrap: wrap;
margin: -10px; /* 抵消卡片外边距 */
}
.card {
flex: 0 0 calc(33.333% - 20px); /* 三列布局 */
margin: 10px;
padding: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* 响应式调整 */
@media (max-width: 768px) {
.card {
flex: 0 0 calc(50% - 20px); /* 平板上两列 */
}
}
@media (max-width: 480px) {
.card {
flex: 0 0 calc(100% - 20px); /* 手机上单列 */
}
}
圣杯布局:
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.holy-grail__header,
.holy-grail__footer {
flex: 0 0 auto;
padding: 20px;
}
.holy-grail__main {
display: flex;
flex: 1 0 auto; /* 占用所有剩余空间 */
}
.holy-grail__content {
flex: 1 0 auto; /* 中间区域扩展 */
padding: 20px;
}
.holy-grail__nav,
.holy-grail__aside {
flex: 0 0 200px; /* 固定宽度侧边栏 */
padding: 20px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.holy-grail__main {
flex-direction: column;
}
.holy-grail__nav,
.holy-grail__aside {
flex: 0 0 auto;
}
}
垂直和水平居中:
.center-container {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
background-color: #f5f5f5;
}
.center-item {
width: 200px;
height: 200px;
background-color: #3498db;
}
2. 网格布局(Grid)
CSS Grid是二维布局系统,专为排列行和列而设计,可以创建复杂的布局结构。
a. 基本概念
-
Grid容器:应用
display: grid的元素 - Grid项目:Grid容器的直接子元素
- Grid线:定义网格结构的线,包括行线和列线
- Grid单元格:两条相邻行线和列线之间的空间
- Grid轨道:两条相邻网格线之间的行或列
b. 容器属性
.grid-container {
display: grid; /* 或 display: inline-grid; */
/* 定义列 */
grid-template-columns: 100px 200px auto;
/* 或使用重复函数: repeat(3, 1fr); */
/* 定义行 */
grid-template-rows: 100px auto 100px;
/* 定义网格间隙 */
column-gap: 20px; /* 列间隙 */
row-gap: 20px; /* 行间隙 */
gap: 20px; /* 行和列间隙的简写 */
/* 网格线命名 */
grid-template-columns: [start] 1fr [middle] 2fr [end];
/* 网格区域命名 */
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
/* 项目对齐(水平) */
justify-items: stretch; /* 默认值 */
/* 其他可选值: start, end, center */
/* 项目对齐(垂直) */
align-items: stretch; /* 默认值 */
/* 其他可选值: start, end, center */
/* 轨道对齐(当网格小于容器时) */
justify-content: start; /* 默认值 */
align-content: start; /* 默认值 */
/* 其他可选值: end, center, space-between, space-around, space-evenly */
/* 自动放置算法 */
grid-auto-flow: row; /* 默认值 */
/* 其他可选值: column, row dense, column dense */
/* 自动创建的轨道大小 */
grid-auto-rows: auto;
grid-auto-columns: auto;
}
c. 项目属性
.grid-item {
/* 指定项目位置 */
grid-column-start: 1;
grid-column-end: 3; /* 或 span 2 */
grid-row-start: 1;
grid-row-end: 2;
/* 简写形式 */
grid-column: 1 / 3; /* 或 1 / span 2 */
grid-row: 1 / 2;
/* 更简洁的简写 */
grid-area: 1 / 1 / 2 / 3; /* 行开始/列开始/行结束/列结束 */
/* 使用命名区域 */
grid-area: header;
/* 单个项目对齐(水平) */
justify-self: stretch; /* 默认值 */
/* 其他可选值: start, end, center */
/* 单个项目对齐(垂直) */
align-self: stretch; /* 默认值 */
/* 其他可选值: start, end, center */
}
d. 特殊单位与函数
fr单位:弹性长度单位,用于分配剩余空间。
.grid {
grid-template-columns: 1fr 2fr 1fr; /* 比例为1:2:1 */
}
minmax()函数:定义最小和最大尺寸范围。
.grid {
grid-template-columns: minmax(100px, 1fr) 3fr;
}
repeat()函数:重复轨道定义。
.grid {
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 100px 200px); /* 重复模式 */
}
auto-fill & auto-fit:根据容器大小自动计算轨道数量。
.responsive-grid {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.responsive-grid-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
e. 常见Grid布局模式
基本网格布局:
.basic-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
杂志布局:
.magazine-layout {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
gap: 20px;
}
.feature-article {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
.sidebar {
grid-column: 3 / 5;
}
.regular-article {
grid-column: span 2;
}
响应式图片画廊:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-auto-rows: 200px;
gap: 20px;
}
.gallery-item {
overflow: hidden;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.gallery-item img:hover {
transform: scale(1.1);
}
.gallery-item--featured {
grid-column: span 2;
grid-row: span 2;
}
经典布局:
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* 响应式调整 */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
高级布局技术
1. 多列布局(Column Layout)
CSS列布局用于创建类似报纸的多列文本,可以按列分配内容并自动平衡。
.multi-column {
column-count: 3; /* 指定列数 */
column-width: 200px; /* 指定列宽 */
/* 列间隙 */
column-gap: 30px;
/* 列间分隔线 */
column-rule: 1px solid #ddd;
/* 避免元素跨列分割 */
break-inside: avoid;
}
/* 使元素横跨所有列 */
.multi-column h2 {
column-span: all;
margin-bottom: 1em;
}
使用场景:
- 文本密集型内容(如文章、新闻)
- 创建杂志风格布局
- 表单或列表分组
2. 表格布局
虽然不推荐使用表格进行页面布局,但CSS display: table 属性系列可以用于特定场景。
.table-layout {
display: table;
width: 100%;
}
.table-row {
display: table-row;
}
.table-cell {
display: table-cell;
padding: 10px;
vertical-align: middle;
}
使用场景:
- 需要垂直居中且不知道高度的内容
- 需要同时设置多个元素高度相等
- 兼容旧版浏览器
3. 内在Web设计(Intrinsic Web Design)
混合使用多种布局技术,根据内容自然尺寸和行为设计布局。
.intrinsic-layout {
display: grid;
grid-template-columns: auto minmax(min-content, 1fr) auto;
align-items: start;
}
.sidebar {
width: clamp(200px, 25vw, 300px);
}
.content {
display: flex;
flex-direction: column;
min-width: min-content;
}
.fluid-type {
font-size: clamp(1rem, 2vw + 0.5rem, 1.5rem);
}
特点:
- 使用
min-content、max-content控制尺寸 - 结合Grid、Flexbox创建响应式布局
- 利用
clamp()函数设置流体尺寸 - 减少媒体查询依赖
4. 子网格(Subgrid)
较新的CSS Grid功能,允许网格项目继承父网格的轨道定义。
.parent-grid {
display: grid;
grid-template-columns: repeat(9, 1fr);
gap: 10px;
}
.nested-grid {
grid-column: 2 / 7;
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
使用场景:
- 创建复杂的嵌套布局
- 保持嵌套元素与父元素对齐
- 表单布局对齐
5. 容器查询(Container Queries)
基于容器大小而非视口大小进行样式调整的新技术(浏览器支持正在增加)。
.container {
container-type: inline-size;
container-name: card-container;
}
@container card-container (min-width: 400px) {
.card {
display: flex;
}
.card-image {
flex: 0 0 200px;
}
}
@container card-container (max-width: 399px) {
.card {
flex-direction: column;
}
.card-image {
width: 100%;
height: auto;
}
}
优势:
- 基于组件容器大小而非整个视口响应式设计
- 更好的组件封装性
- 相同组件在不同上下文中可以有不同表现
布局最佳实践
1. 移动优先设计
从小屏幕设计开始,然后逐步为更大屏幕扩展功能。
/* 基础样式(移动设备) */
.container {
display: flex;
flex-direction: column;
}
/* 平板及以上 */
@media (min-width: 768px) {
.container {
flex-direction: row;
}
}
/* 桌面 */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}
2. 混合布局策略
根据需要组合使用不同的布局技术。
.page {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header, .footer {
padding: 20px;
}
.main {
display: flex;
flex-wrap: wrap;
padding: 20px;
}
.article {
flex: 1 300px;
margin: 10px;
}
.article-content {
column-count: 2;
column-gap: 20px;
}
3. 可访问性考虑
确保布局不会影响内容的可访问性。
/* 提供跳过导航的链接 */
.skip-link {
position: absolute;
top: -40px;
left: 0;
padding: 8px;
background-color: #000;
color: #fff;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
/* 确保键盘焦点可见 */
:focus {
outline: 2px solid blue;
outline-offset: 2px;
}
/* 考虑减少动画运动 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
4. 性能优化
选择高效的布局方法,减少布局抖动和回流。
/* 使用transform而非调整位置属性,减少回流 */
.animated {
transform: translateX(100px);
transition: transform 0.3s ease;
}
/* 使用opacity和transform进行动画,减少布局计算 */
.modal {
opacity: 0;
transform: scale(0.95);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.modal.active {
opacity: 1;
transform: scale(1);
}
/* 预先设定图像尺寸,减少布局移动 */
.image {
width: 100%;
aspect-ratio: 16 / 9;
background-color: #f0f0f0; /* 占位色 */
}
5. 内容优先
让内容决定布局,而不是强制内容适应固定布局。
/* 根据内容量自动调整网格项目大小 */
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 20px;
}
/* 使用fit-content根据内容设置宽度 */
.content-width {
width: fit-content;
max-width: 100%;
}
/* 使用min-content和max-content控制宽度 */
.sidebar {
width: min-content;
}
.expandable {
width: max-content;
max-width: 100%;
}
七、响应式设计
响应式Web设计是一种使网页内容能够适应不同设备和屏幕尺寸的方法。它使同一个网站能够在桌面、平板和手机等设备上提供最佳的查看和交互体验。
媒体查询
媒体查询是响应式设计的核心技术,允许根据设备特性(如屏幕宽度、高度、方向等)应用不同的CSS样式。
1. 基本语法
@media media-type and (media-feature) {
/* CSS规则 */
}
媒体类型(media-type):
-
all- 所有设备 -
screen- 计算机屏幕、平板和智能手机 -
print- 打印预览模式/打印页面 -
speech- 屏幕阅读器
媒体特性(media-feature):
-
width,min-width,max-width- 视口宽度 -
height,min-height,max-height- 视口高度 -
orientation- 设备方向(portrait或landscape) -
aspect-ratio- 视口宽高比 -
resolution- 设备分辨率 -
color- 颜色位数 -
hover- 设备是否支持悬停 -
pointer- 指针精度(none, coarse, fine)
2. 常见断点和用法
/* 基础样式(适用于所有设备) */
body {
font-size: 16px;
line-height: 1.5;
}
/* 小屏设备(手机,768px以下) */
@media screen and (max-width: 767px) {
body {
font-size: 14px;
}
.container {
padding: 10px;
}
}
/* 中等屏幕设备(平板,768px-1023px) */
@media screen and (min-width: 768px) and (max-width: 1023px) {
.container {
padding: 20px;
max-width: 750px;
margin: 0 auto;
}
}
/* 大屏设备(桌面,1024px及以上) */
@media screen and (min-width: 1024px) {
.container {
padding: 30px;
max-width: 1140px;
margin: 0 auto;
}
}
3. 移动优先与桌面优先
移动优先策略:
先为移动设备编写基础样式,然后通过min-width媒体查询逐步增强桌面版样式。
/* 基础样式(适用于移动设备) */
.nav {
display: flex;
flex-direction: column;
}
.nav-item {
padding: 10px;
border-bottom: 1px solid #eee;
}
/* 平板及以上的样式增强 */
@media (min-width: 768px) {
.nav {
flex-direction: row;
justify-content: space-between;
}
.nav-item {
border-bottom: none;
}
}
桌面优先策略:
先为桌面设备编写完整样式,然后通过max-width媒体查询针对小屏幕进行简化。
/* 基础样式(适用于桌面设备) */
.nav {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.nav-item {
padding: 15px;
}
/* 针对移动设备的样式调整 */
@media (max-width: 767px) {
.nav {
flex-direction: column;
}
.nav-item {
padding: 10px;
border-bottom: 1px solid #eee;
}
}
4. 复合媒体查询
可以组合多个媒体特性以创建更精确的条件。
/* 针对横屏的平板设备 */
@media (min-width: 768px) and (max-width: 1023px) and (orientation: landscape) {
.sidebar {
display: flex;
flex-direction: row;
}
}
/* 针对高分辨率屏幕 */
@media (min-width: 1200px) and (min-resolution: 192dpi) {
.hero-image {
background-image: url('hero-large@2x.jpg');
}
}
/* 针对不支持悬停的触摸设备 */
@media (hover: none) and (pointer: coarse) {
.button {
padding: 12px 20px; /* 更大的触摸目标 */
}
.dropdown:hover .dropdown-menu {
display: none; /* 禁用悬停展开菜单 */
}
}
5. 媒体查询在<link>标签中的应用
可以在HTML中使用媒体查询有条件地加载不同的样式表。
<!-- 所有设备的基础样式 -->
<link rel="stylesheet" href="base.css">
<!-- 平板设备的样式 -->
<link rel="stylesheet" href="tablet.css" media="screen and (min-width: 768px) and (max-width: 1023px)">
<!-- 桌面设备的样式 -->
<link rel="stylesheet" href="desktop.css" media="screen and (min-width: 1024px)">
<!-- 打印样式 -->
<link rel="stylesheet" href="print.css" media="print">
响应式单位
响应式设计依赖于灵活的尺寸单位,而不是固定像素值,以便内容能够自适应不同的屏幕尺寸。
1. 相对长度单位
相对于字体大小的单位:
-
em- 相对于父元素的字体大小 -
rem- 相对于根元素(html)的字体大小 -
ex- 相对于字符'x'的高度 -
ch- 相对于字符'0'的宽度
html {
font-size: 16px; /* 基准字体大小 */
}
h1 {
font-size: 2rem; /* 32px (16px × 2) */
}
p {
font-size: 1rem; /* 16px */
margin-bottom: 1.5em; /* 相对于自身字体大小的1.5倍 */
}
.container {
padding: 1.25rem; /* 20px */
max-width: 75rem; /* 1200px */
}
相对于视口的单位:
-
vw- 视口宽度的1% -
vh- 视口高度的1% -
vmin- 视口较小尺寸(宽或高)的1% -
vmax- 视口较大尺寸(宽或高)的1%
.hero {
height: 80vh; /* 视口高度的80% */
padding: 5vw; /* 视口宽度的5% */
}
.fullscreen {
width: 100vw;
height: 100vh;
}
.square {
width: 50vmin; /* 在任何方向上不超过视口的50% */
height: 50vmin;
}
.responsive-font {
font-size: calc(16px + 1vw); /* 基础大小 + 视口缩放 */
}
2. 百分比
百分比单位使元素尺寸相对于其包含块(通常是父元素)。
.container {
width: 80%; /* 父元素宽度的80% */
max-width: 1200px;
margin: 0 auto;
}
.column {
width: 50%; /* 父元素宽度的50% */
padding: 0 2%;
float: left;
}
/* 创建固定宽高比的元素 */
.aspect-ratio-box {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9宽高比 (9÷16=0.5625) */
}
.aspect-ratio-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
3. CSS函数
calc() - 混合不同单位的数学计算:
.sidebar {
width: calc(100% - 250px); /* 全宽减去250px */
}
.column {
width: calc(33.333% - 20px); /* 三分之一宽度减去间距 */
margin: 0 10px;
}
.responsive-height {
height: calc(100vh - 80px); /* 视口高度减去头部高度 */
}
min(), max(), clamp() - 响应式值的范围控制:
/* 使用min()确保不超过最大宽度 */
.container {
width: min(90%, 1200px); /* 取90%和1200px中较小的值 */
}
/* 使用max()确保不小于最小宽度 */
.button {
padding: max(8px, 1vw) max(16px, 2vw);
}
/* 使用clamp()设置有范围的值 */
p {
font-size: clamp(16px, 4vw, 22px); /* 最小16px,最大22px,理想值4vw */
}
.flexible-column {
width: clamp(250px, 25%, 400px);
}
响应式图片
图像通常是网页中最大的资源,需要特殊处理以确保在不同设备上都能高效率地加载并良好显示。
1. 基本响应式图片
使用CSS使图片适应容器:
img {
max-width: 100%; /* 不超过容器宽度 */
height: auto; /* 保持原始宽高比 */
}
.contain-image {
object-fit: contain; /* 完整显示图像,可能留白 */
width: 100%;
height: 300px;
}
.cover-image {
object-fit: cover; /* 填满容器,可能裁剪 */
width: 100%;
height: 300px;
}
2. 使用srcset和sizes属性
允许浏览器选择最合适的图像源:
<!-- 根据设备像素比选择图像 -->
<img src="image-1x.jpg"
srcset="image-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x"
alt="响应式图像">
<!-- 根据视口宽度选择图像 -->
<img src="small.jpg"
srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw"
alt="响应式图像">
sizes属性告诉浏览器图像在不同条件下将占据多少视口宽度:
-
(max-width: 600px) 100vw- 在小屏幕上,图像宽度为视口的100% -
(max-width: 1200px) 50vw- 在中等屏幕上,图像宽度为视口的50% -
33vw- 在大屏幕上,图像宽度为视口的33%
3. picture元素
提供更强大的响应式图像控制,包括基于媒体查询的格式和尺寸切换:
<picture>
<!-- 在小屏幕上使用垂直裁剪的图像 -->
<source media="(max-width: 767px)" srcset="image-mobile.jpg">
<!-- 在大屏幕上使用水平图像 -->
<source media="(min-width: 768px)" srcset="image-desktop.jpg">
<!-- 不支持picture元素的浏览器回退 -->
<img src="image-desktop.jpg" alt="响应式图像">
</picture>
<!-- 根据浏览器支持提供不同格式 -->
<picture>
<source type="image/webp" srcset="image.webp">
<source type="image/jpeg" srcset="image.jpg">
<img src="image.jpg" alt="响应式图像">
</picture>
4. CSS背景图像
使用媒体查询为背景图像提供不同的版本:
.hero {
background-image: url('hero-mobile.jpg');
background-size: cover;
background-position: center;
height: 50vh;
}
@media (min-width: 768px) {
.hero {
background-image: url('hero-tablet.jpg');
height: 60vh;
}
}
@media (min-width: 1200px) {
.hero {
background-image: url('hero-desktop.jpg');
height: 70vh;
}
}
/* 使用image-set()为高DPI设备提供不同版本 */
.hero {
background-image: -webkit-image-set(
url('hero-1x.jpg') 1x,
url('hero-2x.jpg') 2x
);
background-image: image-set(
url('hero-1x.jpg') 1x,
url('hero-2x.jpg') 2x
);
}
响应式设计模式
多年的实践已经形成了一些常见的响应式设计模式,用于解决布局适应不同屏幕尺寸的问题。
1. 流式网格(Fluid Grid)
使用百分比定义的网格系统,允许内容自动缩放:
.row {
display: flex;
flex-wrap: wrap;
margin: 0 -15px;
}
.col {
padding: 0 15px;
flex-basis: 100%;
}
@media (min-width: 768px) {
.col-md-6 {
flex-basis: 50%;
}
.col-md-4 {
flex-basis: 33.333%;
}
.col-md-3 {
flex-basis: 25%;
}
}
2. 弹性图片(Flexible Images)
确保图像和媒体不超出其容器:
.fluid-media {
max-width: 100%;
height: auto;
}
/* 处理固定宽高比的嵌入内容(如视频) */
.responsive-embed {
position: relative;
padding-bottom: 56.25%; /* 16:9 宽高比 */
height: 0;
overflow: hidden;
}
.responsive-embed iframe,
.responsive-embed object,
.responsive-embed embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
3. 列下沉(Column Drop)
当屏幕变小时,多列布局中的列按顺序下沉:
.container {
display: flex;
flex-wrap: wrap;
}
.sidebar, .content, .aside {
width: 100%;
}
@media (min-width: 600px) {
.sidebar {
width: 30%;
}
.content {
width: 70%;
}
}
@media (min-width: 1000px) {
.sidebar {
width: 20%;
}
.content {
width: 60%;
}
.aside {
width: 20%;
}
}
4. 布局转换(Layout Shifter)
在不同断点使用显著不同的布局:
.container {
display: flex;
flex-wrap: wrap;
}
.box {
flex: 1 100%;
}
@media (min-width: 768px) {
.main {
flex: 2 0px;
}
.aside1 {
order: 1;
flex: 1 0px;
}
.aside2 {
order: 3;
flex: 1 0px;
}
.main {
order: 2;
}
}
5. 抽屉式导航(Off-canvas)
在小屏幕上隐藏导航或侧边栏,通过点击按钮显示:
.container {
position: relative;
min-height: 100vh;
overflow-x: hidden;
}
.content {
transition: transform 0.3s ease;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 80%;
max-width: 300px;
height: 100%;
transform: translateX(-100%);
transition: transform 0.3s ease;
background-color: white;
z-index: 100;
}
.nav-open .sidebar {
transform: translateX(0);
}
.nav-open .content {
transform: translateX(80%);
}
@media (min-width: 768px) {
.sidebar {
position: static;
transform: none;
width: 25%;
}
.content {
transform: none;
width: 75%;
}
.menu-toggle {
display: none;
}
}
移动友好设计
除了响应式布局,还需要考虑移动设备的触摸交互、更慢的网络和更小的屏幕等特性。
1. 视口设置
确保移动设备正确渲染响应式网页:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
这个元标签告诉移动浏览器:
-
width=device-width- 将网页宽度设置为设备宽度 -
initial-scale=1.0- 设置初始缩放级别
2. 触摸友好界面
为触摸设备优化交互元素:
/* 增大触摸目标尺寸 */
.button, .nav-link, .checkbox label {
min-height: 44px;
min-width: 44px;
padding: 12px 16px;
}
/* 增加元素间距,防止误触 */
.nav-links li {
margin-bottom: 8px;
}
/* 清晰的状态反馈 */
.button:active {
transform: scale(0.98);
background-color: #0056b3;
}
/* 针对触摸设备的交互方式 */
@media (hover: none) {
/* 触屏设备下菜单展开方式 */
.dropdown-toggle::after {
content: " +";
}
.dropdown-toggle[aria-expanded="true"]::after {
content: " -";
}
}
3. 性能优化
为移动设备优化性能和加载速度:
/* 减少图片尺寸和质量 */
@media (max-width: 767px) {
.background {
background-image: url('bg-small.jpg');
}
}
/* 简化移动版动画 */
@media (max-width: 767px) {
.animate {
animation: none !important;
transition: none !important;
}
}
/* 按需加载 */
.card-image {
loading: lazy;
}
4. 内容优先级
在移动设备上突出显示最重要的内容:
@media (max-width: 767px) {
/* 隐藏次要内容 */
.secondary-info {
display: none;
}
/* 调整内容顺序 */
.main-content {
order: 1;
}
.sidebar {
order: 2;
}
/* 简化内容表现 */
.data-table {
display: block;
}
.data-table thead {
display: none;
}
.data-table td {
display: block;
}
.data-table td::before {
content: attr(data-label);
font-weight: bold;
display: inline-block;
width: 40%;
}
}
响应式设计测试与调试
创建功能完善的响应式设计需要在各种设备和环境中进行测试。
1. 浏览器开发工具
所有现代浏览器都提供响应式设计模式和设备模拟:
- Chrome/Edge DevTools: 切换设备工具栏
- Firefox Responsive Design Mode
- Safari Responsive Design Mode
这些工具允许模拟不同的屏幕尺寸、像素密度和用户代理。
2. 实际设备测试
尽管模拟器很有用,但在实际设备上测试仍然至关重要,可以发现以下问题:
- 触摸交互问题
- 实际性能和加载时间
- 特定设备的浏览器兼容性问题
- 真实网络条件下的体验
3. 实用测试技巧
/* 调试辅助:显示所有元素的边界 */
* {
outline: 1px solid red;
}
/* 突出显示溢出元素 */
body {
overflow-x: hidden;
}
:root {
overflow-x: hidden;
position: relative;
}
/* 在不同断点显示当前断点名称 */
body::after {
position: fixed;
bottom: 0;
right: 0;
padding: 5px;
background: black;
color: white;
z-index: 9999;
font-size: 12px;
}
@media (max-width: 575px) {
body::after {
content: "XS";
}
}
@media (min-width: 576px) and (max-width: 767px) {
body::after {
content: "SM";
}
}
/* 以此类推... */
八、CSS变量和计算
CSS变量(自定义属性)和计算函数大大增强了CSS的功能,使样式能够更加灵活、可维护和动态。
CSS变量(自定义属性)
CSS变量允许开发者定义可重用的值,这些值可以在整个样式表中引用,实现真正的"编程"能力。
1. 变量声明与使用
CSS变量的名称必须以两个破折号(--)开头,通常在:root选择器中定义全局变量:
:root {
/* 颜色变量 */
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333333;
--background-color: #f8f9fa;
/* 尺寸变量 */
--spacing-unit: 8px;
--border-radius: 4px;
--container-width: 1200px;
/* 字体变量 */
--font-family-base: 'Roboto', sans-serif;
--font-size-base: 16px;
--line-height: 1.5;
/* 时间变量 */
--transition-duration: 0.3s;
}
使用var()函数引用变量:
.button {
background-color: var(--primary-color);
color: white;
padding: var(--spacing-unit) calc(var(--spacing-unit) * 2);
border-radius: var(--border-radius);
font-family: var(--font-family-base);
transition: all var(--transition-duration) ease;
}
.button:hover {
background-color: var(--secondary-color);
}
.container {
max-width: var(--container-width);
margin: 0 auto;
padding: calc(var(--spacing-unit) * 2);
}
2. 变量作用域和继承
CSS变量遵循CSS的级联规则,具有作用域和继承特性:
:root {
--main-color: blue;
}
.card {
--card-padding: 16px;
padding: var(--card-padding);
color: var(--main-color); /* 从:root继承 */
}
.card--featured {
--main-color: gold; /* 局部覆盖全局变量 */
--card-padding: 24px; /* 覆盖.card中的变量 */
}
.card__header {
padding: var(--card-padding); /* 访问.card或.card--featured中的变量 */
border-bottom: 1px solid var(--main-color);
}
3. 变量回退值
var()函数可以提供回退值,当变量未定义或值无效时使用:
.element {
/* 如果--custom-width未定义,使用100% */
width: var(--custom-width, 100%);
/* 可以嵌套变量 */
background-color: var(--theme-color, var(--default-color, #f0f0f0));
/* 多个回退值需要嵌套 */
padding: var(--padding, var(--spacing, 20px));
}
4. 修改变量与响应式设计
CSS变量可以基于上下文或媒体查询进行动态修改:
/* 定义默认亮色主题变量 */
:root {
--text-color: #333;
--background-color: #fff;
--link-color: #0066cc;
}
/* 响应式变化 */
@media (max-width: 768px) {
:root {
--spacing-unit: 4px; /* 在小屏幕上减小间距 */
--font-size-base: 14px; /* 在小屏幕上减小字体 */
}
}
/* 暗色模式变量覆盖 */
@media (prefers-color-scheme: dark) {
:root {
--text-color: #eee;
--background-color: #121212;
--link-color: #88ccff;
}
}
/* 特定组件上下文中修改变量 */
.dark-section {
--text-color: white;
--background-color: #333;
background-color: var(--background-color);
color: var(--text-color);
}
5. 用JavaScript操作CSS变量
CSS变量的一个强大功能是可以通过JavaScript动态修改:
// 获取CSS变量值
const rootStyles = getComputedStyle(document.documentElement);
const primaryColor = rootStyles.getPropertyValue('--primary-color').trim();
console.log('当前主色: ' + primaryColor);
// 设置CSS变量值
document.documentElement.style.setProperty('--primary-color', '#ff6b6b');
// 基于用户交互修改变量
const slider = document.getElementById('font-size-slider');
slider.addEventListener('input', function() {
document.documentElement.style.setProperty('--font-size-base', this.value + 'px');
});
// 实现主题切换
function toggleDarkMode() {
document.body.classList.toggle('dark-theme');
}
配套的CSS:
:root {
--primary-color: #3498db;
--font-size-base: 16px;
}
body {
font-size: var(--font-size-base);
}
.dark-theme {
--primary-color: #9b59b6;
--background-color: #121212;
--text-color: #f5f5f5;
}
CSS计算
CSS提供了几个强大的函数,用于动态计算值并进行简单的数学运算。
1. calc()函数
calc()允许在CSS中执行基本数学运算,特别有用的是它可以混合不同的单位:
.sidebar {
/* 100%宽度减去150像素 */
width: calc(100% - 150px);
}
.responsive-padding {
/* 基础内边距加上视口宽度的3% */
padding: calc(10px + 3vw);
}
.column {
/* 三列布局,考虑间距 */
width: calc((100% - 40px) / 3);
margin-right: 20px;
}
.column:last-child {
margin-right: 0;
}
.nested-calc {
/* 嵌套计算 */
height: calc(100vh - calc(80px + 2rem));
}
支持的运算符:
-
+加法 -
-减法 -
*乘法 -
/除法
注意事项:
- 运算符两侧需要有空格
- 可以嵌套
calc() - 不能除以零
- 某些复杂表达式可能需要使用括号
2. min(), max()和clamp()函数
这三个函数允许根据条件选择值,在创建响应式设计时非常有用。
min() - 从多个值中选择最小的一个:
.container {
/* 选择90%和1200px中较小的值 */
width: min(90%, 1200px);
margin: 0 auto;
}
.responsive-font {
/* 确保字体不会太大 */
font-size: min(5vw, 36px);
}
max() - 从多个值中选择最大的一个:
.column {
/* 确保列至少300px宽 */
width: max(300px, 25%);
}
.button {
/* 确保按钮至少有足够的点击区域 */
padding: max(8px, 1vw) max(16px, 2vw);
}
clamp() - 将值限定在一个范围内,同时提供一个首选值:
.responsive-width {
/* 最小500px,最大1200px,理想值为视口宽度的80% */
width: clamp(500px, 80vw, 1200px);
}
.fluid-typography {
/* 最小16px,最大24px,理想值为视口宽度的4% */
font-size: clamp(16px, 4vw, 24px);
}
.margin-block {
/* 响应式但有界限的间距 */
margin-block: clamp(1rem, 5vh, 3rem);
}
clamp(MIN, VAL, MAX)相当于max(MIN, min(VAL, MAX))。
3. 实际应用示例
响应式排版系统:
:root {
/* 基础字体大小 */
--font-size-base: clamp(16px, 1rem + 0.5vw, 20px);
/* 比例系数 */
--scale-ratio: 1.25;
/* 派生尺寸 */
--font-size-sm: calc(var(--font-size-base) / var(--scale-ratio));
--font-size-lg: calc(var(--font-size-base) * var(--scale-ratio));
--font-size-xl: calc(var(--font-size-lg) * var(--scale-ratio));
--font-size-xxl: calc(var(--font-size-xl) * var(--scale-ratio));
}
body {
font-size: var(--font-size-base);
line-height: 1.5;
}
h1 { font-size: var(--font-size-xxl); }
h2 { font-size: var(--font-size-xl); }
h3 { font-size: var(--font-size-lg); }
small { font-size: var(--font-size-sm); }
间距系统:
:root {
--space-unit: clamp(8px, 1vw, 16px);
--space-xs: calc(var(--space-unit) * 0.5);
--space-sm: var(--space-unit);
--space-md: calc(var(--space-unit) * 2);
--space-lg: calc(var(--space-unit) * 3);
--space-xl: calc(var(--space-unit) * 5);
}
.card {
padding: var(--space-md);
margin-bottom: var(--space-lg);
}
.card-title {
margin-bottom: var(--space-sm);
}
颜色系统与暗模式:
:root {
/* 基础颜色 */
--hue-primary: 210; /* 蓝色 */
--saturation-primary: 100%;
--lightness-primary-base: 50%;
/* 计算变体 */
--primary-color: hsl(var(--hue-primary), var(--saturation-primary), var(--lightness-primary-base));
--primary-light: hsl(var(--hue-primary), var(--saturation-primary), calc(var(--lightness-primary-base) + 20%));
--primary-dark: hsl(var(--hue-primary), var(--saturation-primary), calc(var(--lightness-primary-base) - 20%));
/* 文本颜色 */
--text-base-lightness: 20%;
--text-color: hsl(0, 0%, var(--text-base-lightness));
}
@media (prefers-color-scheme: dark) {
:root {
--lightness-primary-base: 60%; /* 暗模式中主色更亮 */
--text-base-lightness: 90%; /* 暗模式中文本更亮 */
}
}
复杂布局:
.layout {
--sidebar-width: 250px;
--main-padding: clamp(1rem, 3vw, 2rem);
--header-height: 60px;
--footer-height: 80px;
display: grid;
grid-template-columns: var(--sidebar-width) calc(100% - var(--sidebar-width));
grid-template-rows: var(--header-height) calc(100vh - var(--header-height) - var(--footer-height)) var(--footer-height);
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.main-content {
grid-area: main;
padding: var(--main-padding);
max-height: calc(100vh - var(--header-height) - var(--footer-height));
overflow-y: auto;
}
@media (max-width: 768px) {
.layout {
--sidebar-width: 0px; /* 移动版隐藏侧边栏 */
grid-template-rows: var(--header-height) auto var(--footer-height);
}
}