如何精简仅背景URL不同的.bg-login-[n]类重复CSS代码?
精简重复CSS的实现方案
这类仅资源路径有差异的重复CSS规则,按下面的优先级选实现方式即可,比JS遍历生成样式更规范、易维护。
第一步:先抽离完全重复的公共规则
所有.bg-login-[n]类的no-repeat center center属性完全一致,不需要每个类单独写,用属性选择器统一命中即可:
/* 命中所有类名包含bg-login-的元素 */ [class*="bg-login-"] { background-repeat: no-repeat; background-position: center center; /* 如果需要统一设置背景尺寸也可以写在这里,不用单独给每个类加 */ background-size: cover; }
抽完公共规则后,每个单独的类只需要写background-image属性即可,代码量直接减少一半以上。
方案1:CSS预处理器循环(最推荐,生产环境首选)
如果项目已经配置了Sass/Less/Stylus这类CSS预处理器,直接用循环语法批量生成差异化规则即可,编译产物是纯静态CSS,没有任何运行时开销,后续维护只需要修改循环的数值范围,不用手动复制粘贴代码。
以Sass为例:
// 公共样式提前抽离的前提下,循环生成1-5的背景规则 @for $i from 1 through 5 { .bg-login-#{$i} { background-image: url(/images/login/login-#{$i}.jpg); } }
如果用Less,写法如下:
.loop(@i) when (@i <= 5) { .loop(@i + 1); .bg-login-@{i} { background-image: url(/images/login/login-@{i}.jpg); } } .loop(1);
后续如果要加第6、7张登录背景,只要把循环上限的5改成对应数字就行,不用新增重复代码块。
方案2:原生CSS无预处理器方案
如果项目没有引入预处理器,也不想用JS生成样式,可以靠CSS自定义属性实现,不需要提前定义一堆类:
/* 只需要定义一次公共类 */ .bg-login { background-repeat: no-repeat; background-position: center center; background-size: cover; background-image: url("/images/login/login-" var(--login-bg-index) ".jpg"); }
HTML使用时直接通过行内样式传图片序号即可,不需要提前写对应类:
<!-- 对应login-1.jpg --> <div class="bg-login" style="--login-bg-index: 1"></div> <!-- 对应login-3.jpg --> <div class="bg-login" style="--login-bg-index: 3"></div>
目前所有现代浏览器都支持url()内多段值拼接自定义属性,兼容度足够覆盖绝大多数业务场景。
方案3:轻量JS实现(不推荐首屏场景用)
如果确实需要用JS生成样式,不要用拼接innerHTML插入style标签的写法,用原生CSSStyleSheetAPI生成样式表,性能更好也不会产生冗余DOM节点:
const bgCount = 5; const sheet = new CSSStyleSheet(); // 插入公共规则 sheet.insertRule(`[class*="bg-login-"] { background-repeat: no-repeat; background-position: center center; background-size: cover; }`); // 批量插入差异化规则 for (let i = 1; i <= bgCount; i++) { sheet.insertRule(`.bg-login-${i} { background-image: url(/images/login/login-${i}.jpg); }`); } // 挂载样式到文档 document.adoptedStyleSheets.push(sheet);
注意:运行时生成CSS有概率出现首屏样式闪烁(图片加载前背景样式未生效),如果是首屏就要渲染的登录页背景,不优先选这个方案。
内容的提问来源于stack exchange,提问作者lechnerio
相关产品推荐
相关产品推荐

