modern-css

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Modern CSS

现代CSS

This skill provides a reference for writing modern, robust, and efficient CSS.

本技能为编写现代、健壮且高效的CSS提供参考。

Layout & Responsive Design

布局与响应式设计

Container Queries

Container Queries

css
.card {
  container: --my-card / inline-size;
}

@container --my-card (width < 40ch) {
  /* Component-based responsive design */
}

@container (20ch < width < 50ch) {
  /* Range syntax */
}
Container units:
cqi
,
cqb
,
cqw
,
cqh
- size relative to container dimensions
Anchored container queries: Style positioned elements based on anchor fallback state
css
.tooltip {
  container-type: anchored;
}

@container anchored(top) {
  /* Styles when positioned at top */
}
css
.card {
  container: --my-card / inline-size;
}

@container --my-card (width < 40ch) {
  /* 基于组件的响应式设计 */
}

@container (20ch < width < 50ch) {
  /* 范围语法 */
}
容器单位:
cqi
cqb
cqw
cqh
- 相对于容器尺寸的单位
锚定容器查询: 根据锚点回退状态为定位元素设置样式
css
.tooltip {
  container-type: anchored;
}

@container anchored(top) {
  /* 定位在顶部时的样式 */
}

Media Query Range Syntax

媒体查询范围语法

css
@media (width <= 1024px) { }
@media (360px < width < 1024px) { }
css
@media (width <= 1024px) { }
@media (360px < width < 1024px) { }

Grid Enhancements

Grid增强特性

  • Subgrid: Inherit parent grid lines for nested layouts
  • Masonry:
    display: grid-lanes
    for Pinterest-style layouts with logical tab order. (Previously proposed as
    grid-template-rows: masonry
    ).

  • Subgrid: 继承父级网格线用于嵌套布局
  • Masonry: 使用
    display: grid-lanes
    实现Pinterest式布局,同时保持合理的标签顺序。(此前提案为
    grid-template-rows: masonry

Color & Theming

颜色与主题

Color Scheme & Light-Dark Function

配色方案与light-dark函数

css
:root {
  color-scheme: light dark;
  --surface-1: light-dark(white, #222);
  --text-1: light-dark(#222, #fff);
}
css
:root {
  color-scheme: light dark;
  --surface-1: light-dark(white, #222);
  --text-1: light-dark(#222, #fff);
}

Modern Color Spaces

现代颜色空间

css
/* OKLCH: uniform brightness, P3+ colors */
.vibrant {
  background: oklch(72% 75% 330);
}

/* Display-P3 for HDR displays */
@media (dynamic-range: high) {
  .neon {
    --neon-red: color(display-p3 1 0 0);
  }
}

/* Better gradients with in oklch */
.gradient {
  background: linear-gradient(
    to right in oklch,
    color(display-p3 1 0 .5),
    color(display-p3 0 1 1)
  );
}
css
/* OKLCH:亮度均匀,支持P3+色域 */
.vibrant {
  background: oklch(72% 75% 330);
}

/* 为HDR显示器使用Display-P3 */
@media (dynamic-range: high) {
  .neon {
    --neon-red: color(display-p3 1 0 0);
  }
}

/* 使用oklch实现更自然的渐变 */
.gradient {
  background: linear-gradient(
    to right in oklch,
    color(display-p3 1 0 .5),
    color(display-p3 0 1 1)
  );
}

Color Manipulation

颜色操作

css
/* color-mix() */
.lighten {
  background: color-mix(in oklab, var(--brand), white);
}

/* Relative color syntax */
.lighter {
  background: oklch(from blue calc(l + .25) c h);
  background: oklch(from blue 75% c h); /* Set to specific lightness */
}

.semi-transparent {
  background: oklch(from var(--color) l c h / 50%);
}

.complementary {
  background: hsl(from blue calc(h + 180) s l);
}
css
/* color-mix() */
.lighten {
  background: color-mix(in oklab, var(--brand), white);
}

/* 相对颜色语法 */
.lighter {
  background: oklch(from blue calc(l + .25) c h);
  background: oklch(from blue 75% c h); /* 设置为特定亮度 */
}

.semi-transparent {
  background: oklch(from var(--color) l c h / 50%);
}

.complementary {
  background: hsl(from blue calc(h + 180) s l);
}

Accent Color

强调色

css
:root {
  accent-color: hotpink; /* Tints checkboxes, radios, range inputs */
}

css
:root {
  accent-color: hotpink; /* 为复选框、单选框、范围输入框着色 */
}

Typography

排版

Text Wrapping

文本换行

css
h1 {
  text-wrap: balance; /* Balanced multi-line headings */
  max-inline-size: 25ch;
}

p {
  text-wrap: pretty; /* No orphans */
  max-inline-size: 50ch;
}
css
h1 {
  text-wrap: balance; /* 平衡多行标题 */
  max-inline-size: 25ch;
}

p {
  text-wrap: pretty; /* 避免孤行 */
  max-inline-size: 50ch;
}

Text Box Trim

文本框修剪

css
h1, p, button {
  text-box: trim-both cap alphabetic; /* Optical vertical centering */
}
css
h1, p, button {
  text-box: trim-both cap alphabetic; /* 光学垂直居中 */
}

Fluid Typography

流体排版

css
.heading {
  font-size: clamp(1rem, 1rem + 0.5vw, 2rem); /* Respects user preferences */
}
css
.heading {
  font-size: clamp(1rem, 1rem + 0.5vw, 2rem); /* 尊重用户偏好设置 */
}

Dynamic Viewport Units

动态视口单位

  • dvh
    /
    dvw
    - Dynamic (accounts for mobile browser UI)
  • svh
    /
    svw
    - Small (smallest possible viewport)
  • lvh
    /
    lvw
    - Large (largest possible viewport)

  • dvh
    /
    dvw
    - 动态视口(考虑移动浏览器UI)
  • svh
    /
    svw
    - 最小视口(最小可能的视口尺寸)
  • lvh
    /
    lvw
    - 最大视口(最大可能的视口尺寸)

Animations & Motion

动画与动效

Scroll-Driven Animation

滚动驱动动画

css
/* Animate on scroll position */
.parallax {
  animation: slide-up linear both;
  animation-timeline: scroll();
}

/* Animate on viewport intersection */
.fade-in {
  animation: fade linear both;
  animation-timeline: view();
  animation-range: cover -75cqi contain 20cqi;
}
css
/* 根据滚动位置执行动画 */
.parallax {
  animation: slide-up linear both;
  animation-timeline: scroll();
}

/* 根据视口相交状态执行动画 */
.fade-in {
  animation: fade linear both;
  animation-timeline: view();
  animation-range: cover -75cqi contain 20cqi;
}

View Transitions

View Transitions

Status: Baseline Newly Available (Same-document). Cross-document transitions are in Limited Availability (Chrome/Safari 18.2+).
css
@view-transition {
  navigation: auto; /* Automatically animate page transitions (MPAs) */
}

nav {
  view-transition-name: --persist-nav; /* Persist specific elements */
  view-transition-class: --site-header; /* Group transitions with classes */
}

/* Style the active transition */
html:active-view-transition {
  overflow: hidden;
}
Nested View Transition Groups: Preserve 3D transforms and clipping during transitions.
状态: 同文档过渡已正式可用;跨文档过渡处于有限可用状态(Chrome/Safari 18.2+支持)。
css
@view-transition {
  navigation: auto; /* 自动为多页面应用(MPA)添加页面过渡动画 */
}

nav {
  view-transition-name: --persist-nav; /* 保留特定元素状态 */
  view-transition-class: --site-header; /* 使用类对过渡效果分组 */
}

/* 为活跃的过渡设置样式 */
html:active-view-transition {
  overflow: hidden;
}
嵌套View Transition组: 过渡期间保留3D变换和裁剪效果。

Advanced Easing with linear()

使用linear()实现高级缓动

css
.springy {
  --spring: linear(
    0, 0.14 4%, 0.94 17%, 1.15 24% 30%, 1.02 43%, 0.98 51%, 1 77%, 1
  );
  transition: transform 1s var(--spring);
}
css
.springy {
  --spring: linear(
    0, 0.14 4%, 0.94 17%, 1.15 24% 30%, 1.02 43%, 0.98 51%, 1 77%, 1
  );
  transition: transform 1s var(--spring);
}

@starting-style

@starting-style

css
.dialog {
  transition: opacity .5s, scale .5s;

  @starting-style {
    opacity: 0;
    scale: 1.1;
  }
}

css
.dialog {
  transition: opacity .5s, scale .5s;

  @starting-style {
    opacity: 0;
    scale: 1.1;
  }
}

Custom Properties & Advanced Features

自定义属性与高级特性

@property

@property

Type-safe, animatable custom properties:
css
@property --gradient-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.animate {
  transition: --gradient-angle 1s ease;

  &:hover {
    --gradient-angle: 360deg;
  }
}
类型安全、可动画的自定义属性:
css
@property --gradient-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.animate {
  transition: --gradient-angle 1s ease;

  &:hover {
    --gradient-angle: 360deg;
  }
}

Math Functions & calc-size()

数学函数与calc-size()

Newly Available:
calc-size()
allows calculations and transitions on intrinsic sizes (auto, min-content).
css
/* Finally: Animate to auto height! */
.accordion-content {
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease;
}

.accordion-item.open .accordion-content {
  height: calc-size(auto);
}

.radial-layout {
  --_angle: calc(var(--sibling-index) * var(--_offset));
  translate:
    calc(cos(var(--_angle)) * var(--_circle-size))
    calc(sin(var(--_angle)) * var(--_circle-size));
}
新特性:
calc-size()
支持对固有尺寸(auto、min-content)进行计算和过渡。
css
/* 终于可以实现自动高度的动画了! */
.accordion-content {
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease;
}

.accordion-item.open .accordion-content {
  height: calc-size(auto);
}

.radial-layout {
  --_angle: calc(var(--sibling-index) * var(--_offset));
  translate:
    calc(cos(var(--_angle)) * var(--_circle-size))
    calc(sin(var(--_angle)) * var(--_circle-size));
}

Tree Counting Functions (Coming Soon)

树形计数函数(即将推出)

css
.staggered {
  animation-delay: calc(sibling-index() * .1s);
  background-color: hsl(sibling-count() 50% 50%);
}
css
.staggered {
  animation-delay: calc(sibling-index() * .1s);
  background-color: hsl(sibling-count() 50% 50%);
}

Conditional CSS with if() (Coming Soon)

使用if()实现条件CSS(即将推出)

css
.dynamic {
  color: if(
    style(--theme: dark),
    white,
    black
  );
}

css
.dynamic {
  color: if(
    style(--theme: dark),
    white,
    black
  );
}

Architecture & Organization

架构与组织

Cascade Layers

级联层

css
@layer reset, design-system, components, utilities;

@import "open-props/colors" layer(design-system);
@import "components/nav/base.css" layer(components.nav);

@layer components.nav.primary {
  nav {
    position: sticky;
    inset-block-start: 0;
  }
}
Benefits:
  • Import third-party CSS with lower specificity
  • Organize styles by concern, not selector weight
  • Nested layers create clear hierarchies

css
@layer reset, design-system, components, utilities;

@import "open-props/colors" layer(design-system);
@import "components/nav/base.css" layer(components.nav);

@layer components.nav.primary {
  nav {
    position: sticky;
    inset-block-start: 0;
  }
}
优势:
  • 以更低优先级引入第三方CSS
  • 按关注点组织样式,而非选择器权重
  • 嵌套层创建清晰的层级结构

Interactive Components

交互组件

Dialog

Dialog

html
<dialog id="modal">
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="confirm">Confirm</button>
  </form>
</dialog>

<button commandfor="modal" command="showModal">Open</button>
<button commandfor="modal" command="close">Close</button>
New:
closedby
attribute enables light-dismiss behavior
html
<dialog id="modal">
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="confirm">Confirm</button>
  </form>
</dialog>

<button commandfor="modal" command="showModal">Open</button>
<button commandfor="modal" command="close">Close</button>
新特性:
closedby
属性支持轻触关闭行为

Popover

Popover

html
<button popovertarget="menu">Show Menu</button>
<div popover id="menu">...</div>
popover=hint: Ephemeral tooltips that don't dismiss other popovers
css
[popover] {
  transition:
    display .5s allow-discrete,
    overlay .5s allow-discrete,
    opacity .5s;

  @starting-style {
    &:popover-open {
      opacity: 0;
    }
  }
}
html
<button popovertarget="menu">Show Menu</button>
<div popover id="menu">...</div>
popover=hint: 临时提示框,不会关闭其他弹出层
css
[popover] {
  transition:
    display .5s allow-discrete,
    overlay .5s allow-discrete,
    opacity .5s;

  @starting-style {
    &:popover-open {
      opacity: 0;
    }
  }
}

Anchor Positioning

锚点定位

css
.tooltip-anchor {
  anchor-name: --tooltip;
}

.tooltip[popover] {
  position-anchor: --tooltip;
  position-area: block-start;
  position-try-fallbacks: flip-block;
  position-try-order: most-height;
}
Pseudo-elements:
anchor()
,
::scroll-button()
,
::scroll-marker()
css
.tooltip-anchor {
  anchor-name: --tooltip;
}

.tooltip[popover] {
  position-anchor: --tooltip;
  position-area: block-start;
  position-try-fallbacks: flip-block;
  position-try-order: most-height;
}
伪元素:
anchor()
::scroll-button()
::scroll-marker()

Exclusive Accordion

互斥手风琴组件

html
<details name="accordion">...</details>
<details name="accordion">...</details>
<!-- Only one can be open at a time -->
html
<details name="accordion">...</details>
<details name="accordion">...</details>
<!-- 同一时间只能打开一个 -->

Customizable Select

可自定义的Select

css
select {
  appearance: base-select; /* Full CSS control */
}

/* Style options with rich HTML */
select option::before {
  content: ""; /* Can include images, icons */
}
css
select {
  appearance: base-select; /* 完全由CSS控制样式 */
}

/* 使用富HTML为选项设置样式 */
select option::before {
  content: ""; /* 可包含图片、图标 */
}

Search Element

搜索元素

html
<search>
  <form>
    <input type="search" name="q">
    <button type="submit">Search</button>
  </form>
</search>

html
<search>
  <form>
    <input type="search" name="q">
    <button type="submit">Search</button>
  </form>
</search>

Form Enhancements

表单增强

Field Sizing

字段尺寸

css
textarea, select, input {
  field-sizing: content; /* Auto-grow to content */
}

textarea {
  min-block-size: 3lh; /* Line-height units */
  max-block-size: 80dvh;
}
css
textarea, select, input {
  field-sizing: content; /* 自动适应内容尺寸 */
}

textarea {
  min-block-size: 3lh; /* 基于行高的单位 */
  max-block-size: 80dvh;
}

Better Validation Pseudo-Classes

更完善的验证伪类

css
/* Wait for user interaction before showing errors */
:user-invalid {
  outline-color: red;
}

:user-valid {
  outline-color: green;
}

label:has(+ input:user-invalid) {
  text-decoration: underline wavy red;
}
css
/* 等待用户交互后再显示错误状态 */
:user-invalid {
  outline-color: red;
}

:user-valid {
  outline-color: green;
}

label:has(+ input:user-invalid) {
  text-decoration: underline wavy red;
}

HR in Select

Select中的HR分隔线

html
<select>
  <option>Option 1</option>
  <hr>
  <option>Option 2</option>
</select>

html
<select>
  <option>Option 1</option>
  <hr>
  <option>Option 2</option>
</select>

Visual Effects

视觉效果

Scrollbar Styling

滚动条样式

css
.custom-scrollbar {
  scrollbar-color: hotpink transparent;
  scrollbar-width: thin;
}
css
.custom-scrollbar {
  scrollbar-color: hotpink transparent;
  scrollbar-width: thin;
}

Shape Function

Shape函数

css
.complex-clip {
  clip-path: shape(
    from 0% 0%,
    curve by 50% 25% via 25% 50%,
    line to 100% 100%
  );
}
css
.complex-clip {
  clip-path: shape(
    from 0% 0%,
    curve by 50% 25% via 25% 50%,
    line to 100% 100%
  );
}

Corner Shapes

边角形状

css
.fancy-corners {
  corner-shape: squircle;
  corner-shape: notch;
  corner-shape: scoop;
  corner-shape: superellipse(0.7);
}

css
.fancy-corners {
  corner-shape: squircle;
  corner-shape: notch;
  corner-shape: scoop;
  corner-shape: superellipse(0.7);
}

Progressive Enhancement Patterns

渐进增强模式

Feature Detection

特性检测

css
@supports (animation-timeline: view()) {
  .fade-in {
    animation: fade linear both;
    animation-timeline: view();
  }
}

@supports (container-type: inline-size) {
  .responsive-card {
    container-type: inline-size;
  }
}
css
@supports (animation-timeline: view()) {
  .fade-in {
    animation: fade linear both;
    animation-timeline: view();
  }
}

@supports (container-type: inline-size) {
  .responsive-card {
    container-type: inline-size;
  }
}

Respect User Preferences

尊重用户偏好

css
@media (prefers-reduced-motion: no-preference) {
  .animated {
    animation: slide 1s ease;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #222;
  }
}

@media (prefers-contrast: more) {
  .text {
    font-weight: 600;
  }
}

css
@media (prefers-reduced-motion: no-preference) {
  .animated {
    animation: slide 1s ease;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #222;
  }
}

@media (prefers-contrast: more) {
  .text {
    font-weight: 600;
  }
}

Checking Browser Support: Baseline

浏览器兼容性检查:Baseline

What is Baseline? A unified way to understand cross-browser feature availability. Features are marked as:
  • Widely Availabl: Supported in the last 2.5 years of all major browsers
  • Newly Availab: Available in all major browsers
  • Limited Availability: Not yet in all browsers
什么是Baseline? 一种统一了解跨浏览器特性支持情况的方式。特性分为以下几类:
  • 广泛可用: 所有主流浏览器近2.5年内的版本均支持
  • 新可用: 所有主流浏览器均已支持
  • 有限可用: 尚未在所有浏览器中支持

How to Check Baseline Status

如何检查Baseline状态

  1. BEST: Fetch https://web-platform-dx.github.io/web-features-explorer/groups/ and find the feature in there, then fetch it's detail page.
  2. Can I Use: caniuse.com shows Baseline badges at the top of each feature
  3. MDN: Look for the Baseline badge in the browser compatibility table
  4. web.dev: Feature articles include Baseline status
Remember: Always check Baseline status, use
@supports
for cutting-edge features, and respect user preferences with media queries. Modern CSS is about progressive enhancement and building resilient interfaces that work for everyone.

  1. 最佳方式: 访问https://web-platform-dx.github.io/web-features-explorer/groups/,查找对应特性并查看详情页。
  2. Can I Use: caniuse.com的每个特性页面顶部会显示Baseline标识
  3. MDN: 浏览器兼容性表格中会标注Baseline标识
  4. web.dev: 特性文章中会包含Baseline状态信息
注意: 始终检查Baseline状态,对前沿特性使用
@supports
进行兼容处理,并通过媒体查询尊重用户偏好。现代CSS的核心是渐进增强,构建能为所有人服务的健壮界面。

Real-World Example: Modern Component

实战示例:现代组件

Here's a card component using many modern CSS features:
css
/* Cascade layer for organization */
@layer components.card {

  /* Custom properties with @property */
  @property --card-hue {
    syntax: "<number>";
    inherits: false;
    initial-value: 200;
  }

  .card {
    /* Container for responsive design */
    container: card / inline-size;

    /* Logical properties */
    inline-size: 100%;
    padding-inline: var(--space-md);
    padding-block: var(--space-lg);

    /* Modern color system */
    background: light-dark(
      oklch(98% 0.02 var(--card-hue)),
      oklch(20% 0.02 var(--card-hue))
    );

    /* Border with relative color */
    border: 1px solid oklch(from var(--surface) calc(l * 0.9) c h);

    /* Smooth corners */
    border-radius: var(--radius-md);

    /* View transition */
    view-transition-name: --card;

    /* Scroll-driven animation */
    animation: fade-in linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 30%;

    /* Anchor for tooltips */
    anchor-name: --card-anchor;

    /* Transition custom property */
    transition: --card-hue 0.5s var(--ease-spring-3);

    &:hover {
      --card-hue: 280;
    }

    /* Responsive typography in container */
    @container card (width > 30ch) {
      .card__title {
        font-size: clamp(1.5rem, 3cqi, 2.5rem);
        text-wrap: balance;
      }
    }

    @container card (width < 30ch) {
      .card__image {
        aspect-ratio: 16 / 9;
        object-fit: cover;
      }
    }
  }

  .card__title {
    /* Text box trim for optical alignment */
    text-box: trim-both cap alphabetic;
    text-wrap: balance;

    /* Logical margin */
    margin-block-end: var(--space-sm);
  }

  .card__body {
    text-wrap: pretty;
    max-inline-size: 65ch;
  }

  .card__cta {
    /* Inherit font */
    font: inherit;

    /* Accent color */
    accent-color: var(--brand);

    /* Field sizing */
    field-sizing: content;

    /* Logical properties */
    padding-inline: var(--space-md);
    padding-block: var(--space-sm);

    /* Modern color with relative syntax */
    background: oklch(from var(--brand) l c h);
    color: oklch(from var(--brand) 95% 0.05 h);

    &:hover {
      background: oklch(from var(--brand) calc(l * 1.1) c h);
    }

    &:user-invalid {
      outline: 2px solid light-dark(red, #ff6b6b);
    }
  }

  /* Popover tooltip anchored to card */
  .card__tooltip[popover] {
    position-anchor: --card-anchor;
    position-area: block-start;
    position-try-fallbacks: flip-block;

    /* Entry animation */
    @starting-style {
      opacity: 0;
      scale: 0.9;
    }

    transition:
      opacity 0.2s,
      scale 0.2s,
      display 0.2s allow-discrete,
      overlay 0.2s allow-discrete;
  }

  /* Scroll state container queries */
  @supports (container-type: scroll-state) {
    .card__sticky-header {
      container-type: scroll-state;
      position: sticky;
      inset-block-start: 0;

      @container scroll-state(stuck: top) {
        box-shadow: 0 2px 8px oklch(0% 0 0 / 0.1);
      }
    }
  }

  /* Respect user preferences */
  @media (prefers-reduced-motion: reduce) {
    .card {
      animation: none;
      transition: none;
    }
  }

  @media (prefers-contrast: more) {
    .card {
      border-width: 2px;
    }
  }
}

/* Keyframes for scroll animation */
@keyframes fade-in {
  from {
    opacity: 0;
    scale: 0.95;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}
以下是一个使用了多项现代CSS特性的卡片组件:
css
/* 使用级联层组织代码 */
@layer components.card {

  /* 使用@property定义自定义属性 */
  @property --card-hue {
    syntax: "<number>";
    inherits: false;
    initial-value: 200;
  }

  .card {
    /* 响应式设计的容器 */
    container: card / inline-size;

    /* 逻辑属性 */
    inline-size: 100%;
    padding-inline: var(--space-md);
    padding-block: var(--space-lg);

    /* 现代颜色系统 */
    background: light-dark(
      oklch(98% 0.02 var(--card-hue)),
      oklch(20% 0.02 var(--card-hue))
    );

    /* 使用相对颜色设置边框 */
    border: 1px solid oklch(from var(--surface) calc(l * 0.9) c h);

    /* 平滑圆角 */
    border-radius: var(--radius-md);

    /* View Transition */
    view-transition-name: --card;

    /* 滚动驱动动画 */
    animation: fade-in linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 30%;

    /* 为提示框设置锚点 */
    anchor-name: --card-anchor;

    /* 自定义属性的过渡动画 */
    transition: --card-hue 0.5s var(--ease-spring-3);

    &:hover {
      --card-hue: 280;
    }

    /* 容器内的响应式排版 */
    @container card (width > 30ch) {
      .card__title {
        font-size: clamp(1.5rem, 3cqi, 2.5rem);
        text-wrap: balance;
      }
    }

    @container card (width < 30ch) {
      .card__image {
        aspect-ratio: 16 / 9;
        object-fit: cover;
      }
    }
  }

  .card__title {
    /* 文本框修剪实现光学对齐 */
    text-box: trim-both cap alphabetic;
    text-wrap: balance;

    /* 逻辑外边距 */
    margin-block-end: var(--space-sm);
  }

  .card__body {
    text-wrap: pretty;
    max-inline-size: 65ch;
  }

  .card__cta {
    /* 继承字体样式 */
    font: inherit;

    /* 强调色 */
    accent-color: var(--brand);

    /* 字段尺寸 */
    field-sizing: content;

    /* 逻辑属性 */
    padding-inline: var(--space-md);
    padding-block: var(--space-sm);

    /* 使用相对语法的现代颜色 */
    background: oklch(from var(--brand) l c h);
    color: oklch(from var(--brand) 95% 0.05 h);

    &:hover {
      background: oklch(from var(--brand) calc(l * 1.1) c h);
    }

    &:user-invalid {
      outline: 2px solid light-dark(red, #ff6b6b);
    }
  }

  /* 锚定到卡片的弹出提示框 */
  .card__tooltip[popover] {
    position-anchor: --card-anchor;
    position-area: block-start;
    position-try-fallbacks: flip-block;

    /* 入场动画 */
    @starting-style {
      opacity: 0;
      scale: 0.9;
    }

    transition:
      opacity 0.2s,
      scale 0.2s,
      display 0.2s allow-discrete,
      overlay 0.2s allow-discrete;
  }

  /* 滚动状态容器查询 */
  @supports (container-type: scroll-state) {
    .card__sticky-header {
      container-type: scroll-state;
      position: sticky;
      inset-block-start: 0;

      @container scroll-state(stuck: top) {
        box-shadow: 0 2px 8px oklch(0% 0 0 / 0.1);
      }
    }
  }

  /* 尊重用户偏好 */
  @media (prefers-reduced-motion: reduce) {
    .card {
      animation: none;
      transition: none;
    }
  }

  @media (prefers-contrast: more) {
    .card {
      border-width: 2px;
    }
  }
}

/* 滚动动画的关键帧 */
@keyframes fade-in {
  from {
    opacity: 0;
    scale: 0.95;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

HTML for the Example

示例对应的HTML

html
<article class="card">
  <img
    class="card__image"
    src="image.jpg"
    alt="Description"
    loading="lazy"
  >

  <h2 class="card__title">Card Title</h2>

  <p class="card__body">
    Card description with pretty text wrapping that avoids orphans.
  </p>

  <button
    class="card__cta"
    popovertarget="card-tooltip"
  >
    Learn More
  </button>

  <div
    class="card__tooltip"
    popover="hint"
    id="card-tooltip"
  >
    Additional information appears here
  </div>
</article>
html
<article class="card">
  <img
    class="card__image"
    src="image.jpg"
    alt="Description"
    loading="lazy"
  >

  <h2 class="card__title">Card Title</h2>

  <p class="card__body">
    Card description with pretty text wrapping that avoids orphans.
  </p>

  <button
    class="card__cta"
    popovertarget="card-tooltip"
  >
    Learn More
  </button>

  <div
    class="card__tooltip"
    popover="hint"
    id="card-tooltip"
  >
    Additional information appears here
  </div>
</article>

Canonical Resources

权威资源

Usage Guidelines

使用指南

  1. Prioritize Stability:
    • Recommend Newly Available or Widely Available features for production code.
    • Use Limited Availability features with progressive enhancement, graceful degredation, or
      @supports
      . Or ask the user how they want to handle it.
  2. Use the web platform:
    • Always prefer standard CSS solutions over JavaScript libraries for layout, animation, and interaction (e.g., use CSS Masonry instead of Masonry.js, Popover API instead of custom tooltip scripts).
  3. Code Style:
    • Use modern color spaces (
      oklch
      ) for new palettes.
  1. 优先选择稳定特性:
    • 生产环境推荐使用新可用广泛可用的特性。
    • 有限可用的特性,需结合渐进增强、优雅降级或
      @supports
      使用,或询问用户的处理偏好。
  2. 优先使用Web平台原生方案:
    • 对于布局、动画和交互需求,始终优先选择标准CSS解决方案而非JavaScript库(如使用CSS Masonry而非Masonry.js,使用Popover API而非自定义提示框脚本)。
  3. 代码风格:
    • 新配色方案优先使用现代颜色空间(
      oklch
      )。