Skip to content

CSS3 速查表

CSS 的最新演进,包含样式、布局和动画模块。

01

选择器

属性与伪类选择器

CSS3 引入了强大的属性选择器和伪类。^= 匹配前缀,$= 匹配后缀,*= 匹配子串。nth-child 无需 JavaScript 即可实现斑马条纹。

css3
/* attribute selectors */
input[type="text"] { border: 1px solid blue; }
a[href^="https"] { color: green; }
a[href$=".pdf"] { color: red; }
a[href*="example"] { font-weight: bold; }

/* pseudo-classes */
a:visited { color: purple; }
li:first-child { font-weight: bold; }
li:nth-child(odd) { background: #f0f0f0; }
input:focus { outline: 2px solid blue; }

结构伪类

结构伪类根据元素在 DOM 中的位置进行选择。:first-child / :last-child 定位首尾。nth-child(an+b) 支持公式:2n 为偶数,2n+1 为奇数,3n 为每第三个。:nth-of-type 仅统计相同元素类型的兄弟。:empty 匹配无子元素的元素。

css3
/* positional pseudo-classes */
li:first-child { color: green; }
li:last-child { color: red; }
li:only-child { font-weight: bold; }

/* nth variants */
li:nth-child(3) { color: blue; }
li:nth-child(2n+1) { background: #eee; } /* odd */
li:nth-last-child(2) { color: orange; }

/* type-based */
p:first-of-type { font-size: 1.2em; }
p:nth-of-type(even) { color: gray; }
div:empty { display: none; }

:is、:where 与 :has

:is() 和 :where() 用于分组选择器以简化书写。区别::is() 取其参数中最高的优先级,而 :where() 始终为零优先级——非常适合低覆盖的基础样式。:has() 是期待已久的父级/关系选择器,可根据后代为元素设置样式。

css3
/* :is() - matches any selector in the list */
:is(h1, h2, h3) { color: navy; }
:is(.btn, .link):hover { opacity: 0.8; }

/* :where() - same as :is but zero specificity */
:where(article, section) p { line-height: 1.6; }

/* :has() - parent selector (selects element that has a match) */
div:has(> img) { padding: 0; }
card:has(.badge) { border-color: gold; }
form:has(input:invalid) button { opacity: 0.5; }

否定与表单伪类

:not() 否定选择器,现在接受选择器列表。表单伪类(:required、:valid、:invalid、:checked、:placeholder-shown、:in-range)无需 JavaScript 即可根据输入状态设置样式。

css3
/* :not() excludes matching elements */
input:not([type="checkbox"]) { display: block; }
li:not(:last-child) { border-bottom: 1px solid #ddd; }

/* form state pseudo-classes */
input:required { border-color: red; }
input:optional { border-color: #ccc; }
input:valid { border-color: green; }
input:invalid { border-color: red; }
input:in-range { color: black; }
input:out-of-range { color: red; }
input:placeholder-shown { background: #fafafa; }
input:checked + label { font-weight: bold; }

优先级与层叠

优先级决定选择器冲突时应用哪条规则。按 ID、类、元素计数为 (a,b,c)。!important 会覆盖层叠但破坏可维护性。当优先级相同时,源代码中后定义的规则胜出。

css3
/* specificity ranking: inline > ID > class/attr/pseudo > type/element */
#nav .item { color: red; }     /* 1,1,0 */
.menu .item { color: blue; }   /* 0,2,0 */
li.item { color: green; }      /* 0,1,1 */

/* !important overrides normal declarations */
.btn { color: white !important; }

/* source order wins on equal specificity */
.late { color: purple; }  /* wins over .early */
02

盒模型

盒尺寸

box-sizing: border-box 将内边距和边框包含在声明的 width/height 中,使尺寸可预测。全局应用 border-box 是最重要的 CSS 重置。

css3
/* default: width = content only */
.box-content { box-sizing: content-box; width: 200px; padding: 20px; } /* total 240px */

/* padding & border inside width */
.box-border { box-sizing: border-box; width: 200px; padding: 20px; border: 2px solid; } /* total 200px */

/* universal reset - apply everywhere */
*, *::before, *::after {
  box-sizing: border-box;
}

外边距与内边距

内边距在边框内部(继承背景);外边距在外部(透明)。相邻块元素之间的垂直外边距会折叠为较大值。margin: 0 auto 使具有定义宽度的块级元素水平居中。

css3
.box {
  /* top right bottom left (clockwise) */
  margin: 10px 20px 15px 25px;
  /* 2 values: vertical horizontal */
  padding: 10px 20px;
  /* single value: all sides */
  margin: 0 auto; /* horizontal centering for fixed-width block */
}

/* margin collapse (vertical only) */
.a { margin-bottom: 30px; }
.b { margin-top: 20px; }
/* gap between .a and .b = 30px, not 50px (collapsed to larger) */

/* negative margins pull elements together */
.pull-left { margin-left: -10px; }

盒阴影

box-shadow 语法:offset-x offset-y blur-radius spread-radius color。正偏移将阴影向右/下移动。inset 创建内阴影。多个阴影分层,第一个在最上层。使用 rgba 实现半透明的自然阴影。

css3
/* offset-x offset-y blur spread color */
.card { box-shadow: 0 4px 6px rgba(0,0,0,0.1); }

/* inset shadow (inside the box) */
.inset { box-shadow: inset 0 2px 4px rgba(0,0,0,0.2); }

/* multiple shadows (first = top layer) */
.layered { box-shadow: 0 1px 2px #000, 0 8px 24px rgba(0,0,0,0.15); }

/* no blur, hard shadow (neo-brutalism) */
.hard { box-shadow: 6px 6px 0 #000; }

/* glow effect */
.glow { box-shadow: 0 0 20px rgba(0,150,255,0.6); }

显示类型

display: none 将元素从布局中移除。block 元素占据全宽并垂直堆叠;inline 元素随文本流动且忽略 width/height。inline-block 结合内联流动与块级尺寸。flow-root 无需 clearfix 即可清除浮动。

css3
/* block: full width, new line */
div, p { display: block; }

/* inline: flows with text, ignores width/height */
span, a { display: inline; }

/* inline-block: flows inline but accepts width/height */
.tag { display: inline-block; width: 100px; }

/* none: removed from layout entirely */
.hidden { display: none; }

/* modern display values */
.flow { display: flow-root; } /* new block formatting context */
.contents { display: contents; } /* element's box disappears, children participate */

溢出

overflow 控制超出盒子的内容如何处理。visible 让内容溢出;hidden 裁剪;auto 在需要时添加滚动条;scroll 始终显示。clip 阻止任何滚动(包括通过 JS)。将 overflow 设为非 visible 会创建新的格式化上下文。

css3
.scrollable {
  overflow: auto;       /* scrollbars when needed */
  overflow-y: scroll;   /* always show vertical scrollbar */
  overflow-x: hidden;   /* hide horizontal overflow */
}

/* visible (default) - content spills out */
.spill { overflow: visible; }

/* clip - like hidden but no programmatic scroll */
.clipped { overflow: clip; }

/* clip to a shape */
.custom-clip {
  overflow: clip;
  overflow-clip-margin: 20px;
}

/* longhand for both axes */
.both { overflow-x: hidden; overflow-y: auto; }
03

Flexbox 布局

Flex 容器

display: flex 将元素变为 flex 容器。justify-content 沿主轴对齐(row 中为水平);align-items 沿交叉轴对齐。flex-wrap 允许项目换行。gap 替代基于外边距的间距 hack。Flexbox 擅长一维布局。

css3
.container {
  display: flex;
  flex-direction: row;       /* row | row-reverse | column | column-reverse */
  justify-content: center;   /* main axis: flex-start | center | space-between | space-around | space-evenly */
  align-items: center;       /* cross axis: stretch | flex-start | center | baseline */
  flex-wrap: wrap;           /* nowrap | wrap | wrap-reverse */
  gap: 16px;                 /* spacing between items */
  align-content: space-between; /* multi-line spacing */
}

Flex 项目

flex-grow 控制项目如何扩展填充额外空间(1 = 等量)。flex-shrink 控制收缩。flex-basis 是初始尺寸。简写 flex: 1 表示从零基准等量增长——非常适合等宽列。align-self 为单个项目覆盖容器的 align-items。

css3
.item {
  flex-grow: 1;     /* grow to fill extra space (0 = don't grow) */
  flex-shrink: 1;   /* shrink when space is tight (0 = don't shrink) */
  flex-basis: 200px; /* initial size before growing/shrinking */
  
  /* shorthand: flex: grow shrink basis */
  flex: 1 1 200px;   /* flexible from 200px */
  flex: 1;            /* = 1 1 0% - equal distribution */
  flex: 0 0 250px;    /* fixed width, no grow/shrink */
  
  align-self: flex-end; /* override align-items for this item */
  order: 2;             /* visual reordering (default 0) */
}

Flex 对齐模式

Flexbox 使居中变得简单:justify-content: center + align-items: center。粘性页脚使用列向 flex 的 body,min-height: 100vh,主内容设为 flex: 1。自动外边距(margin-left: auto)是 justify-content 的灵活替代方案。

css3
/* perfect centering */
.center {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* sticky footer: body is flex column */
body { display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; } /* grows to fill, pushing footer down */

/* navbar: space between */
.nav { display: flex; justify-content: space-between; }

/* auto margins absorb space */
.push-right { margin-left: auto; }

Flex 换行与响应式网格

flex-wrap: wrap 允许项目在空间不足时换行。flex: 1 1 280px 创建从 280px 起始并增长填充行的卡片。无需媒体查询即可实现响应式卡片网格。对于一致的卡片网格,CSS Grid 通常是更好的选择。

css3
.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  /* start at 280px, grow & shrink fluidly */
  flex: 1 1 280px;
  /* prevent stretching beyond readable width */
  max-width: 100%;
}

/* OR fixed-width cards that wrap */
.card-fixed {
  flex: 0 0 300px;
}

/* last row items stretch to fill - to avoid, use grid instead */
/* gap wraps with items automatically */

Flex 方向与轴

flex-direction 决定主轴。row(默认)中 justify-content 控制水平对齐;column 中控制垂直对齐——两轴互换。对齐时始终要问哪个是主轴。row-reverse 和 column-reverse 翻转项目顺序。

css3
/* row: main axis = horizontal */
.row { display: flex; flex-direction: row; justify-content: center; }

/* column: main axis = vertical (axes swap!) */
.col { display: flex; flex-direction: column; align-items: center; }

/* reverse order */
.reverse { display: flex; flex-direction: row-reverse; }

/* centering in column: justify-content centers vertically */
.col-center {
  display: flex;
  flex-direction: column;
  justify-content: center; /* vertical center */
  align-items: center;     /* horizontal center */
}
04

网格布局

网格容器

display: grid 创建二维布局。grid-template-columns 定义列轨道;fr 单位按比例分配剩余空间。repeat(auto-fit, minmax(200px, 1fr)) 是响应式网格的魔法配方——无需媒体查询即可自动创建列。

css3
.grid {
  display: grid;
  /* fixed columns */
  grid-template-columns: 200px 1fr 200px;
  /* responsive auto columns */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-template-rows: auto 1fr auto;
  gap: 20px;            /* row + column gap */
  row-gap: 20px;        /* gap between rows */
  column-gap: 16px;     /* gap between columns */
}

网格模板区域

grid-template-areas 让你用命名区域直观地绘制布局——可读性极强。每个引号字符串是一行;名称放置项目,点号标记空单元格。grid-area: name 的项目填充该区域。

css3
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

/* empty cell with a dot */
grid-template-areas: "header header" "sidebar .";

网格项目放置

网格项目可通过线号显式放置。grid-column: 1 / 3 从线 1 跨越到线 3(覆盖 2 列)。span 关键字按轨道数定尺寸。线也可在 grid-template-columns 中命名以提高可读性。

css3
.item {
  /* place by line numbers: row-start / col-start / row-end / col-end */
  grid-column: 1 / 3;      /* span columns 1 to 3 */
  grid-row: 1 / 2;
  
  /* span keyword */
  grid-column: span 2;     /* span 2 columns */
  grid-row: 2 / span 3;
  
  /* shorthand: grid-area: row-start / col-start / row-end / col-end */
  grid-area: 1 / 1 / 3 / 4;
  
  /* name a line and reference it */
  grid-column-start: content-start;
}

网格对齐

网格对齐在两个层面工作。justify-content/align-content 在有剩余空间时定位整个网格。justify-items/align-items 在单元格内对齐项目(默认 stretch)。justify-self/align-self 为单个项目覆盖对齐。

css3
.grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  
  /* align tracks within container */
  justify-content: center;  /* center the grid horizontally */
  align-content: center;    /* center vertically (needs fixed height) */
  
  /* align items within their cells */
  justify-items: stretch;   /* fill cell width (default) */
  align-items: center;      /* center within cell height */
}

.item {
  justify-self: start;      /* override justify-items for one item */
  align-self: end;
}

auto-fit 与 auto-fill

两者都创建尽可能多的轨道,但在项目较少时表现不同。auto-fit 折叠未使用的轨道并拉伸现有项目填充行。auto-fill 保留空轨道,项目保持最小尺寸。想让项目增长用 auto-fit;想要一致的项目尺寸用 auto-fill。

css3
/* auto-fit: empty tracks collapse, items stretch to fill */
.autofit {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

/* auto-fill: empty tracks remain, items keep their size */
.autofill {
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

/* with few items:
   auto-fit -> items stretch to fill the row
   auto-fill -> items stay small, leaving empty columns */
05

定位

定位值

static 是默认值。relative 从正常流位置偏移(空间保留)。absolute 移出流并相对于最近的已定位祖先定位。fixed 相对于视口。sticky 根据滚动位置在 relative 和 fixed 之间切换。

css3
/* static - default, flows normally */
.static { position: static; }

/* relative - offset from its normal position */
.relative { position: relative; top: 10px; left: 20px; }

/* absolute - positioned relative to nearest positioned ancestor */
.absolute { position: absolute; top: 0; right: 0; }

/* fixed - positioned relative to viewport (stays on scroll) */
.fixed { position: fixed; bottom: 0; left: 0; }

/* sticky - relative until scroll threshold, then fixed */
.sticky { position: sticky; top: 0; }

绝对居中

绝对居中有多种方法。translate(-50%, -50%) 技巧适用于任意尺寸的元素。inset: 0 + margin: auto 技术需要显式尺寸。现代方法是 display: grid 配合 place-items: center。

css3
/* classic: position absolute + transform */
.center {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}

/* inset: 0 + margin: auto (needs width/height) */
.center-auto {
  position: absolute;
  inset: 0;          /* top/right/bottom/left: 0 */
  margin: auto;
  width: 300px;
  height: 200px;
}

/* modern: no positioning needed */
.center-grid { display: grid; place-items: center; }

粘性定位

position: sticky 使元素保持在正常流中,直到到达阈值(如 top: 0),然后像 fixed 一样固定。非常适合粘性页眉。注意:任何祖先的 overflow: hidden/auto/scroll 会成为包含块并破坏预期行为。

css3
.header {
  position: sticky;
  top: 0;            /* sticks when header hits top of viewport */
  z-index: 100;
  background: white;
}

/* sticky sidebar that scrolls with content until threshold */
.sidebar {
  position: sticky;
  top: 60px;         /* offset below the fixed header */
  max-height: calc(100vh - 60px);
  overflow-y: auto;
}

/* NOTE: a parent with overflow: hidden breaks sticky */

z-index 与层叠上下文

z-index 仅对已定位(非 static)元素生效。层叠上下文由 position + z-index 创建,但也由 opacity < 1、transform、filter、will-change 和 isolation: isolate 创建。在层叠上下文内,子级 z-index 值是隔离的。

css3
.modal { position: fixed; z-index: 1000; }
.overlay { position: fixed; z-index: 999; }
.card { position: relative; z-index: 1; }

/* creating a stacking context (isolates z-index) */
.context {
  position: relative;
  z-index: 0;  /* children's z-index only matters within this */
}

/* other properties that create stacking contexts:
   opacity < 1, transform, filter, will-change, isolation: isolate */
.isolated { isolation: isolate; }

inset 简写

inset 是 top、right、bottom、left 的逻辑简写——像 margin/padding 一样接受 1、2 或 4 个值。inset: 0 使绝对定位元素拉伸以填充包含块。它与 margin: auto 配合用于居中。

css3
/* inset sets top right bottom left (like margin) */
.popup {
  position: absolute;
  inset: 0;          /* all sides = 0 (stretches to fill parent) */
}

/* two values: vertical horizontal */
.pill {
  position: absolute;
  inset: 10px 20px;  /* top/bottom 10px, left/right 20px */
}

/* four values: top right bottom left */
.box {
  position: absolute;
  inset: 10px 20px 30px 40px;
}

/* longhand equivalents */
.inset-longhand {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}
06

文本样式

字体属性

font-family 应始终以通用字体系列(serif、sans-serif、monospace)结尾作为最后回退。font-weight 范围 100-900。line-height 最好设为无单位值(1.5)以随 font-size 缩放。font 简写需要 size 和 family。

css3
body {
  font-family: "Helvetica Neue", Arial, sans-serif; /* fallback chain */
  font-size: 16px;
  font-weight: 400;     /* 100-900; 400=normal, 700=bold */
  font-style: italic;   /* normal | italic | oblique */
  line-height: 1.5;     /* unitless = multiplier of font-size */
  letter-spacing: 0.5px;
  word-spacing: 2px;
  font-variant: small-caps;
}

/* shorthand: style weight size/line-height family (order matters) */
p { font: italic 700 16px/1.5 "Georgia", serif; }

文本格式化

text-align: justify 可能产生空白河流;配合 hyphens: auto 可获得更整洁的块。text-decoration 现在接受行、样式和颜色的简写。white-space: nowrap 防止换行。text-shadow 接受 offset-x offset-y blur color。

css3
.text {
  text-align: justify;          /* left | right | center | justify */
  text-decoration: underline wavy red; /* line style color */
  text-decoration: line-through;
  text-transform: uppercase;    /* lowercase | capitalize */
  text-indent: 2em;             /* first-line indent */
  white-space: nowrap;          /* prevent wrapping */
  word-break: break-word;       /* break long words */
  hyphens: auto;                /* auto-hyphenate (needs lang attr) */
  text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}

文本溢出与省略号

单行截断需要三个属性:white-space: nowrap、overflow: hidden、text-overflow: ellipsis。多行截断使用 -webkit-line-clamp 配合 display: -webkit-box。需要 max-width 或 width 才能触发截断。

css3
.truncate {
  /* three properties required for ellipsis */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;    /* clip | ellipsis */
  max-width: 200px;
}

/* multi-line clamp (line-clamp) */
.clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;       /* limit to 3 lines */
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* custom fade effect */
.fade {
  -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent);
}

text-shadow 与效果

text-shadow 接受 offset-x offset-y blur-radius color。多个阴影分层,第一个在最上层——适用于霓虹光晕或文字描边(四方向阴影模拟描边)。硬阴影(无模糊)营造复古、贴纸般的美感。

css3
/* x-offset y-offset blur color */
.shadow { text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }

/* multiple shadows (first = top) */
.neon { text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff; }

/* 3D letterpress effect */
.letterpress { text-shadow: 0 1px 0 rgba(255,255,255,0.5); }

/* outline text (no blur, light color) */
.outline { text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; }

/* hard shadow retro effect */
.retro { text-shadow: 4px 4px 0 #ff6b6b; }

书写模式与方向

writing-mode 控制文字方向:horizontal-tb(默认)、vertical-rl(如传统中文/日文)或 vertical-lr。direction: rtl 处理阿拉伯语等从右到左的语言。逻辑属性自动适应书写模式和方向——对国际化布局至关重要。

css3
/* horizontal (default) */
.horizontal { writing-mode: horizontal-tb; }

/* vertical, top to bottom */
.vertical-rl { writing-mode: vertical-rl; }
.vertical-lr { writing-mode: vertical-lr; }

/* text direction */
.rtl { direction: rtl; unicode-bidi: bidi-override; }

/* logical properties adapt to writing mode */
.box {
  margin-inline-start: 10px;   /* logical left in LTR */
  padding-block: 20px;         /* logical top/bottom */
  inset-inline-end: 0;         /* logical right in LTR */
}
07

背景与渐变

背景简写

background 简写接受所有背景属性。同时使用 position 和 size 时用斜杠分隔(center/cover)。多个背景以逗号分隔分层,第一个声明在最上层。纯色应始终作为回退放在最后。

css3
.box {
  /* longhand */
  background-color: #fff;
  background-image: url("bg.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  background-attachment: fixed;
  
  /* shorthand (color image position/size repeat attachment) */
  background: #fff url("bg.png") center/cover no-repeat fixed;
}

/* multiple backgrounds (first = top layer) */
.multi {
  background: url("top.png") top left/contain no-repeat,
              url("bottom.png") bottom right/cover no-repeat #eee;
}

线性渐变

linear-gradient(direction, color-stops) 创建平滑过渡。方向可以是关键字(to right)或角度(45deg)。色标可包含百分比位置——两个色标放在同一位置创建硬边缘(非常适合条纹)。渐变是图像。

css3
/* direction or angle, then color stops */
.gradient { background: linear-gradient(to right, red, blue); }
.gradient-45 { background: linear-gradient(45deg, red, blue); }

/* multiple color stops */
.rainbow { background: linear-gradient(to right, red, orange, yellow, green, blue); }

/* color stops with positions */
.hard-stop { background: linear-gradient(to right, red 0%, red 50%, blue 50%, blue 100%); }

/* transparent stops for fade effects */
.fade { background: linear-gradient(to bottom, rgba(0,0,0,0.5), transparent); }

径向与锥形渐变

radial-gradient 从中心点向外辐射——适用于聚光灯和按钮。可定位中心(at top left)并控制形状/大小。conic-gradient 围绕中心点旋转颜色——非常适合饼图和色轮。

css3
/* radial: radiates from a center point */
.radial { background: radial-gradient(circle, red, blue); }
.radial-c { background: radial-gradient(circle at top left, #fff, #000); }
.radial-size { background: radial-gradient(closest-side, red, blue); }

/* conic: rotates around a center point */
.pie { background: conic-gradient(red 0% 30%, blue 30% 70%, green 70% 100%); }

/* conic with angle start */
.spin { background: conic-gradient(from 45deg, red, yellow, green, red); }

background-clip 与 origin

background-clip 控制背景延伸范围:border-box(默认)、padding-box 或 content-box。关键技巧:background-clip: text 配合 color: transparent 用渐变或图像填充文字。始终为 Safari 包含 -webkit- 前缀版本。

css3
/* clip: where the background paints */
.border-box { background-clip: border-box; } /* default - under border */
.padding-box { background-clip: padding-box; } /* inside border */
.content-box { background-clip: content-box; } /* inside padding */

/* text clip: gradient-filled text */
.gradient-text {
  background: linear-gradient(to right, red, blue);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* origin: where positioning starts */
.origin { background-origin: content-box; }

背景附着与视差

background-attachment: fixed 创建视差效果——背景固定而内容在其上滚动。scroll(默认)随元素移动;local 随元素内容滚动。fixed 附着在移动端效果卡顿且支持差;改用基于 transform 的视差。

css3
/* fixed: background stays put during scroll (parallax) */
.parallax {
  background-image: url("hero.jpg");
  background-attachment: fixed;
  background-size: cover;
  height: 100vh;
}

/* scroll: scrolls with element (default) */
.scroll { background-attachment: scroll; }

/* local: scrolls with element's content */
.local {
  background-attachment: local; /* scrolls with inner content */
}

/* NOTE: background-attachment: fixed has poor mobile support
   prefer transform-based parallax for mobile */
08

边框与圆角

边框圆角

border-radius 圆角,接受 1-4 个值(从左上顺时针)。斜杠分隔水平/垂直半径以实现椭圆角。正方形上 border-radius: 50% 创建完美圆形;矩形上为椭圆。圆角会裁剪背景、边框及(配合 overflow: hidden)子内容。

css3
.box { border-radius: 10px; }              /* all corners */
.box-2 { border-radius: 10px 20px; }        /* top-left/bottom-right  top-right/bottom-left */
.box-4 { border-radius: 10px 20px 30px 40px; } /* TL TR BR BL (clockwise) */

/* per-corner longhand */
.card {
  border-top-left-radius: 10px;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 30px;
  border-bottom-left-radius: 40px;
}

/* elliptical corners (horizontal / vertical) */
.ellipse { border-radius: 50px / 25px; }

/* perfect circle (square element) */
.circle { border-radius: 50%; }

边框图像

border-image 将图像切为 9 个区域并将角/边应用于边框。border-image-slice 切分源图像;repeat 控制边的平铺方式。常见的现代技巧:用 border-image 配合 linear-gradient 和 slice 1 创建渐变边框。

css3
.frame {
  border: 20px solid transparent;
  border-image-source: url("frame.png");
  border-image-slice: 30;        /* slice image into 9 regions */
  border-image-width: 20px;
  border-image-outset: 0;
  border-image-repeat: stretch;  /* stretch | repeat | round | space */
}

/* shorthand */
.frame-shorthand {
  border: 20px solid transparent;
  border-image: url("frame.png") 30 stretch;
}

/* gradient border (using border-image) */
.grad-border {
  border: 4px solid;
  border-image: linear-gradient(to right, red, blue) 1;
}

多重边框

CSS 无法堆叠多个 border 属性,但有变通方法。box-shadow 配合零偏移和扩展创建清晰的外边框(支持 border-radius)。outline 在外部绘制第二条边框,但忽略 border-radius。伪元素可完全控制包括圆角。

css3
/* technique 1: box-shadow (no rounded issue) */
.multi-shadow {
  box-shadow: 0 0 0 5px red, 0 0 0 10px blue;
}

/* technique 2: outline (outside border, no radius) */
.outline-border {
  border: 5px solid red;
  outline: 5px solid blue;
  outline-offset: 0;
}

/* technique 3: pseudo-element (full control) */
.pseudo-border {
  position: relative;
  border: 5px solid red;
}
.pseudo-border::after {
  content: "";
  position: absolute;
  inset: -10px;
  border: 5px solid blue;
  border-radius: inherit;
}

渐变边框

渐变边框较棘手,因为 border-image 不支持 border-radius。稳健方案:分层两个背景——一个裁剪到 padding-box 的纯色和一个裁剪到 border-box 的渐变,配合透明边框。此方案支持 border-radius 且到处可用。

css3
/* method 1: border-image (works but no border-radius) */
.grad-1 {
  border: 4px solid;
  border-image: linear-gradient(to right, red, blue) 1;
}

/* method 2: background-clip trick (works with radius) */
.grad-2 {
  border: 4px solid transparent;
  border-radius: 12px;
  background:
    linear-gradient(white, white) padding-box,
    linear-gradient(to right, red, blue) border-box;
}

/* method 3: mask + pseudo (advanced, supports radius + animation) */

轮廓与焦点样式

outline 绘制在边框外部且不影响布局,非常适合焦点指示器。outline-offset 添加间距。关键无障碍规则:绝不在没有可见替代方案时设置 outline: none。:focus-visible 仅对键盘导航显示轮廓。

css3
/* outline: doesn't affect layout, draws outside border */
.focusable:focus {
  outline: 2px solid blue;
  outline-offset: 2px;  /* gap between element and outline */
}

/* never use outline: none without a replacement */
button:focus { outline: none; box-shadow: 0 0 0 3px rgba(0,150,255,0.5); }

/* :focus-visible: only shows outline for keyboard users */
button:focus-visible { outline: 2px solid blue; outline-offset: 2px; }
button:focus:not(:focus-visible) { outline: none; }

/* outline shorthand */
.box { outline: 2px dashed red; }
09

变换

2D 变换

2D 变换——translate、rotate、scale、skew——移动和扭曲元素而不影响布局(兄弟元素不会重排)。组合变换从右向左应用,因此顺序很重要:rotate 在 translate 前会沿旋转轴移动。变换是 GPU 加速的,非常适合动画。

css3
.box { transform: translate(50px, 20px); }   /* move right 50, down 20 */
.box-x { transform: translateX(50px); }
.box-scale { transform: scale(1.5); }          /* grow 1.5x */
.box-scale-2 { transform: scale(1, 2); }       /* x 1, y 2 */
.box-rotate { transform: rotate(45deg); }      /* clockwise */
.box-skew { transform: skew(20deg, 10deg); }   /* skew x, y */

/* combine transforms (order matters!) */
.combo { transform: translate(20px, 0) rotate(45deg) scale(1.2); }

/* transform does NOT affect layout (no reflow) */

变换原点

transform-origin 设置变换的枢轴点——默认为元素中心。接受关键字(top left)、像素或百分比。改变原点会显著改变旋转和缩放行为:围绕顶边翻转的卡片需要 transform-origin: top。

css3
.box { transform: rotate(45deg); }

/* default origin: center center (50% 50%) */
.center { transform-origin: center center; }

/* rotate around top-left corner */
.tl { transform-origin: top left; transform: rotate(45deg); }

/* custom point (x y) */
.custom { transform-origin: 20px 50px; transform: rotate(45deg); }

/* 3-value form (x y z) */
.three-d { transform-origin: 0 0 100px; }

/* percentage-based */
.pct { transform-origin: 100% 0; } /* top-right corner */

3D 变换

3D 变换增加了 rotateX、rotateY、rotateZ、translateZ 和 scaleZ。perspective(n) 必须作为第一个变换函数(或在父级上)应用以启用深度——值越小 3D 效果越夸张。translate3d 和 scale3d 是 GPU 加速的。

css3
.card { transform: perspective(1000px) rotateY(45deg); }

/* rotateX/Y/Z - rotate around 3D axes */
.flip { transform: rotateX(180deg); }   /* flip horizontally */
.turn { transform: rotateY(180deg); }   /* flip like a page */
.spin { transform: rotateZ(90deg); }    /* same as rotate() */

/* translate3d (GPU-accelerated) */
.move { transform: translate3d(50px, 20px, 100px); }

/* scale3d */
.grow { transform: scale3d(1.5, 1.5, 1.5); }

/* combined 3D */
.combo-3d { transform: perspective(800px) rotateX(15deg) rotateY(-20deg) translateZ(-50px); }

透视与 3D 空间

perspective 定义观察者距离——越小 3D 越夸张。放在父级上使所有子级共享同一消失点。transform-style: preserve-3d 让嵌套元素存在于共享 3D 空间(构建立方体的关键)。backface-visibility: hidden 是翻转卡片效果的关键。

css3
/* perspective on parent: applies to all children uniformly */
.scene { perspective: 1000px; }
.cube { transform: rotateY(45deg); }

/* perspective() in transform: only affects that element */
.solo { transform: perspective(1000px) rotateY(45deg); }

/* perspective-origin: vanishing point */
.scene { perspective: 1000px; perspective-origin: top left; }

/* transform-style: preserve-3d lets children share 3D space */
.cube {
  transform-style: preserve-3d;
  transform: rotateY(30deg);
}
.cube .face { position: absolute; transform: translateZ(50px); }

/* backface-visibility: hide back of flipped element */
.card { backface-visibility: hidden; }

变换动画(性能)

始终动画 transform 和 opacity——它们是 GPU 加速的,不触发布局(重排)或绘制。动画 top/left/width/margin 会强制浏览器每帧重新计算布局,导致卡顿。will-change: transform 提示浏览器提前准备合成器层。

css3
/* GOOD: animate transform & opacity (GPU-accelerated) */
.smooth {
  transition: transform 0.3s ease;
}
.smooth:hover { transform: translateY(-5px); }

/* BAD: animating top/left triggers reflow */
.janky { transition: top 0.3s; }
.janky:hover { top: -5px; }

/* will-change: hint the browser to optimize */
.prepared {
  will-change: transform;  /* prepare for upcoming transform changes */
}

/* force GPU layer (use sparingly) */
.gpu { transform: translateZ(0); }
10

过渡

过渡简写

transition: property duration timing-function delay。默认为 all 0s ease 0s——因此只写 transition: 0.3s 即可动画所有更改的属性。为性能和控制,列出具体属性。多个过渡以逗号分隔。过渡放在元素默认状态上。

css3
.btn {
  background: blue;
  /* shorthand: property duration timing-function delay */
  transition: background 0.3s ease 0s;
  
  /* common usage */
  transition: all 0.3s ease;
  
  /* multiple properties (comma-separated) */
  transition: background 0.3s, transform 0.2s ease-out;
  
  /* list the same duration on many properties */
  transition: 0.3s;
}

.btn:hover {
  background: darkblue;
  transform: scale(1.05);
}

缓动函数

缓动函数控制加速度。ease(默认)平滑。ease-out 对 UI 感觉最灵敏(快开始,慢结束)。cubic-bezier(x1,y1,x2,y2) 可自定义曲线——y 轴上 0-1 之外的值产生过冲/弹跳。steps(n) 创建离散跳跃。

css3
.ease { transition: all 0.3s ease; }              /* default, smooth start/end */
.linear { transition: all 0.3s linear; }          /* constant speed */
.ease-in { transition: all 0.3s ease-in; }        /* slow start */
.ease-out { transition: all 0.3s ease-out; }      /* slow end (feels responsive) */
.ease-in-out { transition: all 0.3s ease-in-out; }/* slow both ends */

/* cubic-bezier: custom curve (P1x P1y P2x P2y) */
.custom { transition: all 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55); } /* overshoot */

/* steps: jump in increments */
.steps { transition: all 0.3s steps(4, end); }

多重与错开过渡

不同属性可有不同持续时间和延迟——适用于一个属性在另一个开始前完成的编排效果。transition-delay 为列表创建错开的入场;配合 nth-child 逐项递增延迟。

css3
.card {
  /* different durations per property */
  transition: transform 0.2s ease-out, box-shadow 0.4s ease;
  
  /* delay creates staggered effect */
  transition: background 0.3s, color 0.3s 0.1s; /* color starts after 0.1s */
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 30px rgba(0,0,0,0.2);
  background: #f5f5f5;
}

/* stagger multiple elements via transition-delay */
.item:nth-child(1) { transition-delay: 0s; }
.item:nth-child(2) { transition-delay: 0.1s; }
.item:nth-child(3) { transition-delay: 0.2s; }

可过渡属性

某些属性过渡平滑;另一些导致卡顿。GPU 加速的明星是 transform、opacity 和 filter。颜色和 box-shadow 还可(触发绘制而非布局)。避免过渡 width、height、margin、top、left——它们每帧强制布局重算。

css3
/* WELL-SUPPORTED & performant */
.good {
  transition: transform 0.3s, opacity 0.3s, filter 0.3s;
}

/* OK but may trigger paint */
.okay {
  transition: background-color 0.3s, color 0.3s, border-color 0.3s;
  transition: box-shadow 0.3s;
}

/* AVOID: triggers layout (reflow) - janky */
.bad {
  transition: width 0.3s, height 0.3s, margin 0.3s, top 0.3s, left 0.3s;
}

/* if you must animate size, use transform: scale() instead */
.smooth-resize { transition: transform 0.3s; }

过渡触发器

过渡在任何属性更改时触发:伪类状态(:hover、:focus、:checked)、类更改(由 JS 添加/移除)和媒体查询更改。它们在旧值和新值之间平滑插值。对于复杂、循环或多步运动,使用 @keyframes 动画。

css3
/* hover trigger */
.btn { transition: all 0.3s; }
.btn:hover { transform: scale(1.1); }

/* focus trigger (accessibility-friendly) */
.input { transition: border-color 0.2s; }
.input:focus { border-color: blue; }

/* class change via JavaScript */
.modal { transition: opacity 0.3s; opacity: 0; }
.modal.open { opacity: 1; }

/* media query trigger */
.box { transition: width 0.3s; width: 100%; }
@media (min-width: 768px) { .box { width: 50%; } }

/* CSS state triggers (:checked) */
.toggle:checked + .menu { transition: max-height 0.3s; max-height: 500px; }
11

动画

@keyframes 关键帧

@keyframes 定义动画序列。停止点可以是百分比(0%、50%、100%)或 from/to(等同于 0%/100%)。未在停止点列出的属性在已定义停止点之间插值。只有可动画属性(transform、opacity、颜色)有效。

css3
@keyframes bounce {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-30px); }
  100% { transform: translateY(0); }
}

/* from/to shorthand (2-stop) */
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* multiple properties at each stop */
@keyframes pulse {
  0%   { opacity: 1; transform: scale(1); }
  50%  { opacity: 0.5; transform: scale(1.1); }
  100% { opacity: 1; transform: scale(1); }
}

动画简写

animation 简写按此顺序打包 8 个属性:name duration timing-function delay iteration-count direction fill-mode play-state。至少需要 name 和 duration。第一个时间值是 duration,第二个是 delay。

css3
.bouncing {
  /* longhand */
  animation-name: bounce;
  animation-duration: 1s;
  animation-timing-function: ease-in-out;
  animation-delay: 0s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-fill-mode: both;
  animation-play-state: running;
  
  /* shorthand: name duration timing delay count direction fill-mode play-state */
  animation: bounce 1s ease-in-out 0s infinite alternate both running;
  
  /* minimal: name + duration */
  animation: bounce 1s;
}

迭代与方向

animation-iteration-count 控制重复——infinite 永远循环,小数值播放部分循环。animation-direction: alternate 在下一次迭代时正向然后反向播放动画,创建无缝弹跳。alternate 对脉冲等往返运动至关重要。

css3
/* iteration-count: how many times to play */
.once { animation-iteration-count: 1; }    /* default */
.thrice { animation-iteration-count: 3; }
.forever { animation-iteration-count: infinite; }
.fractional { animation-iteration-count: 0.5; } /* half a play */

/* direction */
.normal { animation-direction: normal; }       /* 0% -> 100% */
.reverse { animation-direction: reverse; }     /* 100% -> 0% */
.alternate { animation-direction: alternate; } /* forward, then backward */
.alternate-rev { animation-direction: alternate-reverse; }

动画填充模式

animation-fill-mode 控制动画运行前后的样式。none(默认)恢复元素正常样式。forwards 在结束后保持最终关键帧状态——对入场动画至关重要,避免元素突然回弹。backwards 在延迟期间应用第一个关键帧。

css3
@keyframes slideIn {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

/* none (default): reverts to original styles before/after */
.none { animation: slideIn 1s; }

/* forwards: holds the final (to) state after finishing */
.forwards { animation: slideIn 1s forwards; }

/* backwards: applies the (from) state during delay */
.backwards { animation: slideIn 1s 0.5s backwards; }

/* both: applies from during delay AND holds to after */
.both { animation: slideIn 1s 0.5s both; }

播放状态与暂停

animation-play-state: paused 在当前帧冻结动画;running 恢复。这是悬停暂停或通过 JS 切换类暂停的最简洁方式——动画记住位置而非重启。配合 reduced-motion 媒体查询以提升可访问性。

css3
.anim { animation: spin 2s linear infinite; }

/* pause on hover */
.anim:hover { animation-play-state: paused; }

/* pause via class (JS toggle) */
.anim.paused { animation-play-state: paused; }

/* useful for performance: pause off-screen animations */
.offscreen { animation-play-state: paused; }

/* resume */
.resumed { animation-play-state: running; }
12

媒体查询

基本语法

媒体查询条件性地应用样式。(min-width: 768px) 是移动优先——在 768px 及以上屏幕应用。用 and(两者须匹配)、逗号(或)、not(否定)组合。移动优先(min-width)方法首选:先写小屏基础样式,再为大屏增强。

css3
/* apply styles when viewport is at least 768px wide */
@media (min-width: 768px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
}

/* combine conditions with and */
@media (min-width: 768px) and (max-width: 1024px) {
  .box { padding: 20px; }
}

/* list of queries (OR) */
@media (max-width: 600px), (min-width: 1200px) {
  .text { font-size: 14px; }
}

/* negate with not */
@media not print {
  .screen-only { display: block; }
}

最小/最大宽度断点

断点应基于内容而非特定设备,但常见范围效果不错:640px(平板)、1024px(桌面)、1280px(大屏)。移动优先意味着使用 min-width 并以移动样式为基础。较新的范围语法(width >= 768px)更具可读性。

css3
/* common breakpoints (mobile-first) */
/* base styles (mobile) */
.container { padding: 16px; }

@media (min-width: 640px)  { /* small tablets */ 
  .container { padding: 24px; }
}
@media (min-width: 1024px) { /* desktops */
  .container { padding: 32px; max-width: 1200px; margin: 0 auto; }
}
@media (min-width: 1280px) { /* large screens */
  .container { max-width: 1400px; }
}

/* range syntax (newer, cleaner) */
@media (width >= 768px) and (width <= 1024px) {
  .box { padding: 20px; }
}

方向与宽高比

除宽度外,媒体查询还可针对方向(纵向/横向)、宽高比、悬停能力和指针类型。@media (hover: hover) 确保悬停样式仅在具有真实指针的设备上应用(避免触摸上的粘性悬停)。(pointer: coarse) 针对触摸设备——适合放大点击区域。

css3
/* portrait vs landscape */
@media (orientation: portrait) {
  .grid { grid-template-columns: 1fr; }
}
@media (orientation: landscape) {
  .grid { grid-template-columns: 1fr 1fr; }
}

/* aspect ratio */
@media (min-aspect-ratio: 16/9) {
  .video { width: 100%; height: auto; }
}

/* hover capability: devices that support hover */
@media (hover: hover) {
  .btn:hover { background: darkblue; }
}

/* pointer: fine (mouse) vs coarse (touch) */
@media (pointer: coarse) {
  .btn { padding: 16px 32px; } /* bigger tap targets */
}

打印样式

打印媒体查询设置打印时的页面外观。隐藏导航、广告和交互元素;将内容扩展到全宽;强制黑底白字以节省墨水。break-inside: avoid 防止元素跨页拆分。链接上的 ::after 技巧在打印中显示 URL。

css3
@media print {
  /* hide non-essential UI */
  .nav, .sidebar, .ads, .comments { display: none; }
  
  /* expand main content */
  .main { width: 100%; margin: 0; }
  
  /* force black text on white */
  body { color: black; background: white; }
  
  /* avoid breaking inside elements */
  h1, h2, img, table { break-inside: avoid; }
  
  /* page breaks before sections */
  h1 { break-before: page; }
  
  /* show URLs after links */
  a[href]::after { content: " (" attr(href) ")"; }
}

prefers-reduced-motion 与 color-scheme

prefers-reduced-motion 是关键无障碍功能——前庭疾病用户需要最小化运动。始终提供禁用或缩短动画的 reduced-motion 回退。prefers-color-scheme 让你自动适应用户的操作系统主题。

css3
/* respect users who prefer less motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* light/dark mode */
@media (prefers-color-scheme: dark) {
  body { background: #1a1a1a; color: #eee; }
  .card { background: #2a2a2a; }
}

@media (prefers-color-scheme: light) {
  body { background: white; color: #333; }
}
13

响应式设计

使用 clamp() 实现流式排版

clamp(min, preferred, max) 创建在边界之间流式缩放的值——非常适合无需媒体查询即可自适应的排版和间距。首选值通常是基于 vw 的表达式。这消除了许多断点。配合 rem 以提升可访问性。

css3
/* clamp(min, preferred, max) - fluid between bounds */
h1 {
  /* scales from 1.5rem to 3rem as viewport grows */
  font-size: clamp(1.5rem, 5vw, 3rem);
}

p {
  /* readable body text on any screen */
  font-size: clamp(1rem, 2.5vw, 1.25rem);
}

/* fluid spacing */
.section {
  padding: clamp(1rem, 4vw, 3rem);
}

/* fluid container width */
.container {
  width: clamp(280px, 90vw, 1200px);
  margin: 0 auto;
}

移动优先方法

移动优先意味着以小屏样式为基础,然后用 min-width 媒体查询为大屏增强。这产生更精简的 CSS(移动端只下载所需内容)并迫使内容优先的思维。桌面优先(max-width)强制移动设备下载并覆盖桌面样式。

css3
/* base = mobile styles (no media query) */
.card {
  width: 100%;
  padding: 12px;
  font-size: 14px;
}

/* progressively enhance for larger screens */
@media (min-width: 640px) {
  .card { width: 50%; padding: 16px; }
}

@media (min-width: 1024px) {
  .card { width: 33.33%; padding: 24px; font-size: 16px; }
}

/* AVOID desktop-first (forces mobile to override) */
/* @media (max-width: 640px) { ... } */

容器查询

容器查询是颠覆性的:让组件根据父级尺寸而非视口响应。卡片无论是在窄侧边栏还是宽主区域都能自适应布局——真正的组件级响应式。container-type: inline-size 查询宽度(最高性能)。

css3
/* make an element a query container */
.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

/* styles based on the container's size, not the viewport */
@container sidebar (min-width: 400px) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}

/* inline-size = width only (most common, performant) */
/* size = both dimensions (more expensive) */

/* unnamed container query (uses nearest ancestor) */
.card-wrap { container-type: inline-size; }
@container (min-width: 500px) {
  .card { flex-direction: row; }
}

视口单位

vh/vw 是视口的百分比。问题:移动端 100vh 随地址栏显示/隐藏而变化,导致卡顿。较新的 svh/lvh/dvh 单位修复了此问题——dvh 动态更新,svh 使用最小稳定值。始终通过 calc 或 clamp 为 vw 字号设置 rem/px 下限。

css3
.hero {
  height: 100vh;        /* full viewport height */
  /* small viewport units: account for mobile browser chrome */
  height: 100svh;       /* smallest possible viewport (stable) */
  height: 100lvh;       /* largest possible viewport */
  height: 100dvh;       /* dynamic - updates as chrome shows/hides */
}

.full-width { width: 100vw; }
.responsive-font { font-size: 5vw; }

/* vmin/vmax: smaller/larger of width or height */
.square { width: 50vmin; height: 50vmin; }
.banner { height: 30vmax; }

/* combining with calc for safety */
.hero-text { font-size: calc(16px + 2vw); }

宽高比

aspect-ratio 自动保持宽高比——不再需要响应式视频的 padding-top hack。元素高度由宽度(或反之)派生。配合图片上的 object-fit: cover,可防止图片加载时的布局偏移。这是为媒体预留空间并避免 CLS(核心 Web 指标)的最简洁方式。

css3
/* maintain a 16:9 ratio regardless of width */
.video {
  aspect-ratio: 16 / 9;
  width: 100%;
}

/* square avatar */
.avatar {
  aspect-ratio: 1;
  width: 80px;
  border-radius: 50%;
}

/* golden ratio card */
.card {
  aspect-ratio: 1.618;
}

/* combined with object-fit for responsive images */
.thumb {
  aspect-ratio: 4 / 3;
  width: 100%;
  object-fit: cover;
}
14

自定义属性(变量)

定义与使用变量

CSS 自定义属性(变量)用 --name 声明,用 var(--name) 使用。在 :root 上定义以全局访问,或作用于任何元素。与预处理器变量不同,它们是实时的:更改变量会实时更新所有使用处,且它们会层叠和继承。var() 接受第二个参数作为回退。

css3
:root {
  --primary: #3490dc;
  --spacing: 16px;
  --max-width: 1200px;
}

.button {
  background: var(--primary);
  padding: var(--spacing);
  /* with fallback value (used if --primary undefined) */
  color: var(--text-color, #333);
}

/* override in a specific scope */
.dark-theme {
  --primary: #5a9fee;
}

主题与深色模式

自定义属性使主题化变得简单:定义语义变量(--bg、--text、--primary),然后在 [data-theme] 选择器中覆盖。切换 <html> 上的 data-theme 属性可瞬间切换整个主题——无需重复样式表。配合 prefers-color-scheme 实现自动深色模式。

css3
:root {
  --bg: #ffffff;
  --text: #1a1a1a;
  --primary: #3490dc;
}

[data-theme="dark"] {
  --bg: #1a1a1a;
  --text: #ffffff;
  --primary: #5a9fee;
}

body {
  background: var(--bg);
  color: var(--text);
}

/* auto dark mode via media query */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1a1a1a;
    --text: #ffffff;
  }
}

层叠与继承

自定义属性像普通 CSS 一样层叠和继承。在 .card 上定义的变量可用于 .card 及所有后代——但不能用于兄弟。每个元素读取自身作用域的计算值。@property(较新)可声明带语法、初始值和继承标志的类型化变量——支持自定义属性的平滑过渡。

css3
:root { --color: blue; }       /* global */
.card { --color: green; }      /* scoped to .card */
.card .inner { color: var(--color); } /* green - inherits from .card */

/* variables inherit like other properties */
.parent { --size: 20px; }
.child { font-size: var(--size); } /* 20px via inheritance */

/* but: each element reads its own computed value */
.a { --x: 10px; }
.b { /* --x is NOT defined here, even if .a is sibling */ }

/* @property: typed variables with initial value */
@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

JavaScript 交互

CSS 变量完全可从 JavaScript 访问。用 getComputedStyle(el).getPropertyValue(--name) 读取(返回字符串,常有前导空格——需 trim)。用 el.style.setProperty(--name, value) 设置。这使自定义属性成为强大的 JS 到 CSS 桥梁。

css3
/* read a variable */
const styles = getComputedStyle(document.documentElement);
const primary = styles.getPropertyValue("--primary"); /* "#3490dc" */

/* set a variable globally */
document.documentElement.style.setProperty("--primary", "#ff0000");

/* set on a specific element */
el.style.setProperty("--spacing", "24px");

/* inline style with variable */
<div style="--rotate: 45deg"></div>

/* useful pattern: expose JS values to CSS */
.root { --scroll: 0; }
.box { transform: rotate(calc(var(--scroll) * 1deg)); }

回退与链式

var() 支持第二个参数作为回退,仅在变量未定义时使用(而非无效时——无效值会使整个属性回退到默认值)。回退可链式:var(--a, var(--b, #default))。用 @supports (--x: 0) 检测支持,尽管所有现代浏览器都支持自定义属性。

css3
.box {
  /* single fallback */
  color: var(--undefined, #333);
  
  /* chained: try --primary, fall back to --blue, then #00f */
  color: var(--primary, var(--blue, #0000ff));
  
  /* fallback in calc() */
  width: calc(100% - var(--sidebar, 250px));
  
  /* invalid values fall back to inherited/default */
  /* var() itself doesn't fail — the property does */
}

/* feature detection for custom property support */
@supports (--custom: property) {
  :root { --modern: true; }
}
15

滤镜

滤镜函数

filter 为元素应用视觉效果。brightness/contrast/saturate 接受乘数(1 = 正常)或百分比。hue-rotate 按角度旋转所有色相。多个滤镜从左到右链式。常见用途:悬停时灰度图片、复古照片效果或调暗背景。

css3
.blur { filter: blur(4px); }              /* gaussian blur in px */
.bright { filter: brightness(1.5); }     /* 1 = normal, >1 brighter */
.contrast { filter: contrast(200%); }    /* 100% = normal */
.gray { filter: grayscale(100%); }       /* 0-100% */
.sepia { filter: sepia(80%); }
.hue { filter: hue-rotate(90deg); }      /* rotate hue */
.invert { filter: invert(100%); }        /* invert colors */
.saturate { filter: saturate(2); }       /* 1 = normal */
.opacity { filter: opacity(50%); }

/* combine multiple filters (left-to-right) */
.vintage { filter: sepia(60%) contrast(110%) brightness(90%) saturate(1.2); }

drop-shadow

drop-shadow 是 box-shadow 的滤镜等价物——但它遵循元素的实际 alpha 形状而非盒子。这意味着阴影会贴合 PNG/SVG 抠图和不规则形状。用于图标阴影、发光徽标或任何非矩形元素。它可能比 box-shadow 更昂贵,请谨慎使用。

css3
/* drop-shadow follows the alpha shape (unlike box-shadow) */
.cutout {
  filter: drop-shadow(4px 4px 8px rgba(0,0,0,0.4));
}

/* shadows on PNG with transparency - hugs the shape */
.logo {
  filter: drop-shadow(0 4px 6px rgba(0,0,0,0.3));
}

/* glow effect on text or SVG */
.icon {
  filter: drop-shadow(0 0 8px rgba(0, 150, 255, 0.8));
}

/* multiple drop-shadows layer */
.deep {
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.5))
          drop-shadow(0 2px 4px rgba(0,0,0,0.3));
}

backdrop-filter

backdrop-filter 对元素后面的所有内容应用滤镜——毛玻璃效果的标志。半透明背景配合 backdrop-filter: blur() 创建磨砂玻璃外观。始终为 Safari 包含 -webkit- 前缀。元素背景需要一定透明度才能显示效果。

css3
/* frosted glass effect */
.glass {
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px); /* Safari */
  border: 1px solid rgba(255, 255, 255, 0.3);
}

/* saturate + blur for vivid glass */
.vivid-glass {
  backdrop-filter: blur(16px) saturate(180%);
}

/* dark glass for dark mode */
.dark-glass {
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(12px);
}

组合滤镜

多个滤镜从左到右应用,因此顺序影响结果(例如灰度在色相旋转之前没有可旋转的内容)。滤镜可动画且 GPU 加速——非常适合悬停效果。将 filter 与 mix-blend-mode 配合可将元素与背景混合。

css3
/* order matters: each filter feeds the next */
.artsy {
  filter: grayscale(100%) contrast(150%) brightness(110%);
}

/* animate filters smoothly */
img { transition: filter 0.3s; }
img:hover { filter: grayscale(0%) saturate(1.4); }

/* use CSS variables for dynamic filters */
.dynamic { filter: var(--photo-filter, none); }

/* layer with other effects */
.complex {
  filter: blur(1px) brightness(1.1);
  mix-blend-mode: multiply;
  opacity: 0.9;
}

滤镜性能

滤镜是 GPU 加速的但并非免费。全屏元素上的大模糊会导致大量重绘和卡顿,尤其在移动端。保持模糊半径小,限制滤镜区域,并在触发动画前应用 will-change: filter。backdrop-filter 特别昂贵——用于小 UI 元素而非整个部分。

css3
/* AVOID: large blur on full-screen elements */
.janky { filter: blur(20px); } /* causes repaints */

/* BETTER: pre-blurred image, or limit blur area */
.smooth {
  filter: blur(2px); /* small radius is cheaper */
}

/* backdrop-filter is expensive - use sparingly */
/* contain: paint can limit repaint area */
.contained {
  contain: paint;
  backdrop-filter: blur(10px);
}

/* will-change prepares the GPU layer */
.prepared {
  will-change: filter;
  filter: blur(4px);
}
16

伪元素

::before 与 ::after

::before 和 ::after 在元素实际内容前后插入生成内容。content 属性是必需的(即使是空字符串用于装饰元素)。内容可以是文本、转义 Unicode 或通过 attr() 的属性值。这些伪元素默认为内联——设置 display: block 以实现盒状装饰。

css3
.quote::before { content: "\201C"; }  /* opening quote */
.quote::after  { content: "\201D"; }  /* closing quote */

/* icon via Unicode */
.warning::before { content: "\26A0"; margin-right: 6px; }

/* decorative element with content: "" */
.card::after {
  content: "";
  display: block;
  width: 50px; height: 2px;
  background: currentColor;
  margin-top: 12px;
}

/* content can use attributes */
a[href^="http"]::after {
  content: " (" attr(href) ")";
  font-size: 0.8em;
}

::first-letter 与 ::first-line

::first-letter 为首字符设置样式——非常适合文章中的首字下沉。::first-line 为第一个格式化行设置样式,随视口宽度变化动态调整。两者仅对块级元素生效。它们是编辑布局的排版要素。

css3
article p::first-letter {
  font-size: 3em;
  font-weight: bold;
  float: left;
  line-height: 0.8;
  margin-right: 8px;
  /* drop cap effect */
}

article p::first-line {
  text-transform: uppercase;
  letter-spacing: 1px;
  font-weight: bold;
}

/* only works on block-level elements */
/* affects the first formatted line (reflows with width) */

::selection

::selection 为用户高亮的文本部分设置样式。只有少数属性适用:color、background-color、text-shadow 和 text-decoration。用于将选择颜色品牌化为与网站匹配。用 ::selection 全局应用或作用于特定元素。

css3
/* style highlighted/selected text */
::selection {
  background: #b3d4fc;
  color: black;
  text-shadow: none;
}

/* scoped to specific elements */
p::selection { background: yellow; }
.highlight::selection { background: gold; color: #333; }

/* note: only a few properties work:
   color, background-color, text-shadow, 
   text-decoration (and its longhands) */

/* firefox historically used ::-moz-selection */

::placeholder 与 ::marker

::placeholder 为表单输入中的占位符文本设置样式——设置 opacity: 1,因为 Firefox 默认半透明。::marker 为列表项的项目符号或编号设置样式,支持有限的属性集(color、content、font、direction)。可用自定义内容替换项目符号。

css3
/* style input placeholder text */
input::placeholder {
  color: #999;
  font-style: italic;
  opacity: 1; /* Firefox applies opacity < 1 by default */
}

/* style list item markers (bullets/numbers) */
ul li::marker {
  color: red;
  font-size: 1.2em;
  content: "\25CF"; /* custom bullet */
}

ol li::marker {
  content: counter(list-item) ". ";
  color: blue;
  font-weight: bold;
}

/* ::marker supports: color, content, font properties,
   direction, unicode-bidi, text-transform, white-space */

生成内容与计数器

通过 ::before/::after 的生成内容可包含 counter() 值、属性值(attr())或字符串字面量——实现无需额外 DOM 的纯 CSS 编号、图标和工具提示。counters() 生成 1.2.3 等嵌套编号。用 attr(data-tooltip) 和悬停过渡构建的工具提示是 JS 库的轻量替代方案。

css3
/* counter in generated content */
h2::before {
  content: "Section " counter(section) ": ";
  color: gray;
}

/* attr() reads HTML attributes */
a::after {
  content: attr(data-icon);
}

/* counters() for nested numbering */
ol { counter-reset: item; }
li { display: block; }
li::before {
  content: counters(item, ".") " ";
  counter-increment: item;
}

/* CSS-only tooltip */
.tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  background: black; color: white;
  padding: 4px 8px;
  opacity: 0; transition: opacity 0.2s;
}
.tooltip:hover::after { opacity: 1; }
17

计数器

counter-reset 与 counter-increment

CSS 计数器让你无需 JavaScript 即可为元素编号。counter-reset 初始化计数器(默认为 0,但可从其他值开始)。counter-increment 增加它(默认加 1,但任何整数都行——甚至负数)。用 content 中的 counter() 显示值。计数器作用于重置它的元素及其后代。

css3
body { counter-reset: section; }   /* initialize to 0 */

h2 {
  counter-increment: section;  /* +1 each h2 */
}

h2::before {
  content: "Section " counter(section) ": ";
}

/* custom increment value */
ol { counter-reset: item; }
li { counter-increment: item 1; }  /* +1 (default) */
li.big { counter-increment: item 2; } /* +2 */

/* reset to a custom starting value */
.start-5 { counter-reset: item 4; } /* next increment = 5 */

counter() 函数

counter(name) 输出计数器的当前值,counter(name, style) 应用列表样式:decimal(默认)、lower/upper-alpha、lower/upper-roman、disc、square 等。可并行运行多个计数器并在 content 中组合——非常适合按章节编号的图表(图 3-2)。

css3
body { counter-reset: section; }
h2 { counter-increment: section; }
h2::before {
  content: "Chapter " counter(section) ". ";
  color: navy;
}

/* counter style (decimal, lower-alpha, upper-roman, etc.) */
h2::before {
  content: counter(section, upper-roman) ". ";
}

/* multiple counters */
body { counter-reset: section figure; }
h2 { counter-increment: section; }
figcaption { counter-increment: figure; }
figcaption::before {
  content: "Figure " counter(section) "-" counter(figure) ": ";
}

使用 counters() 的嵌套计数器

counters(name, separator) 是嵌套计数器函数:它在每个祖先作用域连接计数器值,用给定字符串分隔。这自动生成 1.2.3 等大纲——相同的计数器名称在每个嵌套 <ol> 上重置。分隔符可以是任何字符串,如 . 或 -。

css3
ol { counter-reset: item; list-style: none; }
li::before {
  counter-increment: item;
  /* counters() concatenates ancestor counters with separator */
  content: counters(item, ".") " ";
}

/* produces: 1 / 1.1 / 1.2 / 2 / 2.1 / 2.1.1 ... */
<ol>
  <li>Item
    <ol>
      <li>Sub-item</li>
      <li>Sub-item</li>
    </ol>
  </li>
  <li>Item</li>
</ol>

/* custom separator */
li::before { content: counters(item, "-") ": "; }

计数器样式

计数器支持许多内置样式:decimal、upper-roman、lower-alpha、lower-greek、cjk-decimal 等。@counter-style 让你用符号集、系统(cyclic、additive、extends)和 pad(前导零)、prefix/suffix、range 等选项定义自定义样式。适合主题列表、emoji 项目符号或本地化编号。

css3
/* built-in styles */
.decimal { content: counter(c, decimal); }
.roman { content: counter(c, upper-roman); }       /* I, II, III */
.alpha { content: counter(c, lower-alpha); }        /* a, b, c */
.greek { content: counter(c, lower-greek); }        /* alpha, beta, gamma */
.cjk { content: counter(c, cjk-decimal); }          /* CJK numerals */

/* @counter-style: define a custom style */
@counter-style thumbs {
  system: cyclic;
  symbols: "\1F44D"; /* thumbs up emoji */
  suffix: " ";
}
.like-list { list-style-type: thumbs; }

/* leading zeros via pad */
@counter-style padded {
  system: extends decimal;
  pad: 3 "0"; /* 001, 002, ... */
}

实用计数器模式

计数器在编号步骤指示器、目录和大纲中表现出色。用圆形徽章、颜色和编号设置 ::before 样式,无需手动编号即可创建编号步骤列表。编辑 DOM 后编号自动更新。计数器值无法轻易被 JavaScript 读取——它们仅用于显示。

css3
/* numbered steps */
.steps { counter-reset: step; }
.steps li { counter-increment: step; }
.steps li::before {
  content: counter(step);
  display: inline-block;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--primary);
  color: white;
  text-align: center;
  line-height: 28px;
  margin-right: 10px;
}

/* "you've completed N sections" via counters (limited - 
   counters can't be read by JS easily, use them for display) */
18

多列布局

column-count 与 column-width

多列布局将内容流入报纸式的列中。column-count 固定列数;column-width 让浏览器创建尽可能多的 250px 列(无需媒体查询即可响应)。简写 columns 接受 count 和/或 width。多列适合长篇阅读文本,但短内容可能导致列高不均。

css3
.article {
  /* fixed number of columns */
  column-count: 3;
  
  /* OR width-based (browser decides count) */
  column-width: 250px;
  
  /* shorthand (count width) */
  columns: 3 250px;
  columns: 3;       /* 3 columns */
  columns: 250px;   /* 250px columns, auto count */
}

/* responsive: width lets columns collapse on small screens */
.fluid { column-width: 200px; } /* 1 column on mobile, more on desktop */

column-gap 与 column-rule

column-gap 设置列之间的间距(flexbox 和 grid 现在也使用)。column-rule 在间距中绘制垂直分隔线——它是 border 的列等价物,具有相同的简写。该线不占额外宽度;居中位于间距中。

css3
.article {
  column-count: 3;
  column-gap: 30px;          /* space between columns */
  
  /* divider line (like border) */
  column-rule: 1px solid #ddd; /* shorthand */
  column-rule-width: 1px;
  column-rule-style: solid;
  column-rule-color: #ddd;
}

/* rule sits in the gap, doesn't add width */

column-span

column-span: all 使元素跨越所有列——非常适合杂志风格的标题,列在其上下方流动。column-span: none(默认)保持内容在列中流动。注意这可能导致显著重排;请彻底测试。

css3
.article {
  column-count: 3;
}

/* heading spans all columns (like a magazine) */
.article h2 {
  column-span: all;
  /* resets above the heading, columns resume below */
}

/* default: content flows through columns */
.normal { column-span: none; }

/* note: column-span: all can cause reflow and is 
   not supported in older Firefox */

break-inside 与列分隔

多列内容可能尴尬地在列之间拆分元素。break-inside: avoid 使元素(如卡片或图)在一列内保持完整。break-before/break-after: column 强制列分隔。较旧的 page-break-* 属性作为别名工作。break-inside: avoid 是现代的正确方法。

css3
/* prevent an element from splitting across columns */
.card {
  break-inside: avoid;        /* modern */
  -webkit-column-break-inside: avoid; /* old webkit */
  page-break-inside: avoid;   /* old */
  display: inline-block;      /* hack for older browsers */
  width: 100%;
}

/* control where columns break */
h2 { break-after: column; }   /* force new column after */
h3 { break-before: column; }  /* force new column before */
p  { break-inside: avoid; }   /* keep paragraph together */

column-fill 与平衡

column-fill 控制内容如何在列之间分配。balance(默认)均衡高度,使列尾大致对齐——视觉整洁。auto 在移到下一列前完全填满第一列,需要固定高度;这匹配打印行为。平衡列更适合一般用途。

css3
.article {
  column-count: 3;
  
  /* balance: equalize column heights (default in most browsers) */
  column-fill: balance;
  
  /* auto: fill first column fully, then next (needs height) */
  column-fill: auto;
  height: 500px; /* required for auto */
}

/* balanced columns look neat but can split awkwardly;
   auto is more like print, fills top-to-bottom */
19

用户界面

轮廓与无障碍

可见的焦点指示器是无障碍要求。:focus-visible 仅对键盘用户(非鼠标)显示轮廓,是焦点样式的最佳实践。绝不在没有替代方案时设置 outline: none(如 box-shadow 环)。outline-offset 在元素和轮廓之间添加间距。

css3
/* visible focus ring for keyboard users */
button:focus-visible {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

/* never outline: none without a replacement */
/* custom focus ring via box-shadow */
button:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.5);
}

/* outline shorthand */
.outlined { outline: 2px dashed red; outline-offset: 4px; }

/* thick rounded outline (modern browsers) */
button:focus-visible {
  outline: 3px solid blue;
  outline-offset: 2px;
  border-radius: 4px;
}

resize

resize 控制用户是否可拖动调整元素大小。textarea 默认可调整;设置 resize: none 禁用。vertical/horizontal/both 约束方向。要使 resize 工作,元素必须具有非 visible 的 overflow。适用于文本域、代码编辑器或任何用户可调整的面板。

css3
textarea {
  /* allow vertical resize only (default for textarea) */
  resize: vertical;
  
  /* allow both axes */
  resize: both;
  
  /* horizontal only */
  resize: horizontal;
  
  /* disable resizing */
  .locked { resize: none; }
  
  /* default: inline/block elements can't be resized;
     textarea default is both in most browsers */
}

/* note: resize only works on overflow != visible */

caret-color 与 user-select

caret-color 设置可编辑元素中闪烁光标的颜色——为品牌表单增添小细节。user-select 控制文本是否可选择:none 禁用(用于 UI 控件),all 单击时选择整个元素(适合代码块或电子邮件)。避免在 body 上使用 user-select: none——它损害可访问性。

css3
/* color of the text cursor in inputs */
input, textarea {
  caret-color: #0066cc;  /* default: current color */
}

/* custom thick caret (limited support) */
input { caret-color: red; }

/* control text selection by the user */
.no-select { user-select: none; }        /* disable selection */
.select-all { user-select: all; }        /* select whole element on click */
.select-text { user-select: text; }      /* normal text selection */
.select-contain { user-select: contain; } /* selection stays within */

/* email addresses, code blocks often user-select: all */

appearance 与表单样式

appearance: none 去除表单控件的原生 OS 样式,让你完全用 CSS 设置样式——对跨浏览器一致的表单设计至关重要。去除原生 select 箭头后,添加自定义 background-image。自定义复选框使用 appearance: none 配合 :checked。始终加 -webkit-/-moz- 前缀以完全支持。

css3
/* remove native widget styling */
input, select, button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

/* custom select arrow (after removing native) */
select {
  background-image: url("arrow.svg");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 30px;
}

/* style checkbox/radio with appearance: none */
input[type="checkbox"] {
  appearance: none;
  width: 20px; height: 20px;
  border: 2px solid #999;
  border-radius: 4px;
}
input[type="checkbox"]:checked {
  background: var(--primary);
  border-color: var(--primary);
}

scroll-behavior 与滚动条

在 <html> 上设置 scroll-behavior: smooth 使锚链接点击动画到目标而非跳转——配合 prefers-reduced-motion 为敏感用户禁用。自定义滚动条:标准 scrollbar-width/scrollbar-color 属性在 Firefox 和现代 Chrome 中工作;::-webkit-scrollbar 伪元素在 WebKit/Blink 中提供更精细控制。

css3
/* smooth scrolling for anchor links */
html { scroll-behavior: smooth; }

/* respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* custom scrollbar (WebKit) */
.scroll-area::-webkit-scrollbar { width: 8px; }
.scroll-area::-webkit-scrollbar-track { background: #f1f1f1; }
.scroll-area::-webkit-scrollbar-thumb { background: #888; border-radius: 4px; }
.scroll-area::-webkit-scrollbar-thumb:hover { background: #555; }

/* standard scrollbar-color (Firefox + spec) */
.scroll-area {
  scrollbar-width: thin;
  scrollbar-color: #888 #f1f1f1;
}
20

高级与现代特性

滚动捕捉

Scroll Snap 无需 JavaScript 即可创建轮播式或全页滚动。scroll-snap-type: x/y + mandatory/proximity 控制轴和严格度。带 scroll-snap-align 的子项捕捉到 start/center/end。mandatory 强制捕捉(适合全页部分);proximity 仅在接近时捕捉(更温和,适合图片库)。

css3
.gallery {
  scroll-snap-type: x mandatory;  /* snap horizontally, must snap */
  overflow-x: auto;
  display: flex;
}

.gallery > img {
  scroll-snap-align: center;   /* start | center | end */
  scroll-snap-stop: always;    /* can't skip snaps */
  flex: 0 0 80%;
}

/* vertical full-page snap */
.pages {
  scroll-snap-type: y mandatory;
  height: 100vh;
  overflow-y: scroll;
}
.page { scroll-snap-align: start; height: 100vh; }

/* proximity: only snaps when close (gentler) */
.soft { scroll-snap-type: y proximity; }

object-fit 与 object-position

object-fit 控制 <img> 或 <video> 如何填充其盒子——background-size 的媒体等价物。cover 填充盒子并裁剪溢出;contain 适配整个媒体(可能有空白);fill 拉伸(扭曲)。object-position 设置焦点——当 cover 裁剪重要部分时有用。这消除了响应式媒体的 background-image hack。

css3
/* cover: fill box, crop overflow (like background-size: cover) */
.avatar img {
  width: 100px; height: 100px;
  object-fit: cover;        /* cover | contain | fill | none | scale-down */
  object-position: center;  /* position the focal point */
  border-radius: 50%;
}

/* contain: whole image visible, may letterbox */
.preview img {
  width: 300px; height: 200px;
  object-fit: contain;
  background: #eee;
}

/* object-position shifts the visible area */
.banner img {
  width: 100%; height: 300px;
  object-fit: cover;
  object-position: top;  /* show top of image */
}

will-change

will-change 向浏览器提示某个属性即将变化,让其预分配 GPU 层并优化。在动画前应用,动画后移除——在许多元素上永久使用会浪费内存并可能损害性能。只列出实际会动画的属性(transform、opacity、filter)。

css3
/* hint that an element will animate transform */
.card { will-change: transform; }

/* remove when not needed (frees GPU memory) */
.card.idle { will-change: auto; }

/* multiple properties */
.complex { will-change: transform, opacity; }

/* AVOID: permanent will-change on many elements */
/* .all { will-change: transform, opacity, top, left; } */ /* bad */

/* apply just before animation, remove after */
.prepare { will-change: transform; }
/* JS: el.classList.add('prepare'); 
   setTimeout(() => el.classList.remove('prepare'), 1000); */

contain

contain 告诉浏览器某个元素独立于页面其余部分,启用重大性能优化——contained 元素内的更改不会触发其外的重算。layout、paint、style 和 size 是隔离类型。strict(全部四种,包括 size)最强。将 contain 应用于重复的小部件、列表项或广告以限制重排/重绘成本。

css3
/* isolate an element's layout/paint/style from the rest */
.widget {
  contain: layout paint style;  /* or: strict, content */
  
  /* size: the element's size is independent of its children */
  contain: size;  /* needs explicit dimensions */
}

/* layout: changes inside don't affect outside layout */
/* paint: children don't render outside the box (clipped) */
/* style: counters and quotes are scoped */
/* size: element ignores children for sizing */

/* full isolation */
.isolated { contain: strict; } /* = size layout paint style */
.content-isolated { contain: content; } /* = layout paint style */

/* useful for performance on complex widgets, lists, ads */

aspect-ratio 与通用 gap

aspect-ratio 在任何元素上保持宽高比,防止媒体加载时的布局偏移。gap(及其长写 row-gap/column-gap)是现代间距工具,在 flexbox、grid 和多列中工作——消除了 .item + margin + :last-child hack。这两个特性普遍支持,共同解决了两个最常见的 CSS 痛点。

css3
/* aspect-ratio works on any element */
.video-wrap {
  aspect-ratio: 16 / 9;
  background: black;
}

/* gap works in flex, grid, and multi-column */
.flex { display: flex; gap: 16px; }
.grid { display: grid; gap: 16px; }
.cols { column-count: 3; column-gap: 16px; }

/* row-gap / column-gap longhands */
.layout {
  display: grid;
  row-gap: 24px;
  column-gap: 16px;
}

/* gap replaced margin-based spacing hacks */
/* (no more .item:last-child { margin-right: 0 }) */

这篇内容对您有帮助吗?

学习路径

从零开始学习

通过结构化课程从头学习这个语言。