Less中无法用when实现骨架屏动态尺寸逻辑,因其守卫在编译期固定CSS规则,无法响应DOM变化;应改用aspect-ratio、min-width和overflow: hidden等CSS原生能力控制尺寸。

Less中不能用when实现骨架屏动态尺寸逻辑
骨架屏必须预设宽高,when守卫在编译期就固定了CSS规则,它无法响应真实DOM结构变化。你写.skeleton-card() when (@type = "article"),生成的只是静态width: 320px; height: 180px——但页面加载时卡片实际高度由内容决定,骨架一渲染就错位。真正要做的,是把尺寸控制权交给CSS本身:用aspect-ratio、min-width和overflow: hidden兜底,而不是指望Less算出“该多高”。
用变量+混合统一管理骨架屏光效参数
扫描动画的核心参数(光条宽度、渐变色阶、位移范围)必须集中声明,否则改一次主题色要翻17个文件。推荐这样组织:
@skeleton-light: #f0f0f0;
@skeleton-dark: #e0e0e0;
@skeleton-shine-width: 200px;
@skeleton-animation-duration: 1.4s;
.skeleton-shine() {
background-image:
linear-gradient(90deg, @skeleton-light 25%, @skeleton-dark 50%, @skeleton-light 75%),
linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.3) 50%, rgba(255,255,255,0) 100%);
background-size: @skeleton-shine-width 100%;
background-position: -@skeleton-shine-width 0;
animation: skeleton-scan @skeleton-animation-duration ease-in-out infinite;
}
@keyframes skeleton-scan {
0% { background-position: -@skeleton-shine-width 0; }
100% { background-position: @skeleton-shine-width 0; }
}
-
@skeleton-shine-width必须用px单位,iOS Safari不认rem或%值 - 两层
background-image不能合并成一层,否则失去结构层次感 -
background-position初始值写-@skeleton-shine-width 0,不是-200% 0,避免IE下失效
响应式骨架屏需同步调整aspect-ratio与padding
移动端错位90%是因为aspect-ratio没随断点更新。比如卡片在桌面端是aspect-ratio: 16/9,到手机上得切到aspect-ratio: 4/3,否则圆角区域会漏白。Less里不能靠媒体查询自动推导,得手动配:
.skeleton-card(@ratio: 16/9) {
aspect-ratio: @ratio;
&--mobile { aspect-ratio: 4/3; }
&--tablet { aspect-ratio: 3/2; }
}
// 调用
.card-skeleton {
.skeleton-card(16/9);
@media (max-width: 768px) {
.skeleton-card(4/3);
}
}
- 别用
@media包裹整个.skeleton-card()混合——Less编译后生成的是静态CSS,媒体查询内嵌套混合会导致冗余规则爆炸 -
aspect-ratio值必须写成16/9而非1.777,否则Less计算会丢精度 - 图片占位块必须加
overflow: hidden,否则光效滑出圆角边界
IE11兼容方案只能用伪元素遮罩
IE11不支持background-image多层渐变,也认不得aspect-ratio。这时候when反而能派上用场——但它只用来开关降级样式,不参与逻辑判断:
立即学习“前端免费学习笔记(深入)”;
.skeleton-item() when (@legacy-support = true) {
position: relative;
&::before {
content: "";
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: @skeleton-light;
}
&::after {
content: "";
position: absolute;
top: 0; left: -100%; width: 200px; height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
animation: ie-shine 1.4s ease-in-out infinite;
}
}
-
@legacy-support必须是明确布尔值(true/false),不能是字符串"true",否则守卫不匹配 - IE下
clip-path不可用,伪元素遮罩是唯一稳定方案 - 光效
::after的width必须用px,百分比在IE中行为不可控
骨架屏最难的从来不是写动画,而是让每个容器都严格守着自己的宽高边界。一旦漏掉overflow: hidden或写死height,光效就会在Safari里发虚,在安卓WebView里跳帧——这些细节没法靠Less自动修复,得靠人盯住每个选择器。


















