scss这样写,你学会了吗?

scss在平常业务中肯定会使用,对于切图css写的实在是有点太多,但是在你写css的同时,你可以让css写得和别人有点不一样,那还是比较有意思的。本文是一篇关于scss的使用,希望在你的业务中带来思考和帮助

主要会从scss下面几点来讲

  • scss中的变量如何复用
  • @extend复用样式
  • 如何动态灵活使用插值for循环
  • @mixin@include减少重复样式编写
  • 占位符scss函数的使用

正文开始...

@extend

我们以一组标签为例子,在一组标签中,每一种标签的颜色背景属性不一样,但是宽度,高度属性是一样的

jsx 复制代码
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如何编写

  • scss定义了$width,$height变量
  • global作用域下定义一个.tag-common的类
  • .tag-common类中既使用了tailwindcss也使用了scss的变量【会不生效,所以sass与tailwindcss不能混用】
  • .tag-wrap中使用了@extend来继承.tag-common
css 复制代码
$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;
      }
    }
  }
}

插值与@each循环

现在我们要设置每一个tag的颜色

  • 与上面有所不同的是,我们使用$tagWrap: "tag-wrap",在使用这个变量时,我们使用了scss插值,.#{$tagWrap}
  • 我们使用scss@each循环依次设置了tag1tag2tag3的样式
css 复制代码
$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的子级我们是直接这样写的

css 复制代码
.tag-wrap {
  span {
    @extend .tag-common;
    &:hover {
       font-size: 20px;
    }
  }
}

以上等价于下面,&当前元素

css 复制代码
.tag-wrap span {}
.tag-wrap span:hover {}

@mixin与@include

如果我们tag在多个地方重用,那么我们可以利用@mixin来复用样式tag的样式,这样这个@mixin定义后,我们通过@include xxx()就可以调用了

css 复制代码
$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"函数
css 复制代码
@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占位符可以使用可以减少你使用

css 复制代码
// color.scss
p%name1 {
  color: red;
}
p%name2 {
  color: blue;
}

index.module.scss引入,@extend引入%name1

css 复制代码
@import "./color.scss";
.set-app { 
  :global {
    .public-name .name1 {
      @extend %name1;
    }
    .public-name .name2 {
      @extend %name2;
    }
  }
}

@if 条件

scss也是可以用@if条件的,比如我想根据条件设置不同按钮的颜色

css 复制代码
@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");
        }
      }
    }
  }
}

这样我就可以根据传入的条件设置不同按钮的颜色了

@function

我们从以上例子中我们会发现@mixin@include是配合使用的,@mixin可以很好的定义一个工具mixin可以减少重复类似样式的使用,但在scss中也可以使用函数方式

css 复制代码
$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

  • code example

相关推荐
小白学习日记18 分钟前
【复习】HTML常用标签<table>
前端·html
丁总学Java1 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
yanlele1 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
懒羊羊大王呀1 小时前
CSS——属性值计算
前端·css
xgq1 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试
用户3157476081351 小时前
前端之路-了解原型和原型链
前端
永远不打烊1 小时前
librtmp 原生API做直播推流
前端
北极小狐1 小时前
浏览器事件处理机制:从硬件中断到事件驱动
前端
无咎.lsy2 小时前
vue之vuex的使用及举例
前端·javascript·vue.js
fishmemory7sec2 小时前
Electron 主进程与渲染进程、预加载preload.js
前端·javascript·electron