SASS 简化代码开发的基本方法
概要
本文以一个按钮开发的实例,介绍如何使用SASS来简化CSS代码开发的。
代码和实现
我们希望通过CSS开发下面的代码样式,从样式来看,每个按钮的基本样式相同,就是颜色不同。
如果按照传统的方式开发,需要开发btn ,btn-primary,btn-danger和btn-succsess四个类,比较麻烦,所以先将公共样式提取出来,放到btn类中。
在btn类中,封装所有公共样式,代码如下:
btn{
font-size: 1rem;
font-weight: 400;
padding:.375rem .75rem;
line-height: 1.5;
text-align: center;
vertical-align:middle;
text-decoration: none;
user-select: none;
border-radius: .375rem;
cursor: pointer;
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
每个按钮主要区别是颜色不同,每个按钮的颜色在active,disabled和hover时候,也会有一些差异,如果一个类一个类的写,显然比较麻烦。因此先将这些颜色通过SASS的变量定义出来:
$buttons:("type":"primary", "bgColor": #0d6efd, "fontColor": #fff, "borderColor":#0d6efd),
("type":"success", "bgColor": #198754, "fontColor": #fff, "borderColor":#198754),
("type":"danger", "bgColor": #dc3545, "fontColor": #fff, "borderColor":#dc3545),
("type":"warning", "bgColor": #ffc107, "fontColor": #fff, "borderColor":#ffc720),
("type":"info", "bgColor": #0dcaf0, "fontColor": #000,"borderColor": #25cff2);
通过循环遍历,一次生成所有需要的类。
对于按钮在hover,disabled和active状态下,颜色略有区别的需求,我们可以先设置一个基准颜色,再使用SASS的颜色函数lighten和darken将基准颜色变深或变浅。
@each $btn in $buttons {
.btn-#{map.get($btn,"type")}{
@extend .btn;
background-color: map.get($btn,"bgColor");
border:1px solid map.get($btn,"borderColor");
color: map.get($btn,"fontColor");;
&:hover {
background-color: lighten(map.get($btn,"bgColor"), 10%);
border:1px solid lighten(map.get($btn,"borderColor"), 10%);
color: map.get($btn,"fontColor");
}
&:disabled{
background-color: lighten(map.get($btn,"bgColor"), 20%);
border:1px solid lighten(map.get($btn,"borderColor"), 20%);
color: map.get($btn,"fontColor");
}
&:active {
background-color: darken(map.get($btn,"bgColor"), 10%);
border:1px solid darken(map.get($btn,"borderColor"), 10%);;
color: map.get($btn,"fontColor");
}
}
}
对于生成CSS类,以btn-primary为例,它和btn类的关系应该是继承关系,因此使用@extend,编译后生成的CSS代码如下:
.btn, .btn-primary {
font-size: 1rem;
font-weight: 400;
padding: 0.375rem 0.75rem;
line-height: 1.5;
text-align: center;
vertical-align: middle;
text-decoration: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
border-radius: 0.375rem;
cursor: pointer;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.btn-primary {
background-color: #0d6efd;
border: 1px solid #0d6efd;
color: #fff;
}
此处推荐使用@extend,如果使用@mixin,生成的CSS代码并不合理。
如果使用@mixin,生成的CSS代码如下:
.btn-primary {
font-size: 1rem;
font-weight: 400;
padding: 0.375rem 0.75rem;
line-height: 1.5;
text-align: center;
vertical-align: middle;
text-decoration: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
border-radius: 0.375rem;
cursor: pointer;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
background-color: #0d6efd;
border: 1px solid #0d6efd;
color: #fff;
}
.btn-primary:hover {
background-color: #408cfd;
border: 1px solid #408cfd;
color: #fff;
}
.btn-primary:disabled {
background-color: #72abfe;
border: 1px solid #72abfe;
color: #fff;
}
.btn-primary:active {
background-color: #0257d5;
border: 1px solid #0257d5;
color: #fff;
}
可以看到公共样式被定义到了每个具体的类中,造成了大量冗余的代码。
附录
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Buttons</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="buttons">
<button class="btn btn-primary">Primary</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-info">Info</button>
</div>
</body>
</html>
SASS代码:
@use "sass:map";
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.btn{
font-size: 1rem;
font-weight: 400;
padding:.375rem .75rem;
line-height: 1.5;
text-align: center;
vertical-align:middle;
text-decoration: none;
user-select: none;
border-radius: .375rem;
cursor: pointer;
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
$buttons:("type":"primary", "bgColor": #0d6efd, "fontColor": #fff, "borderColor":#0d6efd),
("type":"success", "bgColor": #198754, "fontColor": #fff, "borderColor":#198754),
("type":"danger", "bgColor": #dc3545, "fontColor": #fff, "borderColor":#dc3545),
("type":"warning", "bgColor": #ffc107, "fontColor": #fff, "borderColor":#ffc720),
("type":"info", "bgColor": #0dcaf0, "fontColor": #000,"borderColor": #25cff2);
@each $btn in $buttons {
.btn-#{map.get($btn,"type")}{
@extend .btn;
background-color: map.get($btn,"bgColor");
border:1px solid map.get($btn,"borderColor");
color: map.get($btn,"fontColor");;
&:hover {
background-color: lighten(map.get($btn,"bgColor"), 10%);
border:1px solid lighten(map.get($btn,"borderColor"), 10%);
color: map.get($btn,"fontColor");
}
&:disabled{
background-color: lighten(map.get($btn,"bgColor"), 20%);
border:1px solid lighten(map.get($btn,"borderColor"), 20%);
color: map.get($btn,"fontColor");
}
&:active {
background-color: darken(map.get($btn,"bgColor"), 10%);
border:1px solid darken(map.get($btn,"borderColor"), 10%);;
color: map.get($btn,"fontColor");
}
}
}