blog
blog copied to clipboard
css var 背景图片处理
前言
我们在做主题切换时希望统一通过 css var 处理。假设我们希望做白色和黑色两种主题,背景图的切换理想情况我们希望通过以下方式实现。
首先定义2套 css var 样式
// theme-vars.less
.theme-white{
--bg-img:url('./bg-img-white.png');
}
.theme-black{
--bg-img:url('./bg-img-black.png');
}
组件中我们希望这样使用:
.your-comp{
background: var(--bg-img) top no-repeat;
}
问题
通过测试发现,iOS 14 以下的系统只支持 base64格式的css 变量,也就是如果图片过大没有生成base64格式,这段代码不会生效: background: var(--bg-img) top no-repeat;
解决方案1
修改图片生成base64 的规则,在vue-cli3 中,默认10kb 以下的图片才会生成base64格式,我们可以将这个规则改写,比如改为100kb:
// vue.config.js
module.exports = {
chainWebpack: config => {
// 设置打包图片转换成base64 大小限制(100kb 内为base64)
config.module
.rule("images")
.use("url-loader")
.loader("url-loader")
.tap(options => Object.assign(options, { limit: 1000 * 100 }));
}
};
如果项目中图片大小都小于100kb 那么我们的目的就达到了。但是打包后你会发现,你的js 文件已经增大了很多,图片越大base64 字符串就越长,占用的空间越大。这可能也是为什么默认小于10kb 的图片才会生成base64 的原因。所以使用这种方案你要权衡项目中图片是否过多,最简单的方式就是打包之后比较输出文件大小。
解决方案2
你也可以像图片切换那样,使用js 实现。这种方式简单粗暴,但是没有使用css var,维护麻烦点。以 vue 代码为例
<template>
<div
:style="{
'background-image': 'url(' + bgImage + ')'
}"
>
other content
</div>
</template>
<script>
export default {
props: {
theme: {
type: String,
default: "white"
}
},
data() {
return {
bgImage: ""
};
},
mounted() {
if (this.theme === "black") {
this.bgImage = require("../../../img/bg-black.png");
} else {
this.bgImage = require("../../../img/bg.png");
}
}
};
</script>
<style lang="less" scoped></style>
--完--