CSS骨架屏动画制作详解
编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《CSS骨架屏动画制作教程》,文章讲解的知识点主要包括,如果你对文章方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。
制作骨架屏动画推荐使用伪元素(::before或::after),因其能实现关注点分离,将动画层与内容层解耦,避免真实内容加载后样式冲突;2. 伪元素可独立控制层叠顺序和透明度,兼容复杂背景设计,提升视觉表现灵活性;3. 动画应优先使用transform属性(如translateX)以触发GPU加速,确保流畅性;4. 可通过will-change: transform提示浏览器优化,但需避免滥用以防资源浪费;5. 渐变应简洁,动画时长和缓动函数需合理设置,减少渲染开销;6. 利用position: absolute和overflow: hidden限制动画范围,防止触发页面重排;7. 替代方案包括使用background-image结合background-position动画,适用于简单场景;8. SVG适合非矩形或高定制化图形,支持无限缩放且动画精细,但代码较复杂;9. 在React、Vue等框架中,推荐封装Skeleton组件,通过状态控制显隐,实现与业务逻辑的无缝集成,提升可维护性。

CSS制作骨架屏加载效果,通常会巧妙地利用元素的伪元素(::before 或 ::after)结合CSS动画来实现。核心思路是创建一个半透明的、带有渐变效果的“光带”,然后通过动画让这个光带在骨架元素上平移,模拟数据加载时的“闪烁”或“流动”感。
解决方案
要制作一个骨架屏效果,我们首先需要一些HTML结构来代表即将加载的内容,比如一个卡片、几行文本和一张图片。然后,通过CSS为这些占位元素设置基础的灰色背景,并利用伪元素或直接在元素背景上叠加一个线性渐变,最后通过 @keyframes 动画控制这个渐变的移动。
HTML结构示例:
<div class="skeleton-card">
<div class="skeleton-image"></div>
<div class="skeleton-content">
<div class="skeleton-line short"></div>
<div class="skeleton-line medium"></div>
<div class="skeleton-line long"></div>
</div>
</div>CSS实现:
/* 基础骨架样式 */
.skeleton-card {
width: 300px;
border-radius: 8px;
overflow: hidden; /* 确保伪元素动画不会溢出 */
margin: 20px;
background-color: #f0f0f0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
position: relative; /* 为伪元素定位提供上下文 */
}
.skeleton-image {
width: 100%;
height: 180px;
background-color: #e0e0e0;
}
.skeleton-content {
padding: 15px;
}
.skeleton-line {
height: 16px;
background-color: #e0e0e0;
margin-bottom: 8px;
border-radius: 4px;
}
.skeleton-line.short {
width: 60%;
}
.skeleton-line.medium {
width: 85%;
}
.skeleton-line.long {
width: 100%;
}
/* 骨架屏动画效果 */
.skeleton-card,
.skeleton-image,
.skeleton-line {
/* 关键:为骨架元素添加动画效果 */
position: relative;
overflow: hidden; /* 隐藏超出部分的伪元素 */
}
.skeleton-card::after,
.skeleton-image::after,
.skeleton-line::after {
content: '';
position: absolute;
top: 0;
left: -100%; /* 从左侧开始 */
width: 100%;
height: 100%;
/* 核心:线性渐变作为“光带” */
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
animation: shimmer 1.5s infinite linear; /* 动画持续时间、无限循环、线性速度 */
}
/* 动画定义 */
@keyframes shimmer {
0% {
transform: translateX(-100%); /* 初始位置:完全在左侧 */
}
100% {
transform: translateX(200%); /* 结束位置:完全在右侧(比100%多,确保完全划过) */
}
}
/* 针对特定元素调整动画,比如让整个卡片一起闪烁 */
/* 如果只想让子元素闪烁,可以移除 .skeleton-card::after 的规则 */
/* 如果想让整个卡片作为整体闪烁,可以只保留 .skeleton-card::after,并移除子元素的::after */
/* 这里为了演示效果,让所有骨架元素都闪烁 */为什么选择伪元素来实现骨架屏动画,而不是直接操作元素本身?
选择伪元素(::before 或 ::after)来制作骨架屏的闪烁动画,在我看来,是一种非常优雅且实用的策略。这不仅仅是技术上的选择,更体现了对代码组织和视觉表现的考量。
首先,它实现了关注点分离。骨架屏的本质是数据的占位符,它最终会被真实内容取代。如果我们将闪烁动画直接应用到元素自身的背景上,那么当真实内容加载进来时,我们可能需要额外处理,比如移除这个背景动画。而使用伪元素,它就像一层半透明的“遮罩”或者“光效层”,独立于元素本身的内容和背景。当数据加载完成,我们只需要简单地移除或隐藏这些带有骨架屏样式的元素(或者替换为真实内容),伪元素自然也就消失了,不会留下任何痕迹或冲突。这种分离让我们的CSS逻辑更清晰,也更容易维护。
其次,层叠上下文和灵活性。伪元素是依附于父元素的,但它们可以拥有自己的 z-index 和定位属性,这使得我们可以精确控制“光带”的层级。想象一下,如果你的骨架元素本身就有一个复杂的背景图片或者渐变,直接在其上叠加动画可能会导致视觉冲突。伪元素则可以完美地作为一层独立的视觉效果叠加在这些背景之上,甚至可以调整其透明度,创造出更细腻的过渡效果。我个人在项目中就遇到过这种情况,使用伪元素让我能更自由地设计动画,而不必担心破坏原有的设计。
最后,从性能和DOM结构的角度来看,虽然现代浏览器对CSS动画的优化已经很好了,但使用伪元素通常意味着你是在操作一个相对简单的、独立的渲染层。动画 transform 属性,如 translateX,通常能触发GPU加速,这对于流畅的动画体验至关重要。将动画逻辑封装在伪元素中,也避免了对主DOM元素的频繁修改,保持了DOM结构的简洁性,这对于一些复杂的单页应用(SPA)来说,是很有益的。
如何优化骨架屏的动画性能,避免卡顿?
骨架屏动画的流畅性直接影响用户体验,尤其是在移动设备或性能较低的机器上。我见过不少网站的骨架屏效果看起来很酷,但在实际加载时却显得卡顿,这往往是因为没有充分考虑到性能优化。要避免卡顿,有几个关键点需要注意:
首先,优先使用 transform 属性进行动画。这是优化动画性能的黄金法则。像 translateX、translateY、scale、rotate 这样的 transform 属性,浏览器通常能够将其推送到GPU进行处理,实现硬件加速。相比之下,动画 left、top、width、height 或 margin 等属性,会触发浏览器的布局(Layout)和绘制(Paint)过程,这通常会导致CPU密集型操作,从而引发卡顿。在我们的骨架屏案例中,通过 transform: translateX() 来移动伪元素,正是利用了这一优势。
其次,合理使用 will-change 属性。will-change 是一个非常有用的CSS属性,它可以提前告知浏览器,某个元素或其属性将要发生变化,从而让浏览器有机会进行优化。比如,在动画开始前给伪元素添加 will-change: transform;。但这并非万能药,切忌滥用。will-change 会让浏览器为该元素分配额外的内存和资源,如果大量元素都设置了 will-change,反而可能适得其反,消耗更多资源甚至导致内存泄漏。我通常只会在那些确定会发生复杂或频繁动画的元素上使用它,并且在动画结束后考虑移除它(通过JavaScript)。
再者,简化渐变和动画复杂度。虽然CSS渐变很强大,但过于复杂或多层嵌套的渐变可能会增加渲染负担。保持渐变简单,例如我们例子中的 linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent),既能达到效果,又不会过度消耗资源。同时,动画的 duration 和 timing-function 也应选择合适的值,避免过快或过于复杂的曲线,保持动画的自然和流畅。
最后,避免不必要的重绘和重排。确保你的骨架屏动画只影响它自身,而不会波及到页面上其他不相关的元素。例如,如果你的动画导致了父元素或兄弟元素的尺寸变化,那就会触发全局的重排。通过 position: absolute 和 overflow: hidden 来限制伪元素的动画范围,可以有效地避免这些问题。在开发过程中,利用浏览器开发者工具(如Chrome的Performance面板)进行性能分析,观察动画过程中是否有不必要的布局和绘制事件发生,是定位和解决卡顿问题的有效方法。
除了伪元素,还有哪些常见的骨架屏实现方式及它们的适用场景?
虽然伪元素是实现骨架屏动画的常用且高效方式,但前端领域的技术选择从来不是单一的。根据项目的具体需求、技术栈以及动画的复杂程度,我们还有其他几种实现骨架屏效果的方法,每种都有其独特的优势和适用场景。
一种常见的替代方案是直接利用CSS的 background 属性。这种方法通常是将一个线性渐变作为元素的背景,然后通过动画 background-position 来实现闪烁效果。
.skeleton-element {
background-color: #e0e0e0;
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
background-size: 200% 100%; /* 让渐变比元素宽,以便移动 */
animation: shimmer-bg 1.5s infinite linear;
}
@keyframes shimmer-bg {
0% {
background-position: -100% 0;
}
100% {
background-position: 200% 0;
}
}这种方法的优点是代码更简洁,不需要额外的伪元素。它适用于那些不需要复杂层叠效果、且元素本身不会有其他背景图片或渐变冲突的简单骨架屏。如果你的元素本身需要一个背景图片,那么这种方法就可能不适用,因为它会覆盖掉原有的背景。
再来,对于更复杂的图形或需要高度定制化的骨架屏,SVG(Scalable Vector Graphics) 是一个非常强大的选择。你可以用SVG绘制出任意形状的占位符(比如圆形头像、不规则的图表区域),然后利用SVG的渐变( 或 )和动画( 标签或CSS动画)来制作闪烁效果。
<svg class="skeleton-svg" width="100" height="100">
<rect x="0" y="0" width="100" height="100" fill="url(#shimmerGradient)"/>
<defs>
<linearGradient id="shimmerGradient">
<stop offset="0%" stop-color="#e0e0e0"/>
<stop offset="50%" stop-color="#f0f0f0"/>
<stop offset="100%" stop-color="#e0e0e0"/>
<animate attributeName="x1" from="-100%" to="200%" dur="1.5s" repeatCount="indefinite"/>
</linearGradient>
</defs>
</svg>SVG的优点在于无限缩放不失真,非常适合响应式设计,并且可以创建出CSS难以实现的复杂图形。缺点是对于简单的矩形或线条,SVG代码可能会显得有些冗长。它的适用场景主要是当你的骨架屏需要非标准形状、或者你已经在使用SVG来构建其他UI元素时。
最后,在现代前端框架(如React、Vue、Angular)中,基于JavaScript的组件化方案也非常流行。开发者会创建一个专门的“Skeleton”组件,这个组件根据传入的props(例如,需要显示多少行文本、是否有图片等)来渲染出对应的HTML结构和CSS样式。当数据加载完成时,只需替换这个Skeleton组件为实际的数据渲染组件即可。
// 伪代码,React组件示例
import React from 'react';
import './Skeleton.css'; // 引入前面定义的CSS
const SkeletonCard = () => (
<div className="skeleton-card">
<div className="skeleton-image"></div>
<div className="skeleton-content">
<div className="skeleton-line short"></div>
<div className="skeleton-line medium"></div>
<div className="skeleton-line long"></div>
</div>
</div>
);
// 在父组件中使用
const MyComponent = ({ isLoading, data }) => {
return isLoading ? <SkeletonCard /> : <ActualContent data={data} />;
};这种组件化方案的优势在于与应用逻辑的深度集成。你可以非常方便地控制骨架屏的显示与隐藏,甚至可以根据不同的加载状态显示不同类型的骨架屏。它使得骨架屏的生命周期管理变得非常清晰,尤其适合大型、复杂的单页应用。虽然它引入了JavaScript的开销,但在大多数现代框架项目中,这已经是标准实践的一部分了。我个人在构建大型应用时,更倾向于这种方式,因为它让状态管理和UI渲染的耦合度降到最低。
今天带大家了解了的相关知识,希望对你有所帮助;关于文章的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
DecktopusAI如何提升30%客单价?
- 上一篇
- DecktopusAI如何提升30%客单价?
- 下一篇
- 小米YU7交付目标15万台,产能成关键
-
- 文章 · 前端 | 1分钟前 |
- SSGSSR客户端渲染怎么选?Next.js数据获取指南
- 432浏览 收藏
-
- 文章 · 前端 | 1分钟前 |
- JavaScript动画实现与交互技巧解析
- 165浏览 收藏
-
- 文章 · 前端 | 6分钟前 |
- CSS导航栏高亮技巧详解
- 108浏览 收藏
-
- 文章 · 前端 | 11分钟前 |
- CSS多行文字浮动环绕技巧解析
- 203浏览 收藏
-
- 文章 · 前端 | 19分钟前 |
- Tailwindline-clamp文本截断问题解析
- 194浏览 收藏
-
- 文章 · 前端 | 29分钟前 | 安全性 target="_blank" HTML链接 rel="noopener" 新窗口打开
- HTML链接新窗口打开设置方法
- 320浏览 收藏
-
- 文章 · 前端 | 30分钟前 |
- CSS引入方式及性能优化技巧
- 175浏览 收藏
-
- 文章 · 前端 | 32分钟前 |
- 获取设备方向的JavaScript方法有哪些
- 135浏览 收藏
-
- 文章 · 前端 | 37分钟前 |
- overflow作用及控制方法详解
- 364浏览 收藏
-
- 文章 · 前端 | 46分钟前 |
- AJAX表单构建指南:状态与反馈管理
- 162浏览 收藏
-
- 文章 · 前端 | 51分钟前 |
- JavaScriptreduce方法使用教程
- 361浏览 收藏
-
- 文章 · 前端 | 57分钟前 | CSSGrid display:grid 间距 项目定位 网格结构
- CSSGrid多行多列布局教程
- 299浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3200次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3413次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3443次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4551次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3821次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览

