背景
一个按钮往往有 4 个状态。
- 默认状态
- hover
- 鼠标按下
- 禁用状态
为了表示这 4 个状态,需要设置 4 个颜色来提示用户。
按钮类型一般有 5 个:
以 primary 类型按钮为例,设置它不同状态下的颜色:
<button class="btn type--primary">Primary</button>
<style>
.btn {
width: 100px;
height: 40px;
border: none;
border-radius: 5px;
}
.btn.type--primary {
/* 基础色 */
background-color: #409eff;
color: #ffffff;
/* hover */
&:hover {
background-color: #79bbff;
}
/* 鼠标按下 */
&:active {
background-color: #337ecc;
}
/* 禁用状态 */
&:disabled {
background-color: #a0cfff;
}
}
</style>
一个按钮就要设置 4 个颜色,5 个类型的按钮就是 20 种颜色,显然要设计出这 20 种颜色非常麻烦。(如果有设计师直接提供设计好的颜色,那么就定义变量直接用。)
因此希望只需给按钮设置一个基本颜色,其他状态的颜色可以根据这个基本颜色自动生成。
sass 调整颜色亮度
按钮不同状态的颜色,其实是修改了按钮基础颜色的亮度。比如:
- hover 就是基础色变亮一点,
- active 就是基础色变暗
- disabled 就是基础色比 hover 还要更亮一点,文字也要更亮。
sass 中提供了工具函数可以便捷的修改颜色的亮度。
引入 sass 的颜色模块,里面有很多实用的工具函数。
@use sass:color
但我们这里不需要引入。因为我们主要使用颜色函数中的变亮,变暗函数。这两个函数已经变成全局的了,可以直接用。
- 变亮:
lighten(颜色, 百分比)
- 变暗:
darken(颜色, 百分比)
.btn {
width: 100px;
height: 40px;
border: none;
border-radius: 5px;
}
.btn.type--primary {
$primary-color: #409eff;
$primary-text-color: #ffffff;
color: $primary-text-color;
background-color: $primary-color;
&:hover {
background-color: lighten($primary-color, 10%);
}
&:active {
background-color: darken($primary-color, 10%);
}
&:disabled {
background-color: lighten($primary-color, 20%);
color: lighten($primary-text-color, 40%);
}
}
进阶:循环优化
上面以 primary 类型按钮为例的代码已经实现了自动生成其他状态颜色的目标。但我们还可以用循环优化一下,省得每个按钮类型重复写上面的代码。
$var: (key: value)
:括号定义对象(map)map-keys
:返回 key 组成的数组(list),类似 Object.keys()@each ... in ...
:遍历数组,类似数组高阶函数 map#{}
:插值表达式,类似模板字符串
<button class="btn type--primary">Primary</button>
<button class="btn type--success">Success</button>
<button class="btn type--warning">Warning</button>
<button class="btn type--danger">Danger</button>
<button class="btn type--info">Info</button>
<style lang="scss">
.btn {
width: 100px;
height: 40px;
border: none;
border-radius: 5px;
}
/* 定义按钮类型颜色对象 */
$btn-color-map: (
primary: #409eff,
success: #67c23a,
warning: #e6a23c,
danger: #f56c6c,
info: #909399
);
/* 生成 .btn.type--primary{},.btn.type--success{} 等样式选择器下的样式 */
@each $type in map-keys($btn-color-map) {
$btn-color: map-get($btn-color-map, $type);
.btn.type--#{$type} {
$bg-color: $btn-color;
$text-color: #ffffff;
color: $text-color;
background-color: $bg-color;
&:hover {
background-color: lighten($bg-color, 10%);
}
&:active {
background-color: darken($bg-color, 10%);
}
&:disabled {
color: lighten($text-color, 40%);
background-color: lighten($bg-color, 20%);
}
}
}
</style>
完整代码
主要功能已经实现了,这里只是补充了下按钮的通用样式。
/*************** start ****************/
/* 按钮全局样式,包括5中类型 */
/*********************************** */
.btn {
box-sizing: border-box;
display: inline-flex;
align-items: center;
justify-content: center;
height: 32px;
padding: 8px 15px;
margin-left: 12px;
font-size: 14px;
font-weight: 500;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: middle;
appearance: none;
cursor: pointer;
user-select: none;
border: 1px solid #dcdfe6;
border-radius: 5px;
outline: none;
transition: .1s;
}
/* 定义按钮类型颜色对象 */
$btn-color-map: (
primary: #409eff,
success: #67c23a,
warning: #e6a23c,
danger: #f56c6c,
info: #909399
);
/* 生成 .btn.type--primary{},.btn.type--success{} 等样式选择器下的样式 */
@each $type in map-keys($btn-color-map) {
$btn-color: map-get($btn-color-map, $type);
.btn.type--#{$type} {
$bg-color: $btn-color;
$text-color: #ffffff;
color: $text-color;
background-color: $bg-color;
border-color: $bg-color;
&:hover {
background-color: lighten($bg-color, 10%);
}
&:active {
background-color: darken($bg-color, 10%);
}
&:disabled {
color: lighten($text-color, 40%);
background-color: lighten($bg-color, 20%);
}
}
}
/*************** end ****************/