• css主题切换


    前端主题切换方案

    提前加载所有主题样式,切换时修改类名

    实现

    思路:提前将所有样式文件引入,然后在切换主题是给一个公共的元素添加一个类名,通过样式的层级来覆盖原有颜色相关样式

    main.js中提前引入样式文件:

    import '@/assets/css/dark.css'
    import '@/assets/css/green.css'
    
    • 1
    • 2

    green.css绿色主题css文件:

    body.green .content {
      color: #333;
      background-color: #c7edcc;
    }
    
    • 1
    • 2
    • 3
    • 4

    原来的样式:

    .content {
      color: #333;
      background-color: #fff;
    }
    
    • 1
    • 2
    • 3
    • 4

    切换主题时给公共的元素添加相对应类型来覆盖原有颜色样式:

        
        
        changeStyle(color) {
          document.body.className = color
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    优缺点

    1》优点

    不用重新加载样式文件,在样式切换时不会有卡顿

    2》缺点:

    首次就加载了所有的主题样式文件,牺牲了一点首屏时间来加载样式

    一定要注意优先级的问题,主题切换的样式优先级要高于原有的才能覆盖

    不是很灵活,没添加一个主题就要添加一个主题样式文件

    link标签动态引入

    实现

    思路:也和前面一样先写好几套主题样式,然后切换时修改link标签的href属性

    document.getElementById('#theme').href = 'green.css'
    
    • 1
    优缺点

    1》优点

    实现了按需加载,首屏更好

    2》缺点

    动态加载样式文件,如果文件过大网络情况不佳的情况下可能会有加载延迟,导致样式切换不流畅

    一定要注意优先级的问题,主题切换的样式优先级要高于原有的才能覆盖

    不是很灵活,没添加一个主题就要添加一个主题样式文件

    CSS变量+类名切换

    和第一种方案类似,只不过不用写那么多样式,相当于方案1的优化版

    CSS定义变量

    –两个短横线用于定义CSS变量

        
    祖先元素
    父亲
    儿子
    儿子的儿子
    .origin { background-color: var(--theme-bg); color: var(--theme-font); } .father { --theme-bg: yellowgreen; --theme-font: red; } .child { background-color: var(--theme-bg); color: var(--theme-font); } .grandson { background-color: var(--theme-bg); color: var(--theme-font); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    父元素(祖先元素)定义了css变量,子元素(后代元素)就可以通过var()来使用了

    var()

    语法:

    var( ,?)
    
    • 1

    var()是一个css函数,可以插入一个自定义属性,用来代替非自定义属性中 值的任何部分

    第一个参数

    作用:要替换的自定义属性的名称

    第二个可选参数

    可选参数

    作用:用作回退值。如果第一个参数引用的自定义属性无效,则该函数将使用第二个值

    :root

    是一个伪类,用于匹配文档的根元素

    1》可以直接在里面设置样式,就相当于给html设置样式

    ​      :root {
    ​        background-color: #ccc;
    ​        padding: 0 20px;
    ​      }
    
    • 1
    • 2
    • 3
    • 4

    2》声明全局css变量,要以 “–” 开头,因为:root是根元素,根元素中定义变量就是全局变量啦

    ​      :root {
    ​        --pink-bg-color: pink;
    ​        --green-color: green;
    ​      }
    
    • 1
    • 2
    • 3
    • 4

    通过var()函数就可以使用全局css变量了

          .box {
            background-color: var(--main-bg-color);
            color: var(--green-color);
          }
    
    • 1
    • 2
    • 3
    • 4
    color-scheme

    配色方案,normal就是浏览器默认配色方案,light白天模式,dark夜间模式,写了两个就是有个按顺序的优先级

    color-scheme: normal;
    color-scheme: light;
    color-scheme: dark;
    color-scheme: light dark;
    
    • 1
    • 2
    • 3
    • 4

    color-scheme 的作用范围很有限,包括表单控件、滚动条和 CSS 系统颜色(浏览器内置的颜色)的使用值

    可以搭配css变量等进行主题切换

    实现

    思路:依然是提前将样式文件载入,切换时将指定的根元素类名更换。不过这里相对灵活的是,默认在根作用域下定义好CSS变量,只需要在不同的主题下更改CSS变量对应的取值即可

    具体实现:

    引入主题样式文件:theme.css

    :root {
      --bg-color: #eee;
      --font-color: #333;
    }
    .red {
      --bg-color: #a61840;
      --font-color: #fbddc2;
    }
    .green {
      --bg-color: #efa5a9;
      --font-color: #ede1bc;
    }
    .blue {
      --bg-color: #4e3bb1;
      --font-color: #dfb9c8;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    通过var()给盒子设置颜色

    .colorful-wrapper {
      background-color: var(--bg-color);
      color: var(--font-color);
      border-color: var(--border-color);
    }
    html.red {
      color-scheme: red;
    }
    html.green {
      color-scheme: green;
    }
    html.blue {
      color-scheme: blue;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    切换主题时:给根元素添加对应的类名

          document.documentElement.className = color
    
    • 1
    优缺点

    优点:

    不用重新加载样式文件,在样式切换时不会有卡顿

    在需要切换主题的地方利用var()绑定变量即可,不存在优先级问题

    新增或修改主题方便灵活,仅需新增或修改CSS变量即可,在var()绑定样式变量的地方就会自动更换

    缺点:

    首屏加载时会牺牲一些时间加载样式资源,除了IE的兼容优点问题基本上可以不用考虑兼容问题

    CSS变量+动态setProperty

    setProperty

    语法:

    style.setProperty(propertyName, value, priority)
    
    • 1

    propertyName:属性名

    value:属性值,可选参数;如果没有指定,则当作空字符串;不能直接在value后加 !import, 设置important需要使用priority来设置

    priority:优先级,可选参数,允许设置"important" 优先级

    返回值为undefined

    实现

    通过:root定义全局css变量,给对应盒子设置颜色时通过var()函数将css变量值设置给对应属性

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    修改主题:通过setProperty来修改变量的值

    export const changeTheme = function (theme, ele = document.documentElement) {
      for (let [key, value] of Object.entries(themes[theme])) {
        ele.style.setProperty(key, value)
      }
    }
    
    export const themes = {
      red: {
        '--bg-color': '#a61840',
        '--font-color': '#fbddc2',
      },
      green: {
        '--bg-color': '#efa5a9',
        '--font-color': '#ede1bc',
      },
      blue: {
        '--bg-color': '#4e3bb1',
        '--font-color': '#dfb9c8',
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    优缺点

    1》优点:

    不用重新加载样式文件,在样式切换时不会有卡顿

    新增或修改主题方便灵活

    2》缺点:

    IE的兼容其他基本浏览器基本不用太考虑

    SASS的mixin混入+类名切换

    theme.scss

    // 白色主题
    $bg-color-light: #fff;
    $font-color-light: #333;
    $border-color-light: #999;
    $bg-image-light: url("src/images/light.png");
    
    // 黑色主题
    $bg-color-dark: #999;
    $font-color-dark: #fff;
    $border-color-dark: #000;
    $bg-image-dark: url(src/images/dark.png");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    mixin.scss

    @import "./theme.scss";
    @mixin bg_image($img) {
      background-image: $img;
      [data-theme="dark"] & {
        background-image: $bg-image-dark;
      }
      [data-theme="light"] & {
        background-image: $bg-image-light;
      }
    }
    
    @mixin font_color($color) {
      color: $color;
      [data-theme="dark"] & {
        color: $font-color-dark;
      }
    
      [data-theme="light"] & {
        color: $font-color-light;
      }
    }
    
    @mixin border_color($color) {
      border-color: $color;
      [data-theme="dark"] & {
        border-color: $border-color-dark;
      }
      [data-theme="light"] & {
        border-color: $border-color-light;
      }
    }
    
    @mixin bg_color($color) {
      background-color: $color;
      [data-theme="dark"] & {
        background-color: $bg-color-dark;
      }
      [data-theme="light"] & {
        background-color: $bg-color-light;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    vue文件中使用

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    优缺点:

    优点:

    灵活

    兼容性好

    缺点:

    vue3才支持

    在组件上绑定了动态样式的地方都会有对应的编译成哈希化的CSS变量,而不像方案3统一地就在:root上设置(不确定在达到一定量级以后的性能)

    Vue3

    基本使用

    v-bind可以绑定data中的变量

    原理其实就是给元素绑定CSS变量,在绑定的数据更新时调用 CSSStyleDeclaration.setProperty 更新CSS变量值

    const theme = {
      color: "red",
    };
    
    
    .box {
      color: v-bind("theme.color");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    优缺点:

    优点:

    灵活,易用,切花不需要重新加载样式文件

    缺点:

    vue3才支持

    在组件上绑定了动态样式的地方都会有对应的编译成哈希化的CSS变量,而不像方案3统一地就在:root上设置(不确定在达到一定量级以后的性能)

    如果主题样式不确定,用户可自定义,使用 CSS变量+动态setProperty 最合适

    如果主题固定使用选择更广,大部分都是选择 CSS变量+类名切换 这种方案

  • 相关阅读:
    c++STL库
    一款快速从数据库中提取信息工具
    SpringCloudAlibaba入门之Sentinel(SCA)
    推荐vim插件tmux
    公益是书籍是什么,公益书籍变现模式有哪些
    云数融合与大数据技术在日常生活中的创新应用探索
    vue3.0中使用echarts,鼠标悬浮无法显示数据框的问题
    【C++】STL之适配器---用deque实现栈和队列
    微服务之SpringCloud
    VUE3学习小记(2)- ref 与 reactive
  • 原文地址:https://blog.csdn.net/weixin_50576800/article/details/133050043