- UI组件
- 前端
【免费下载链接】ant-design-blazor
🌈A rich set of enterprise-class UI components based on Ant Design and Blazor.
导读
骨架屏(Skeleton)是页面在数据加载完成前展示的占位图形组合,而Active动画效果让这些灰色占位块产生从左向右的流光扫过动效,显著降低用户等待时的焦躁感。本文以 ant-design-blazor 官方演示 active.md 为切入点,完整讲解Skeleton组件Active参数的用法、底层 CSS 动画实现原理、主题变量定制方法,并结合仓库源码与官方示例给出可直接落地的实战方案。读完本文,你将掌握在 Blazor 项目中一键开启骨架屏流光动画、精确控制动画节奏与颜色,以及组合Loading状态完成平滑加载过渡的完整能力。
一、什么是 Active 动画效果
官方演示文档对active这一示例的描述只有一句话:"显示动画效果"(Display active animation)。它对应的示例代码位于 Active.razor,全貌如下:
<Skeleton Active="true"></Skeleton>一行代码即可让默认的标题 + 段落骨架块产生流光扫过的动画。在 ant-design-blazor 中,这背后由Skeleton组件的Active布尔参数驱动,其参数定义位于 Skeleton.razor.cs:
/// <summary> /// Display active animation or not /// </summary> [Parameter] public bool Active { get; set; }当Active为true时,组件会在根节点上追加ant-skeleton-active样式类,该逻辑同样在 Skeleton.razor.cs 的SetClassMap中实现:
private void SetClassMap() { ClassMapper .Add("ant-skeleton") .If("ant-skeleton-with-avatar", () => this.Avatar) .If("ant-skeleton-active", () => this.Active) .If("ant-skeleton-rtl", () => RTL); }因此Active的作用本质上是一个"开关":决定是否让骨架屏内部的标题、段落、头像等占位元素套用流光动画样式。
二、底层原理:流光动画的 CSS 实现
动画效果本身并不依赖任何 JavaScript 或 Blazor 交互逻辑,而是完全由 Less 样式编译后的 CSS 完成。核心代码位于骨架屏的样式入口文件 index.less,其中定义了激活态的选择器与动画规则:
// With active animation &-active { .@{skeleton-title-prefix-cls}, .@{skeleton-paragraph-prefix-cls} > li, .@{skeleton-avatar-prefix-cls}, .@{skeleton-button-prefix-cls}, .@{skeleton-input-prefix-cls}, .@{skeleton-image-prefix-cls} { .skeleton-color(); } }可以看到,只要根元素带有ant-skeleton-active类,标题(-title)、段落行(-paragraph > li)、头像(-avatar)、按钮(-button)、输入框(-input)和图片(-image)等所有占位元素都会被套上.skeleton-color()这个 mixin。该 mixin 与配套的 keyframes 定义如下:
.skeleton-color() { position: relative; z-index: 0; overflow: hidden; background: transparent; &::after { position: absolute; top: 0; right: -150%; bottom: 0; left: -150%; background: linear-gradient( 90deg, @skeleton-color 25%, @skeleton-to-color 37%, @skeleton-color 63% ); animation: ~'@{skeleton-prefix-cls}-loading' 1.4s ease infinite; content: ''; } } @keyframes ~"@{skeleton-prefix-cls}-loading" { 0% { transform: translateX(-37.5%); } 100% { transform: translateX(37.5%); } }其工作原理可以拆解为四步:
- 伪元素覆盖:利用
::after伪元素生成一个覆盖整个占位块的渐变层,渐变方向为 90 度(水平),颜色从基础骨架色@skeleton-color过渡到高光色@skeleton-to-color再回到基础色,形成"亮带"。 - 初始偏移:伪元素左右各向外延伸
150%,保证动画移动时渐变带始终能覆盖占位块的全部区域,不会出现露底。 - 循环动画:通过
animation: ant-skeleton-loading 1.4s ease infinite让伪元素在 1.4 秒内以缓动曲线无限循环移动。 - 位移动画:keyframes 让伪元素从
translateX(-37.5%)移动到translateX(37.5%),完成一次从左到右的流光扫过。
需要留意的是,ant-design-blazor 遵循 ant-design 的命名约定,编译后的动画名称为ant-skeleton-loading(前缀ant来自 Less 变量@ant-prefix)。这与原生 ant-design 保持一致的动效节奏(1.4s ease infinite),无需额外配置即可获得与业界一致的观感。
三、动画相关主题变量:颜色与暗色模式适配
流光动画的高光效果依赖两个 Less 主题变量,定义于主题文件中:
- 浅色主题 default.less:
@skeleton-color: rgba(190, 190, 190, 0.2); @skeleton-to-color: shade(@skeleton-color, 5%);- 暗色主题 dark.less:
@skeleton-to-color: fade(@white, 16%);- 变量主题 variable.less 与默认主题取值一致。
这说明两件事:一是@skeleton-color是浅灰色半透明底色,@skeleton-to-color是流光的高光色(浅色主题下比底色加深 5%,暗色主题下为 16% 透明度的白色);二是动画本身无需为暗色模式额外处理,只要主题切换后变量随之变化,流光效果会自动适配。如果你希望定制流光扫过的"光带"颜色,可以在项目的 Less 主题覆盖文件中重新定义这两个变量。
四、SkeletonElement 的 Active:为单个占位元素开启动画
Active不仅存在于Skeleton组件,也存在于单独使用的SkeletonElement组件中。SkeletonElement用于渲染按钮、头像、输入框等单个骨架占位元素,其参数定义于 SkeletonElement.razor.cs:
/// <summary> /// If the skeleton is active /// </summary> [Parameter] public bool Active { get; set; } = false;并在SetClassMap中同样通过.If("ant-skeleton-active", () => Active)(见 SkeletonElement.razor.cs)来挂载激活态样式。官方演示 Element.razor 展示了如何对三种元素分别控制动画开关与尺寸、形状:
<SkeletonElement Type="SkeletonElementType.Button" Active="_buttonActive" Size="_buttonSize" Shape="_buttonShape"></SkeletonElement> <SkeletonElement Type="SkeletonElementType.Avatar" Active="_avatarActive" Size="_avatarSize" Shape="_avatarShape"></SkeletonElement> <SkeletonElement Type="SkeletonElementType.Input" Active="_inputActive" Size="_inputSize" style="width:300px"></SkeletonElement>其中Type的取值由枚举 SkeletonElementType.cs 限定为Button、Input、Avatar三种;Size与Shape分别对应枚举 SkeletonElementSize.cs(Default/Large/Small)与 SkeletonElementShape.cs(Default/Circle/Round/Square)。例如要让一个圆形大号头像带流光动画,可以写:
<SkeletonElement Type="SkeletonElementType.Avatar" Active="true" Size="SkeletonElementSize.Large" Shape="SkeletonElementShape.Circle"> </SkeletonElement>五、实战:Active 与 Loading 组合实现"加载中→加载完成"过渡
单纯开启动画只解决了"占位块在动"的问题,真实场景中还需要结合Loading参数在数据到达后切换到真实内容。Loading参数的语义在 Skeleton.razor.cs 中定义:为true时显示占位图,为false时直接展示子组件(ChildContent)。对应的渲染逻辑在 Skeleton.razor:
@if (Loading) { if (Avatar) { <div class="ant-skeleton-header"> <SkeletonElement Type="@SkeletonElementType.Avatar" Size="@AvatarSize" Shape="@AvatarShape"></SkeletonElement> </div> } <div class="ant-skeleton-content"> @if (Title) { <h3 class="ant-skeleton-title" style="width:@ToCSSUnit(TitleWidth)"></h3> } @if (Paragraph) { <ul class="ant-skeleton-paragraph"> @foreach (var row in this._paragraphRowsList) { <li style="width:@ToCSSUnit(row)"></li> } </ul> } </div> } @if (!Loading) { @ChildContent }官方示例 List.razor 是这一组合的典型应用:用Switch切换_loading状态,加载中显示带头像、带流光的骨架列表,加载完成后展示真实列表项:
<Switch Checked="@_loading" @bind-Value="@_loading"></Switch> <AntList DataSource="@_listData"> <ChildContent Context="item"> <ListItem> <Skeleton Loading="@_loading" Active Avatar> <ListItemMeta Avatar="@item.Avatar" Description="@item.Description"> <Title> <a href="@item.Href">@item.Title</a> </Title> </ListItemMeta> @item.Content </Skeleton> </ListItem> </ChildContent> </AntList>这里Active Avatar是 Razor 中的布尔简写属性语法,等价于Active="true" Avatar="true"。当Avatar为true时,组件会自动套用ant-skeleton-with-avatar类调整布局(见 Skeleton.razor.cs),且头像默认使用圆形、Default尺寸(见SetAvatarProps,Skeleton.razor.cs)。
更贴近真实异步加载的写法可参考官方 Children.razor,用Task.Delay模拟 3 秒请求:
<Skeleton Loading="@_loading"> <h4>Ant Design, a design language</h4> <p> We supply a series of design principles, practical patterns and high quality design resources... </p> </Skeleton> <Button @onclick="showSkeleton" Disabled="@_loading">Show Skeleton</Button> @code{ private bool _loading = false; private async Task showSkeleton() { this._loading = true; await Task.Delay(3000); this._loading = false; } }把它与Active组合,即可实现"请求发起 → 骨架屏流光提示 → 数据到达 → 平滑切换真实内容"的完整体验闭环。官方文档 index.zh-CN.md 也提示:Skeleton 适合网络较慢、内容较多的列表/卡片等首次加载场景,且可被Spin完全代替,但在可用场景下能提供更好的视觉效果与用户体验。
六、参数速查与使用建议
结合 index.zh-CN.md 的 API 表与源码,与动画直接相关及高频配合使用的参数汇总如下:
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
Active | 是否展示动画效果(流光扫过) | bool | false |
Loading | 为true时显示占位图,反之直接展示子组件 | bool | true |
Title | 是否显示标题占位图 | bool | true |
TitleWidth | 标题占位图宽度 | int \| string | 自动(见下方说明) |
Avatar | 是否显示头像占位图 | bool | false |
AvatarSize | 头像占位图大小 | int \| SkeletonElementSize | Default |
AvatarShape | 头像形状 | SkeletonElementShape | Circle |
Paragraph | 是否显示段落占位图 | bool | true |
ParagraphRows | 段落占位图行数 | int? | 自动计算 |
ParagraphWidth | 段落每行宽度,数组时对应每行宽度,否则为最后一行宽度 | int \| string \| IList<...> | 最后一行 61% |
几点由源码确认的细节:
- 标题宽度自动推导:未显式设置
TitleWidth时,SetTitleProps(Skeleton.razor.cs)会根据是否含头像与段落自动取38%或50%。 - 段落行数与末行宽度:
SetParagraphProps(Skeleton.razor.cs)中,未指定ParagraphRows时,有标题则为 2 行、否则 1 行;每行宽度默认满宽,最后一行默认61%(对应样式文件 index.less 中的&:last-child ... width: 61%规则)。 - RTL 兼容:
ant-skeleton-rtl类在RTL模式下自动追加(见 Skeleton.razor.cs),动画与布局在从右向左排版下同样可用。
实践建议:
- 只在首次加载使用:骨架屏适用于数据首次加载的等待场景,反复出现会造成视觉噪音;加载完成后将
Loading置为false以展示真实内容。 - 优先开启 Active:
Active="true"不增加任何额外代码成本,仅靠 CSS 伪元素动画即可显著提升等待体验,建议默认开启。 - 动画节奏按需微调:默认流光周期为
1.4s ease infinite,如需更舒缓或更急促的观感,可覆盖@keyframes ant-skeleton-loading的时长与缓动曲线。 - 暗色模式无需额外处理:流光高光色随主题变量自动切换(见 dark.less),组件本身不感知主题差异。
七、小结
ant-design-blazor 的 SkeletonActive动画虽然只是一个布尔开关,背后却是精心设计的 CSS 工程:ant-skeleton-active类统一挂载流光样式,.skeleton-color()mixin 借助::after伪元素与linear-gradient生成高光带,ant-skeleton-loadingkeyframes 以 1.4 秒缓动循环完成扫过,动画颜色由@skeleton-color/@skeleton-to-color主题变量驱动并天然适配暗色模式。配合Loading、Avatar、ParagraphRows等参数,开发者可以用极少的代码为 Blazor 应用打造专业、流畅的加载体验。相关演示与源码可继续在仓库中查阅:active.md、Skeleton.razor.cs、Skeleton.razor、index.less 及官方文档 index.zh-CN.md。
- UI组件
- 前端
【免费下载链接】ant-design-blazor
🌈A rich set of enterprise-class UI components based on Ant Design and Blazor.
相关推荐
ant-design-blazor Skeleton 骨架屏动画效果(Active)实战指南
ant design blazor Skeleton 骨架屏动画效果(Active)实战指南 Skeleton 是 ant design blazor 组件库中
前端UI组件设计系统Ant Design Skeleton 组件家族共享 API 深入解析:active 动画与 classNames/styles 语义化定制
Ant Design Skeleton 组件家族共享 API 深入解析:active 动画与 classNames/styles 语义化定制 component
前端UI组件设计系统Ant Design Skeleton 组件 active 动画效果全解析:从一行代码到 CSS 动画底层实现
Ant Design Skeleton 组件 active 动画效果全解析:从一行代码到 CSS 动画底层实现 导读 Skeleton(骨架屏)是 Ant De
前端UI组件设计系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考