Sass应用之实现主题切换

更新日期: 2022-06-19阅读: 1.2k标签: 主题

背景

实现主题切换有几种不同的方案,比如使用css变量,使用JavaScript动态加载对应的主题样式文件等。本文主要讲的是如何使用Sass实现主题切换。

前置知识

了解Sass的基本使用

variable

mixin

map

本质

Sass作为CSS预处理器,需要编译成CSS后,才能被浏览器识别和解析。因此无法在浏览器中直接使用Sass实现类似CSS变量那种动态切换。本质上来说,项目中有几个主题就要提前定义好几份主题样式并全部引入。

思路

首先,我们需要给应用的顶层元素添加一个主题标识,用于标识当前的主题,用于之后应用上对应的主题样式。该标识可以是数据属性,也可以是类,也可以是id,这里采用数据属性。

<html>
  <div class="app" >"light"></div>
</html>

然后,每次切换主题时,通过更新该标识,页面就会应用样式文件中提前定义好的对应的主题样式。

.app {
  &[>'light'] {
    color: #333;
  }
  
  &[>'dark'] {
    color: #fff;
  }
}

实现

基础版

基于主题切换的本质和思路,我们可以通过硬编码,实现一个简单的主题切换。

<div id="app" class="app">
  <h1 class="title">Hello, World</h1>
  <p class="subtitle">当前主题:<span id="theme-current">亮色</span></p>
  <button class="theme-switch light" >"light">亮色</button>
  <button class="theme-switch dark" >"dark">暗色</button>
</div>

首先给应用添加一个主题标识,这里我通过给body元素添加一个数据属性>light

<body >"light">
  <div class="app"></div>
</body>

然后提前定义好所有主题样式:

// 所有主题样式
$bg-color-light: #ffffff;
$bg-color-dark: #091a28;
$title-color-light: #363636;
$title-color-dark: #ffffff;
$subtitle-color-light: #4a4a4a;
$subtitle-color-dark: cyan;

.app {
  // 默认主题样式(light主题)
  background-color: $bg-color-light;
  
  // dark主题
  [theme='dark'] & {
    background-color: $bg-color-dark;
  }
}

.title {
  color: $title-color-light;
  
  [theme='dark'] & {
    color: $title-color-dark;
  }
}

.subtitle {
  color: $subtitle-color-light;
  
  [theme='dark'] & {
    color: $subtitle-color-dark;
  }
}

最后,当我们点击不同主题按钮时,就会更新body上的主题标识>完整代码和实现效果可以参考Codepen:

不过该实现有点粗糙,存在几个小问题:

每个需要应用主题样式的CSS选择器中,都要写一遍对应主题需要的样式,比较繁琐

如果有多个主题,代码量会极具增加,并且很多都是重复的“模板代码”

针对这些问题,我们可以利用Sass的一些特性实现一个进阶版的主题切换。

进阶版

首先,针对基础版暴露出的问题。我们需要对Sass变量做一点小小的调整。这里我们将主题样式封装成了map格式,map中每一个元素都对应着不同主题下的样式。

// 所有主题样式
$bg-color: (
  // 亮色
  light: #fff,
  // 暗色
  dark: #091a28
);

$title-color: (
  light: #363636,
  dark: #ffffff
);

$subtitle-color: (
  light: #4a4a4a,
  dark: cyan
);

针对重复的模版代码和代码繁琐的问题,Sass中有个特性mixin,正好可以利用上。

接下来,我们要封装一个mixin,专门解决基础版1-手写代码的繁琐的问题。

这里使用了Sass中的插值表达#{}和map-get方法,#{}类似于JavaScript中的计算属性,可以动态设置属性名,map-get方法用于从map中获取某一个属性对应的值。

@mixin themify($key, $valueMap) {
  // 默认主题
  #{$key}: map-get($valueMap, 'light');
    
  // dark主题
  [theme='dark'] & {
    #{$key}: map-get($valueMap, 'dark');
  }
}

themify主要封装了默认主题样式light,和dark主题样式,这样我们在选择器里,只需要include这些样式即可。

.app {
  @include themify('background-color', $bg-color);
}

.title {
  @include themify('color', $title-color);
}

.subtitle {
  @include themify('color', $subtitle-color);
}

现在看这些代码是不是简洁多了?省去了自己手写那些繁琐的模板代码!

针对“多主题模版代码会更多”的问题,解决起来也就很容易了。只需要简单修改下该mixin,添加上对应的主题样式即可。

@mixin themify($key, $valueMap) {
  // light主题
  #{$key}: map-get($valueMap, 'light');
    
  // dark主题
  [theme='dark'] & {
    #{$key}: map-get($valueMap, 'dark');
  }
  
  // dark1主题
  [theme='dark1'] & {
    #{$key}: map-get($valueMap, 'dark1');
  }
  
  // dark2主题
  [theme='dark2'] & {
    #{$key}: map-get($valueMap, 'dark2');
  }
}

当然,我们还可以对mixin做一下优化,可以将主题封装成list格式,然后通过遍历主题,简化mixin:

@mixin themify($key, $valueMap) {
  // theme list
  $themes: light, dark;
  
  @each $theme in $themes {
    [theme=#{$theme}] & {
      #{$key}: map-get($valueMap, $theme);
    }
  }
}

这样看起来就清爽多了。完整代码和实现效果可以参考Codepen:

总结

Sass作为一款流行的CSS预处理器,提供了插值表达#{}和map类型等特性,在实现主题切换方面提供了不少便利。

当然,Sass实现主题切换还有很多可以优化的点。这里随便列两条常见的:

如果有多条主题样式需要应用,每一条都要写一遍@include,感觉有点麻烦,能不能只写一遍@include?

.app {
  @include themify('background-color', $bg-color);
  @include themify('color', $text-color);
  // ...
}

// 希望可以只写一遍@include
.app {
  @include themify(
    (
    'background-color': $bg-color,
    'color': $text-color
    )
  );
}

如果还需要使用!important去覆盖一些因为权重问题无法应用的样式(比如使用了外部UI库,外部UI库中使用了!important,需要覆盖该样式),怎么解决?

// 这里提供一个思路,可以添加一个参数$important
@mixin themify($key, $valueMap: null, $important: false) {
    // xxx
}

来源:https://segmentfault.com/a/1190000042003368

链接: https://fly63.com/article/detial/11761

wordpress大前端DUX主题

DUX主题是基于WordPress程序的主题,由themebetter团队原创开发,是目前比较火的wordpress主题;支持百度熊掌号,适用于垂直站点、科技博客、个人站,扁平化设计、简洁白色、超多功能配置

Vue实现换主题/皮肤功能

网站换肤,主题切换。网站的主题色可以在几种常用颜色之间进行切换,还有相关图片、图标也要跟随主题进行切换。文章由两部分组成:css切换,图片图标切换

Web前端主题切换的几种方案

本文将介绍 Web 前端主题切换的几种常用方案,示例代码基于 React 框架。废话少说,show you the code!这种方案利用了css多层样式精确匹配的特点,通过样式覆盖的方式实现主题的切换。

采用CSS3的VAR实现动态主题切换

官方称呼其为自定义属性,坊间通常叫做css变量,因为它类似于其他js语言中的变量,可用于存储颜色、字体、大小宽度等css属性值;定义方式为两个连字符也就是中划线(--)开头,引用方式为var(custom-property-name, value)

前端 “一键换肤“ 的几种方案

现在越来越多的网站都提供了拥有换肤(切换主题)功能,如 ElementUI,既是为了迎合用户需求,或是为了凸显自己特点,因此提供了个性化定制的功能.

前端实现切换主题方案

前端开发人员面临着制作增强用户体验和适应用户偏好的用户界面的任务。带有 css 的 react 主要可用于创建多色可切换主题。为用户提供了在给定时间点在主题颜色之间切换以适合他们的偏好的特权。

使用CSS变量实现主题定制真的很简单

Varlet是通过css变量来组织样式的,什么是css变量呢,其实很简单,首先声明自定义的css属性,随便声明在哪个元素上都可以,不过只有该元素的后代才能使用,所以如果要声明全局所有元素都能使用的话,可以设置到根伪类:root下

常用Vue UI框架的主题切换

在如今,很多网页已经可以手动切换明亮模式和黑暗模式,网页的主题切换已经成为了一个常用的需求,因此,本文将从常见框架的处理方式总结一些相关的操作,并探究其本质。

兼容ie浏览器 网站变灰色

在遇到特殊情况的时候,我们作为站长需要紧急将网站变灰的需求,大家都知道通过简单的CSS样式即可实现,上述代码配合指定网页在IE内核下的渲染模式,就可以达到效果,这个语句意思便是告诉IE浏览器

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!