换季了,总觉得衣柜里还缺一件衣服,走,逛商场/某宝
人都想换衣服,何况网站。。。
换肤实现的方案也比较多,之前有 css变量实现换肤,现在的项目基本都使用了css预处理器(也可以使用css变量换肤),所以用sass来实现下
正常情况下 一般都是给根目录加一个属性 [xxx] 来实现的
css
html[data-theme='light'] .item {
background: #fff;
color: #000;
}
html[data-theme='dark'] .item {
background: #000;
color: #fff;
}
本身代码就是老母猪戴胸罩---一套又一套(有几套主题就得写几套代码),自己全部手写的话,那真是厕所打灯笼--找shi,每个主题下的样式都写一次,人都要疯掉了,而且里面很多重复的颜色和代码,不好维护
利用css预处理器,来解决重复代码和书写麻烦的问题
css
/* 颜色这些可以使用变量提出去 */
$themes: ( /* 结构 类似于js的对象 键名是不是字符都可以 */
'': (
bgColor: red,
textColor: blue
),
'light': (
bgColor: #fff,
textColor: #000
),
'dark': (
bgColor: #000,
textColor: #fff
)
);
可以使用 混合 来使用我们定义的变量 循环遍历map结构里面的变量来生产不同的东西,从而达到不手写重复的代码 而且方便后期拓展和增加主题
css
@mixin useTheme() {
/* $key 属性名字 light/dark */
/* $value 属性值 */
@each $key, $value in $themes {
/* 每次循环把主题得值保存起来 需要注意的是 这个 $currentTheme是局部变量 需要加上 !global 提示为全局变量 */
$currentTheme: $key !global;
html[data-theme='#{$key}'] & { /* 这儿其实不加html也行 */
@content; /* useTheme 传过来得属性和值 */
}
}
}
.page {
width: 100px;
height: 100px;
@include useTheme {
background: red;
color: blue;
}
}
手动就生成了三套代码 一个字 爽 !
但现在调用混合的时候,css属性和值都是写死的,这很不科学,可以使用 函数 来实现 动态输入css属性的值
css
@function getVal($key) {
/* map-get 获取map里面属性的值 */
@return map-get(map-get($themes, $currentTheme), $key);
}
.page {
width: 100px;
height: 100px;
@include useTheme {
background: getVal(bgColor); /* 函数实参 是不是字符串都可以 但是尽量统一 */
color: getVal('textColor');
border-color: getVal('textColor');
}
}
实际效果就是
完整代码就是
css
$themes: (
'': (
bgColor: red,
textColor: blue
),
'light': (
bgColor: #fff,
textColor: #000
),
'dark': (
bgColor: #000,
textColor: #fff
)
);
@mixin useTheme() {
@each $key, $value in $themes {
$currentTheme: $key !global;
html[data-theme='#{$key}'] & {
@content;
}
}
}
@function getVal($key) {
@return map-get(map-get($themes, $currentTheme), $key);
}
.page {
width: 100px;
height: 100px;
@include useTheme {
background: getVal(bgColor);
color: getVal('textColor');
border-color: getVal('textColor');
}
}
上面还是半自动,下面来个全自动的,属性名和值都从调用的时候传进来
css
$themes: (
'': (
bgColor: red,
textColor: blue,
fs: 44px
),
'light': (
bgColor: #fff,
textColor: #000,
fs: 44px
),
'dark': (
bgColor: #000,
textColor: #fff,
fs: 44px
)
);
@mixin useTheme() {
@each $key, $value in $themes {
$currentTheme: $key !global;
html[data-theme='#{$key}'] & {
@content;
}
}
}
@function getVal($key) {
@return map-get(map-get($themes, $currentTheme), $key);
}
@mixin styles($style, $type) {
@include useTheme {
#{$style}: getVal($type);
}
}
.page {
width: 100px;
height: 100px;
@include styles('background', 'bgColor');
@include styles('color', 'textColor');
@include styles('font-size', 'fs');
}
/* 编译成的css */
.page {
width: 100px;
height: 100px;
}
html[data-theme=''] .page {
background: red;
}
html[data-theme='light'] .page {
background: #fff;
}
html[data-theme='dark'] .page {
background: #000;
}
html[data-theme=''] .page {
color: blue;
}
html[data-theme='light'] .page {
color: #000;
}
html[data-theme='dark'] .page {
color: #fff;
}
html[data-theme=''] .page {
font-size: 44px;
}
html[data-theme='light'] .page {
font-size: 44px;
}
html[data-theme='dark'] .page {
font-size: 44px;
}
需要注意的是:
混合的使用方法,不同的写法有时候 让不熟悉的人困惑
css
@mixin myStyle {
font-size: 12px;
color: #fdef92;
font-weight: bold;
}
p{
@include myStyle();
}
/* 编译成css代码 */
p{
font-size: 12px;
color: #fdef92;
font-weight: bold;
}
/*
定义混合的时候 myStyle 后面加不加 小括号() 都行
调用混合的时候也是一样 myStyle 后面加不加 小括号() 都可以
*/
还有就是混合传参:
css
@mixin generStyle($style, $type) {
/*
参数和@content 同时在同一个 混合里 存在 使用@include generStyle('color', #000)传参可以生效
再这样调用就会报错
@include useTheme {
fonst-size: 12px;
}
*/
#{$style}: $type;
@content;
}
@mixin generStyle1() { // 可以加小括号
@content;
}
@mixin generStyle2 { // 可以不加小括号
@content;
}
@mixin generStyle3 {
background: yellow;
}
.a {
@include generStyle('color', #000);
// @include useTheme {// 再这样调用就会报错
// fonst-size: 12px;
// }
}
.b {
@include generStyle1 {
font-size: 12px;
}
}
.c {
@include generStyle2 {
font-weight: 600;
}
}
.d {
@include generStyle3;
}
所以在开发的时候应该注意保持统一的代码规范!
sass在线生成css 网址:www.wetools.com/sass-to-css