HELLO,这里是大熊的前端开发笔记。

曾经主题切换功能可以作为软件中亮眼的卖点存在,毕竟那时候要实现换肤可不容易,一套主题一套样式,这代码的重复率嗖嗖嗖的就涨上去了~~当然也可以借助 CSS 预编译 语言编译出多套 CSS 样式表。

没有用觉得我们其实并不需要多套样式表实现换肤?我们只是想要一个像 JS 设计模式中的适配器,约定好规则,不同的主题按照约定规则进行适配即可。

CSS 变量

什么是变量?

就是在一个地方定义,可到处使用的东西。遇到不满意的时候,也可以随时进行改变。嘿...不满意就换这不是理想中的生活吗?扯远了~~

CSS 变量(又称为自定义属性),可以让开发者集中管理 CSS 中可复用的值,比如:颜色,间距,字体大小等等一切 CSS 中的属性值。

变量声明规则

在 CSS 中,变量名必须以 -- 开头,比如:--base-font-size--base-color 等,需注意,变量名是区分大小写的,如 --a--A 是两个不同的变量。

虽然变量名的书写规范没强制要求以短横线 - 分割,但为了与 css 属性名保持一致,还是建议使用短横线分割,不建议使用驼峰命名,比如 --baseFontSize 不推荐,但要这么写代码也能运行。

在声明一个变量也可以使用另一个变量作为变量值。

语法:

--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
/* 使用另一个变量,并使用默认值 */
--base-border: 2px solid var(--base-color, red);

变量申明位置

如果全局使用的变量,可以使用 :root 选择器声明:

:root {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}

局部变量可以在选择器中声明,变量名相同情况下,局部变量会覆盖全局变量:

.box {
--base-font-size: 18px;
--box-color: #666;
--box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

变量使用

在 CSS 中,要使用变量必须要用到 var() 函数,var() 函数的作用就是去获取变量的值,语法如下:

.box {
font-size: var(--base-font-size);
color: var(--base-color);
box-shadow: var(--base-shadow);
} /* 以上代码等价于 */
.box {
font-size: 24px;
color: #333;
box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}

示例:

<div class="box">
box 中的文字内容
</div>
<style>
:root {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: 400px;
height: 120px;
font-size: var(--base-font-size);
color: var(--base-color);
box-shadow: var(--base-shadow);
}
</style>

效果:

var() 默认值

var() 的第二个参数可以设置一个默认值,如果获取的变量没有设置,则使用默认值进行属性赋值,可以理解为 山中无老虎,猴子称大王

示例:

<div class="box">
box 中的文字内容
</div>
<style>
:root {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: 400px;
height: 120px;
font-size: var(--base-font-size, 12px); /* 如果没有设置 --base-font-size,则使用默认值 12px */
color: var(--base-color, #ff4757); /* 如果没有设置 --base-color,则使用默认值 #ff4757 */
box-shadow: var(--base-shadow);
background-color: var(--base-bg-color, rgba(255, 71, 87,0.1)); /* 如果没有设置 --base-bg-color,则使用默认值 rgba(255, 71, 87,0.1) */
}
</style>

font-size 和 color 的值都有定义,所以会使用的定义的值,而 background-color 没有定义,所以会使用默认值。效果:

变量覆盖

有时候可能我们不想要默认的变量值,而是需要特殊设定。比如某些三方组件里面使用 root 声明了变量,这时候要想覆盖 root 声明的变量,应该怎么做?

变量覆盖规则:

1、a.css 和 b.css 同时使用 root 声明了同一个变量,那么跟引入两个 css 文件的顺序有关,后引入的文件会覆盖前一个。

2、:root 声明的变量,可以使用 :root:root 覆盖。

3、局部变量优先级高于全局变量。

比如有如下两个 CSS 代码文件:

a.css 文件:

:root {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}

b.css 文件:

:root {
/*
同时使用 root 声明的变量与引入的顺序有关
*/
--base-color: red;
}
:root:root {
/*
此处声明会覆盖 a.css 文件中的 --base-font-size。
不论 a.css 在前,还是在后,都会生效。
*/
--base-font-size: 16px;
}
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: 400px;
height: 120px;
font-size: var(--base-font-size, 12px);
color: var(--base-color);
box-shadow: var(--base-shadow);
background-color: var(--base-bg-color, rgba(255, 71, 87,0.1));
}
.box:nth-child(1) {
/*
局部变量优先级最高
*/
--base-shadow: 0 0 0 6px rgba(0, 0, 0, 0.3);
}

a.css 在 b.css 之前引入示例:

<link rel="stylesheet" href="./a.css">
<link rel="stylesheet" href="./b.css">
<div class="box">
box1 中的文字内容
</div>
<div class="box">
box2 中的文字内容
</div>

效果:

b.css 在 a.css 之前引入示例:

<link rel="stylesheet" href="./b.css">
<link rel="stylesheet" href="./a.css">
<div class="box">
box1 中的文字内容
</div>
<div class="box">
box2 中的文字内容
</div>

效果:

由于变量的覆盖特性,所以不建议到处声明变量,应该集中管理,在固定文件中声明 CSS 变量!!

主题换肤

一个简单的换肤示例:

<div class="box">
box 中的文字内容
</div>
<div>
<!-- 点击事件将 body class 置空 -->
<a href="javascript:;" onclick="document.body.className = ''">无主题</a>
<!-- 点击事件给 body 添加 class -->
<a href="javascript:;" onclick="document.body.className = 'theme-1'">主题1</a>
<!-- 点击事件给 body 添加 class -->
<a href="javascript:;" onclick="document.body.className = 'theme-2'">主题2</a>
</div>
<style>
.theme-1 {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 0 0 0 6px rgba(0, 0, 0, 0.3);
--base-bg-color: rgba(71, 163, 255, 0.1);
--base-border: 2px solid rgba(71, 163, 255,0.3);
}
.theme-2 {
--base-font-size: 18px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
--base-bg-color: rgba(255, 197, 71, 0.1);
--base-border: 2px solid rgba(255, 197, 71,0.3);
}
.box {
margin: 20px 0;
width: 400px;
height: 120px;
border: var(--base-border, 2px solid rgba(255, 71, 87,0.3));
font-size: var(--base-font-size, 16px);
color: var(--base-color, #ff4757);
box-shadow: var(--base-shadow, 3px 3px 6px rgba(0, 0, 0, 0.3));
background-color: var(--base-bg-color, rgba(255, 71, 87,0.1));
}
</style>

效果:

写在最后

CSS 变量可以让我们很方便的进行主题换肤,也让前端可以集中管理重复的颜色、字体、边框等属性,增强了代码的可维护性。

Web前端入门第 45 问:CSS 变量 var() 轻松实现主题换肤功能的更多相关文章

  1. 利用CSS预处理技术实现项目换肤功能(less css + asp.net mvc4.0 bundle)

    一.背景 在越来越重视用户体验的今天,换肤功能也慢慢被重视起来.一个web系统用户可以选择一个自己喜欢的系统主题,在用户眼里还是会多少加点分的.我们很开心的是easyui v1.3.4有自带defau ...

  2. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  3. 好程序员web前端分享18个用CSS制作出来的东西

    好程序员web前端分享18个用CSS制作出来的东西,与流行的看法相反,CSS不仅仅是用来提供一个WEB页面的基本风格,以使它看起来更有吸引力.还有很多其他的事情,CSS也可以做的很好.由于它创建动画和 ...

  4. 好程序员web前端分享值得参考的css理论:OOCSS、SMACSS与BEM

    好程序员web前端分享值得参考的css理论:OOCSS.SMACSS与BEM 最近在The Sass Way里看到了Modular CSS typography一文,发现文章在开头部分就提到了OOCS ...

  5. 进击的Python【第十三章】:Web前端基础之HTML与CSS样式

    进击的Python[第十四章]:Web前端基础之HTML与CSS样式 一.web框架的本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客 ...

  6. Android零基础入门第45节:GridView简单使用

    原文:Android零基础入门第45节:GridView简单使用 前面一共用了8期来学习ListView列表的相关操作,其实学习的ListView的知识完全适用于AdapterView的其他子类,如G ...

  7. 使用 css/less 动态更换主题色(换肤功能)

    前言 说起换肤功能,前端肯定不陌生,其实就是颜色值的更换,实现方式有很多,也各有优缺点 一.看需求是什么 一般来说换肤的需求分为两种: 1. 一种是几种可供选择的颜色/主题样式,进行选择切换,这种可供 ...

  8. 【转】Javascript+css 实现网页换肤功能

    来源:http://www.php100.com/html/webkaifa/DIV_CSS/2008/1014/2326.html Html代码部分: 1.要有一个带id的样式表链接,我们要通过操作 ...

  9. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  10. Brackets - 强大免费的开源跨平台Web前端开发工具IDE (HTML/CSS/Javascript代码编辑器)

    Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由 Adobe 创建和维护,根据MIT许可证发布,支持 Wind ...

随机推荐

  1. Luogu P5089 元素周期表 / Codeforces 1012B Chemical table 题解 [ 并查集 ] [ 二分图 ] [ 图论建模 ] [ 棋盘覆盖问题 ]

    双倍经验:Luogu P5089 元素周期表 ,CF1012B Chemical table:模拟赛搬的好题,有点厉害.赛时10min码的假贪心拿了五十多分,赢. 并查集思路 1 对于此类棋盘整行整列 ...

  2. IGM机器人维修的关键环节

    在现代科技领域,机器人已经成为不可或缺的一部分,它们广泛应用于各个行业,包括制造业.服务业.医疗.科研等.对于任何机器人来说,定期的维护和修理都是必不可少的.这不仅可以确保机器人正常工作,还可以延长其 ...

  3. npm i 下载太慢

    1.在项目内部进入终端 2.输入:npm config set registry https://registry.npmmirror.com 修改npm下载地址为淘宝 3.然后再执行 npm i 进 ...

  4. 使用vscode开发微信小程序

    1. 安装插件 2. 文件-打开文件夹-将新建的微信小程序导入,代码会有高亮的效果 3. 编辑内容,查看效果,如果有就说明插件引入成功.

  5. 国产数据库高光时刻!天翼云TeleDB荣登TPC-DS全球测评总榜第二

    近日,天翼云TeleDB数据库以40206063QphDS的吞吐量在国际权威机构TPC(国际事务处理性能委员会)发布的数据库基准测试TPC-DS中荣登全球榜单第二位.中国数据库技术跻身国际顶尖行列,这 ...

  6. Xshell连接VMware虚拟机中的CentOS

    步骤: 1. 检查Linux虚拟机的网络连接模式,确保它是NAT模式.(由于只在本机进行连接,所以没有选择桥接模式.当然,桥接模式的配置会有所不同,在此不做深入分析) 2. 在VMware works ...

  7. SpringBoot的yml文件报org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here in 'reader', line 11, column 16:

    报错内容如下: 报错代码如下: 1 spring: 2 cloud: 3 gateway: 4 routes: 5 - id: query_route 6 uri: https://baidu.org ...

  8. 使用SPA单页面跟MPA多页面的优缺点?

    SPA vs MPA 深度解析 1. 概述 什么是 SPA? SPA(Single Page Application,单页面应用)是一种仅加载一个 HTML 页面,并通过 JavaScript 动态更 ...

  9. Debian 9 更换源

    Debian 全球镜像站 # 先备份源列表文件 mv /etc/apt/sources.list /etc/apt/sources.list.bak # 生成新的源列表文件(用的国内源镜像) echo ...

  10. Docker中的Gitlab数据迁移

    一.选择版本 GitLab 12.2或更高版本:   docker exec -t gitlab-backup create GitLab 12.1和更早版本:   gitlab-rake gitla ...