Less中用递归循环(如.loop()配合when (@i > 0)守卫)生成长投影,通过同步递增x/y偏移、渐变颜色与零模糊半径实现锐利斜向阴影,推荐8–12层兼顾性能与效果,并需适配背景明暗及字体加载时机。
Less中用循环生成长投影的
mixin
直接写几十层
不现实,也难维护。Less 的循环(
或递归
)是唯一靠谱的自动化方式。核心逻辑是:每层偏移量递增(如
),颜色透明度渐变(如
),避免硬编码。
常见错误是循环变量未正确递减或未终止,导致编译失败或阴影层数爆炸。务必用
守卫条件,且初始调用传入明确层数(如
)。
偏移必须严格同步:x 和 y 都用同一变量
,否则不是“斜向长影”而是散点
颜色不能只改 alpha:纯黑+渐变透明在浅背景上会发灰,建议用
+
双重控制
模糊半径应为
:长投影本质是锐利拉伸,加 blur 会糊成一团,违背设计意图
多层叠加在 Less 中的性能与兼容性取舍
生成 20 层
值后,CSS 文件体积增长明显,但现代浏览器渲染无压力;真正卡顿的是旧版 Safari(≤14)和部分安卓 WebView,它们对超长
列表解析慢,甚至触发回退渲染。
实操建议:默认生成 8–12 层足够模拟视觉深度;若需适配低端环境,用
包裹,并 fallback 到单层阴影 + 伪元素模拟。
立即学习
“
前端免费学习笔记(深入)
”;
不要用
替代:它不支持多层独立偏移,且无法精确控制每层颜色衰减
避免在
中动态修改长投影:CSS 动画无法逐帧重算 Less 编译结果,只能预设几档固定层级
字体粗细影响显著:细体字(如
)用长投影易断层,建议搭配
如何让长投影随背景色自动适配明暗
硬写
在深色背景上就看不见。Less 中应提取背景主色,用
函数判断明暗,再决定投影用深色下沉还是浅色上浮。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
例如:
;反之则用
并提高透明度。
别依赖
变量:真实项目中背景可能是渐变、图片或 CSS 变量,需预留
手动覆盖入口
函数在 Less v4+ 才稳定,旧版本要用
+ 手动阈值判断
移动端高对比模式下,系统可能强制重绘阴影,此时应禁用长投影,改用
简化版
为什么不用伪元素 +
替代循环?
伪元素方案(如
拉伸+渐变)看似灵活,但实际限制极多:无法响应文字换行、不支持 inline 元素、
在非直角字体下边缘撕裂、且无法像
那样继承父级
或
。
Less 循环生成的
是纯声明式,零 DOM 开销,所有浏览器按规范解析,而伪元素方案需额外定位、z-index 控制、且动画时易出现层叠闪烁。
伪元素长影在 iOS Safari 中常因
优化失效,导致滚动时投影跳变
如果文字含 emoji 或复杂 script(如阿拉伯文),
会扭曲基线,
则天然保持字符轮廓
调试时,开发者工具里直接能看到每一层 shadow 的偏移值——这是伪元素永远做不到的透明性
实际项目中,最易被忽略的是
字体加载时机
:Google Fonts 等异步加载的字体,可能在 Less 编译完成、CSS 注入后才生效,导致首屏长投影错位。必须配合
的
或 JS 检测
后重应用样式。
.long-shadow()text-shadow.loop()@index@i * 1pxfade(#000, 100% - @i * 2%)when (@i > 0).long-shadow(12)@idarken(@base-color, @i * 1.5%)fade()0text-shadowtext-shadowtext-shadow@supports (text-shadow: 0 0 0 #000)filter: drop-shadow()@keyframesfont-weight: 300text-rendering: optimizeLegibilityrgba(0,0,0,0.7)contrast().long-shadow(@bg: #fff, @steps: 10) when (lightness(@bg) > 50%) { ... color: fade(darken(@bg, 40%), 15%) ... }lighten(@bg, 40%)background-color@shadow-basecontrast()lightness(@color) > 50%box-shadowtransform: skew()::beforeskew()text-shadowtext-strokeletter-spacingtext-shadowwill-changeskew()text-shadow@font-facefont-display: optionaldocument.fonts.load()