CSS3 属性速查表 - CSS3 常用样式与布局大全
手写 CSS 的难点很少是记不住属性,而是级联到底谁赢了、盒模型算出的宽度为什么和设计稿对不上、以及布局该交给 Flex 还是 Grid。所以这张表先把选择器优先级和盒模型讲透(含 border-box 与 margin 折叠这两个高频坑),再按布局分工给出明确判断标准:只有一根主轴就用 Flex,需要行列同时对齐就用 Grid,脱离文档流用定位。视觉与交互部分覆盖渐变、阴影、过渡与关键帧动画,最后落到响应式断点写法。判断标准比结论更重要——例如 Flex 的 justify-content 管主轴、align-items 管交叉轴,两者混用是新手最常见的错位来源;Grid 的 track 尺寸则优先用 fr 与 minmax 而不是硬写百分比。
典型使用场景
面向需要手写样式、或在无框架环境中做精细控制的 Web 开发者。本表按八条主线组织:选择器、盒模型、Flex、Grid、定位、背景渐变、动画、响应式。最该先记住的三条是 box-sizing: border-box 让宽高包含内边距与边框、Flex 管一维而 Grid 管二维、移动优先用 @media (min-width) 往大屏扩展而不是反过来。布局写歪时(元素不居中、绝对定位跑到屏幕左上、flex 子项不换行)几乎都出在这三处。响应式字号交给 clamp()、相对单位用 rem,动画用 transition 配合 transform 做位移缩放而不去动 width/height,都能避免大部分重排与卡顿。
选择器 Selectors 10
.class { }#id { }element { }parent > childancestor descendantelement + siblingelement ~ sibling[attr] / [attr="value"]:hover / :focus / :active::before / ::after盒模型 Box Model 9
width: 100px; height: 100px;margin: 10px;padding: 10px;border: 1px solid #000;box-sizing: border-box;display: block / inline / inline-block;display: none;visibility: hidden;opacity: 0.5;Flex 布局 Flexbox 7
display: flex;flex-direction: row / column;justify-content: flex-start / center / space-between;align-items: stretch / center / flex-start;flex-wrap: wrap;flex: 1;gap: 10px;Grid 布局 Grid 7
display: grid;grid-template-columns: 1fr 1fr 1fr;grid-template-rows: 100px auto;grid-gap: 10px;grid-column: 1 / 3;grid-row: 1 / 3;grid-template-areas: "header" "main" "footer";定位 Positioning 7
position: static;position: relative;position: absolute;position: fixed;position: sticky;top: 0; right: 0; bottom: 0; left: 0;z-index: 100;背景与渐变 Background & Gradient 7
background-color: #fff;background-image: url("bg.jpg");background-size: cover / contain;background-position: center;background-repeat: no-repeat;linear-gradient(to right, #000, #fff);radial-gradient(circle, #000, #fff);动画 Animation 6
transition: all 0.3s ease;transform: translateX(10px);transform: scale(1.5);transform: rotate(45deg);@keyframes name { 0% {} 100% {} }animation: name 1s infinite;响应式 Responsive 6
@media (max-width: 768px) { }max-width: 100%;min-width: 0;vw / vh / vmin / vmaxrem / emclamp(1rem, 2vw, 2rem);参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
.class / #id / element | 类 / ID / 元素选择器 | .card { padding: 10px; } |
parent > child | 直接子元素选择器 | nav > ul { margin: 0; } |
ancestor descendant | 后代选择器 | div p { color: #333; } |
element + sibling / element ~ sibling | 相邻兄弟 / 通用兄弟选择器 | h2 + p { margin-top: 0; } |
[attr] / [attr="value"] | 属性选择器 | input[type="text"] { width: 100%; } |
:hover / :focus / :active | 悬停 / 聚焦 / 激活伪类 | a:hover { color: blue; } |
::before / ::after | 伪元素,插入内容或装饰 | p::before { content: "· "; } |
width / height | 盒子的内容宽高 | width: 100px; height: 100px; |
margin / padding | 外边距 / 内边距 | margin: 10px; padding: 10px; |
border | 边框简写(宽度 样式 颜色) | border: 1px solid #000; |
box-sizing: border-box | 宽高包含边框与内边距 | * { box-sizing: border-box; } |
display: block / inline / inline-block | 三种常见显示类型 | .btn { display: inline-block; } |
display: none | 移除元素,不占位 | .hidden { display: none; } |
visibility: hidden | 不可见但仍占布局空间 | .mask { visibility: hidden; } |
opacity: 0.5 | 整体透明度(含内容) | .faded { opacity: 0.5; } |
display: flex | 启用 Flex 布局 | .row { display: flex; } |
flex-direction: row / column | 主轴方向 | flex-direction: column; |
justify-content | 主轴对齐:flex-start / center / space-between | justify-content: center; |
align-items | 交叉轴对齐:stretch / center / flex-start | align-items: center; |
flex: 1 | 弹性增长并占满剩余空间 | .grow { flex: 1; } |
flex-wrap: wrap | 空间不足时换行 | flex-wrap: wrap; |
gap: 10px | 元素间距 | gap: 10px; |
display: grid | 启用 Grid 布局 | .grid { display: grid; } |
grid-template-columns | 定义列轨道 | grid-template-columns: 1fr 1fr 1fr; |
grid-template-rows | 定义行轨道 | grid-template-rows: 100px auto; |
grid-gap: 10px | 网格行列间距 | grid-gap: 10px; |
grid-column: 1 / 3 | 元素跨列 | grid-column: 1 / 3; |
grid-row: 1 / 3 | 元素跨行 | grid-row: 1 / 3; |
grid-template-areas | 命名区域排版 | grid-template-areas: "header" "main" "footer"; |
position: relative | 相对自身定位,作为 absolute 的参照 | .wrap { position: relative; } |
position: absolute | 相对最近定位祖先定位 | .badge { position: absolute; } |
position: fixed | 相对视口固定,不随滚动移动 | .bar { position: fixed; } |
position: sticky | 滚动到阈值后固定 | .nav { position: sticky; } |
top/right/bottom/left | 定位偏移量 | top: 0; left: 0; |
z-index: 100 | 层叠顺序 | z-index: 100; |
background-image: url() | 背景图 | background-image: url("bg.jpg"); |
background-size: cover / contain | 背景图铺满 / 完整显示 | background-size: cover; |
linear-gradient() | 线性渐变 | linear-gradient(to right, #000, #fff); |
radial-gradient() | 径向渐变 | radial-gradient(circle, #000, #fff); |
transition: all 0.3s ease | 属性变化过渡动画 | transition: all 0.3s ease; |
transform: translateX / scale / rotate | 位移 / 缩放 / 旋转(不触发重排) | transform: scale(1.5); |
@keyframes / animation | 定义关键帧并循环应用 | animation: name 1s infinite; |
@media (max-width: 768px) | 媒体查询断点 | @media (max-width: 768px) { .nav { display: none; } } |
vw / vh / vmin / vmax | 视口单位:宽 / 高 / 最短边 / 最长边 | width: 100vw; |
rem / em | 相对根元素 / 父元素字号的单位 | font-size: 1.25rem; |
clamp(min, preferred, max) | 响应式取值,在区间内随视口缩放 | font-size: clamp(1rem, 2vw, 2rem); |
易错点与避坑指南
现象设了 width: 200px 的元素实际占了 200 + padding*2 + border*2,布局比预期宽
原因默认 box-sizing 是 content-box,width 只管内容区,边框和内边距额外叠加。
处置全局设置 * { box-sizing: border-box; },让宽高包含边框与内边距。
现象绝对定位的元素贴在页面左上角,或跑到离它很远的地方
原因absolute 参照的是最近的非 static 祖先;祖先都是 static 时就退回初始包含块,坐标参照系完全不同。
处置给预期作为容器的父元素加 position: relative,再设置 top/left 偏移。
现象元素隐藏后仍然占着位置,下一元素被顶住不上去
原因display: none 会彻底移除元素,而 visibility: hidden 只是不可见,两者占位行为不同。
处置需要彻底移除(含占位)用 display: none;需要保留空间只隐藏可见性用 visibility: hidden。
现象flex 布局写了 justify-content: center 却没居中
原因交叉轴对齐由 align-items 控制,且子项若宽度占满主轴,居中在视觉上看不出来。
处置主轴用 justify-content、交叉轴用 align-items,两条轴要分别设置;确认子项没有固定宽度把主轴填满。
现象做响应式时大屏样式在大屏不生效、小屏反而生效
原因用了 max-width 查询后又按大屏优先书写,逻辑与移动优先相反;基础样式会被窄屏覆盖。
处置改为移动优先:基础样式写小屏表现,再用 @media (min-width: ...) 逐级扩展大屏。
现象给文字做渐变颜色失败,背景渐变倒是正常
原因background-image: linear-gradient() 作用在元素背景上,需要配合 -webkit-background-clip: text 才能显示为文字渐变。
处置组合使用:linear-gradient(...) 加 -webkit-background-clip: text; 与 color: transparent;。
现象动画过程中页面卡顿,掉帧明显
原因过渡作用在 width、height、margin 等会触发重排的属性上,每帧都在重新计算布局。
处置改用 transform: translateX / scale / rotate 与 opacity 做动画,这些属性可由合成层处理。
现象父容器设置了 flex-wrap: wrap,子项仍被挤成一行且内容溢出
原因flex 子项的 min-width 默认是 auto,内容最小宽度可能超过换行判断,导致宁可溢出也不换行。
处置给需要收缩的子项设置 min-width: 0(同时配合 overflow 处理),让换行判定基于真正可用宽度。
排障路径
1先统一盒模型基线
* { box-sizing: border-box; }把 border-box 设为全局基线后,所有宽高都会包含边框与内边距。设置前后对同一元素量一次实际宽度,若差值等于 padding 与 border 之和,说明此前就是 content-box 造成的偏差。
2一维布局用 Flex 复现
display: flex; justify-content: space-between; align-items: center; gap: 10px;justify-content 管主轴、align-items 管交叉轴、gap 管间距,三者分轴设置后左右分栏与垂直居中可同时成立;若间距异常,优先检查是否残留了子元素 margin。
3二维布局用 Grid 复现
display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 10px;三列等宽用 1fr 重复三次最稳,行高可交给内容自适应(auto)。需要某元素占满整行时加 grid-column: 1 / 3;改成命名区域则用 grid-template-areas 做整版排版。
4定位元素跑偏时的三步确认
.wrap { position: relative; } .badge { position: absolute; top: 0; left: 0; z-index: 100; }第一步给参照容器加 relative,第二步再设偏移,最后调 z-index。若去掉 relative 后位置反而对了,说明参照系选错——absolute 只认最近的定位祖先,fixed 才认视口。
5响应式断点自检
@media (max-width: 768px) { .nav { display: none; } }先用窄屏查询确认「小屏样式确实生效」,再决定是否改用 min-width 往大屏扩展。同时用 clamp(1rem, 2vw, 2rem) 给字号做连续缩放,比一堆断点更省事。
6动画性能核对
.box { transition: transform 0.3s ease; } .box:hover { transform: translateX(10px); }transition 与 hover 都作用在 transform 上时,动画只做合成不重排,帧率平稳。若换成 transition: all 或改 width 就会掉帧——先用 transform 版对比确认瓶颈是否在重排。
命令示例
box-sizing 决定宽度是否含内边距
* {
box-sizing: border-box;
}
.card {
width: 100%;
padding: 20px;
border: 1px solid #000;
}默认 content-box 下 100% 宽再加 padding 会溢出容器 40px;全局设 border-box 后 width 就是最终占位,这类「明明设了 100% 却撑破布局」的问题一次性消失。
Flex 双轴居中
.parent {
display: flex;
justify-content: center;
align-items: center;
}justify-content 管主轴(水平),align-items 管交叉轴(垂直),两者分工固定。align-items 默认是 stretch,直接换成 center 常常让子元素高度塌陷或被拉伸,出现「居中后变形」的现象。
Grid 命名区域排整页布局
.layout {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
}
.header { grid-area: header; }
.main { grid-area: main; }
.footer { grid-area: footer; }引号里的空格即列,空行即行,所以 "header main footer" 是三列一行。改布局只需动 areas 字符串,不必逐个调 grid-row / grid-column 的数字。
clamp 写出自适应字号
h1 {
font-size: clamp(1rem, 2vw, 2rem);
}clamp(最小值, 首选值, 最大值) 在视口 375px 到 1000px 之间线性插值,比一堆媒体查询更省事;把中间项写成 vw 的倍数过大时(如 5vw)小屏会撑破容器。
sticky 表头配 z-index
.header {
position: sticky;
top: 0;
z-index: 100;
background: #fff;
}sticky 需要 top 或 bottom 才有参照值,且父级若设了 overflow: hidden,粘性会在该容器内提前失效。z-index 只在定位元素之间比较,不加定位时写了也不生效。
常见坑与注意事项
- display: none 的元素连同子元素一起消失且不占布局,visibility: hidden 只是不可见仍占位;想用 CSS 淡出隐藏却用 display 会导致布局塌陷、点击穿透到下层。
- 不加 box-sizing: border-box 时 width/height 不含 padding 与 border,百分比宽度加内边距必然溢出父容器,这是布局错位最常见的根因。
- position: absolute 的包含块是最近的定位祖先,不是视口;祖先没有 position 时元素相对初始包含块定位,改父级样式会让子元素整体跑位。
- opacity 会创建新的层叠上下文:给 z-index: 999 的祖先加 opacity 后,子元素再大的 z-index 也盖不过外部元素。
- vw/vh 在移动端含浏览器地址栏高度,vh 写的 100vh 会导致页面底部被地址栏遮住并出现可滚动空白。
- transform 与 filter 会创建包含块,使内部的 position: fixed 改为相对该元素定位;给浮层加动画后浮层会跟着滚动走位。
提示
- box-sizing: border-box 让宽高包含边框和 padding,更符合直觉。
- Flex 适合一维布局(行或列),Grid 适合二维布局(行和列同时控制)。
- 移动端优先:先写小屏样式,再用 @media (min-width) 扩展大屏。
- 通配符 * 选择器优先级虽低但会命中每个元素,务必确认 body * 之类规则没有意外影响表单控件外观。
- transform: translate(-50%, -50%) 做绝对居中时父元素必须有 position: relative,否则参照的是更外层的定位祖先。
- gap 在 flex 容器上早已可用,不要再靠子元素 margin 或 :not(:last-child) 制造间距,后者在换行时会错位。
常见问题
子元素设置 position: absolute 后定位总是不对,该检查什么?
绝对定位是相对于「最近的定位祖先」而不是父元素本身。若父级是 position: static(默认值),absolute 就会退回相对视口定位,看起来像「没反应」。给需要充当参照的父容器加 position: relative,再用 top/right/bottom/left 偏移偏移量,最后用 z-index: 100 调整与兄弟元素的层叠。fixed 相对视口、sticky 需要祖先是可滚动容器,这三种参照系别搞混。
display: none 和 visibility: hidden 的差别会影响布局吗?
会影响,这是两者的本质区别。display: none 把元素从渲染树中移除,不占任何布局空间,后续元素会补位;visibility: hidden 只停止绘制,元素仍占据原有的盒子位置,文档流不塌陷。opacity: 0 同样保留位置。三者中只有 display: none 是「彻底拿掉元素」,所以要按条件切换显隐、又不能引起跳版时,用 visibility: hidden 或 opacity: 0 更稳妥。
什么时候该用 Flex,什么时候该用 Grid?
按维度选:一维(只需控制一行或一列的排布)用 display: flex,flex-direction 定主轴、justify-content 主轴对齐、align-items 交叉轴对齐、flex-wrap 换行、gap 出间距、flex: 1 分配剩余空间。二维(行列都要精确定位)用 display: grid,grid-template-columns / rows 定义骨架,grid-column: 1 / 3 实现跨列,grid-template-areas 用命名区域摆整体结构。只有一维需求别上 grid,需要二维对齐时也别用嵌套 flex 硬凑。
响应式布局怎么写才不至于把媒体查询写成一团?
移动端优先:先把小屏样式作为默认写在最前面,再用 @media (min-width: 768px) { } 逐级向上扩展,避免 max-width 层层覆盖。尺寸上用 max-width: 100% 防止图片和容器撑破父级,用 min-width: 0 修复 Flex 子项无法收缩的问题。字号用 clamp(1rem, 2vw, 2rem) 让排版在区间内自动缩放,单位则按需选 vw/vh(视口)、rem(相对根元素)、em(相对父元素)。
box-sizing: border-box 到底改变了什么,为什么建议全局设置?
默认的 content-box 下,width: 100px 指的是内容宽度,再加 padding 与 border 后元素实际占位会大于 100px,于是「宽度撑破容器」的现象频繁出现。box-sizing: border-box 让 width 把 padding 和 border 一起算进去,声明值就是最终占位,配合 max-width: 100% 才符合直觉。建议在全局样式(通常是 * 选择器)统一设置一次,之后每个盒子的尺寸都可预期,不再逐个补算。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。