「技术教程」CSS技巧打造SPA首屏骨架屏 | 实现快速加载和用户友好的首屏骨架结构插图

前言

最近我掌握了一项新技能,利用原生CSS来实现首屏骨架。这不仅可以避免在Home.vue组件中单独创建骨架,而且无需对HTML结构进行任何修改。

让我们先来看一下预览图:

「技术教程」CSS技巧打造SPA首屏骨架屏 | 实现快速加载和用户友好的首屏骨架结构插图1

效果还是相当不错的。

教程

这项技术的原理是利用background-image的多重渐变来实现骨架占位,结合background-sizebackground-position进行精准定位。如果你的骨架包含大量重复内容,还可以配置background-repeat: repeat-y;来进行Y轴重复渲染,效果更为出色。

通过动画控制整体透明度的变化,我们实现了动态效果。而通过使用:empty伪类,我们可以判断#app是否渲染。:empty会在对应的元素内部没有任何内容时生效。

不多说,让我们直接看代码

html,
body,
#app {
    margin: 0;
    padding: 0;
    height: 100%;
}

body {
    background-color: #12161f;
}

#app:empty {
    background-image: linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352), linear-gradient(90deg, #262c3b 30px, #3e4352);
    background-size: 350px 30px, 350px 100px, 350px 30px, 110px 40px, 110px 40px, 110px 40px, 350px 30px, 350px 40px, 110px 150px, 110px 150px, 110px 150px, 110px 40px, 110px 40px, 110px 40px, 350px 80px, 350px 80px, 350px 80px;
    background-position: 12.5px 10px, 12.5px 50px, 12.5px 160px, 12.5px 200px, 132.5px 200px, 252.5px 200px, 12.5px 250px, 12.5px 290px, 12.5px 340px, 132.5px 340px, 252.5px 340px, 12.5px 520px, 132.5px 520px, 252.5px 520px, 12.5px 570px, 12.5px 660px, 12.5px 750px;
    background-repeat: no-repeat;
    animation: theme1-skeleton-blink 1.2s ease-in-out infinite;
}

@keyframes theme1-skeleton-blink {
    50% {
        opacity: 0.6;
    }
}

我这骨架略微复杂,就没有使用y轴重复。

这里基本就行了,由于vite会对index.html中的style样式进行转换,所以如果你使用了rem或者vw,得到最终css其实是已经单位转换后的值,所以大小屏适配也没有问题了。