wui
组件

宽高比 Aspect Ratio

在响应式弹性布局中为图片、视频播放器或媒体卡片锁定固定的宽高比例,防止页面布局抖动(CLS)。

第三方依赖 · radix-ui

基础用法

锁定内容容器为标准的 16 / 9 宽屏比例:

海岸山丘

安装与引入

通过 CLI 自动添加组件,或手动复制源码至项目中:

pnpm dlx @wui-design/cli@latest add @wui/aspect-ratio
安装基础依赖
pnpm add radix-ui clsx tailwind-merge
复制组件源码到 components/ui/aspect-ratio.tsx
components/ui/aspect-ratio.tsx
"use client"

import * as React from "react"
import { AspectRatio as AspectRatioPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

export interface AspectRatioProps extends React.ComponentProps<
  typeof AspectRatioPrimitive.Root
> {
  /** 宽度与高度的比例,例如 16 / 9。@default 1 */
  ratio?: number
}

/** 在响应式宽度下保持媒体或内容的固定宽高比。 */
function AspectRatio({ className, ratio = 1, ...props }: AspectRatioProps) {
  return (
    <AspectRatioPrimitive.Root
      data-slot="aspect-ratio"
      ratio={ratio}
      className={cn("relative overflow-hidden", className)}
      {...props}
    />
  )
}

export { AspectRatio }

属性 Props

AspectRatio (根组件)

继承原生 <div> 元素的全部 HTML 属性:

属性类型默认值说明
rationumber1期望维持的宽度与高度的比值(例如 16 / 9、4 / 3、1 或 4 / 5)。
classNamestring—应用于外层比例容器的额外 CSS 类名(如添加圆角 overflow-hidden 或背景色)。

事件 Events

继承原生 <div> 容器的全部标准 HTML 事件:

属性类型默认值说明
onClick(event: React.MouseEvent<HTMLDivElement>) => void—点击宽高比容器时触发。

使用场景与设计规范

AspectRatio 是消除网页累积布局偏移(Cumulative Layout Shift, CLS)的核心利器:

  • 防止异步图片加载抖动:当图片从网络下载完成前,浏览器由于不知道图片实际高度往往会造成排版塌陷与跳动。通过 AspectRatio 提前占位,页面能保持绝对稳定的布局流。
  • 常见比例建议:
    • 16 / 9:标准横屏视频、B站/YouTube 封面、幻灯片投影。
    • 4 / 3:经典摄影作品、复古画幅。
    • 1 / 1(即 1):商品方形展示图、头像裁剪区、Instagram 帖子。
    • 4 / 5 或 9 / 16:短视频封面、小红书/TikTok 移动端瀑布流。
  • 内部媒体填充规范:容器内部的 <img> 或 <video> 标签推荐设置 className="size-full object-cover",确保在任何屏幕宽度下都能填满比例容器且不变形。

场景示例

视频媒体卡片与播放覆盖层

结合 16:9 比例封面、时长角标与悬停播放按钮;比例容器自带 overflow-hidden,封面悬停放大不会溢出:

Loading…

多比例媒体画廊 (4:5, 1:1, 3:2)

展示不同内容形态下的标准比例排版:

Loading…

无障碍与交互 Accessibility

  • 内容无障碍优先:AspectRatio 本身仅作为纯 CSS 几何布局包装容器,不产生额外的 ARIA 语义。
  • 图片 Alt 属性要求:内部嵌入的 <img> 标签必须提供清晰准确的 alt 描述文本;若为纯装饰性背景,请显式提供 alt="" 并设置 aria-hidden="true"。