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

相关推荐
微臣愚钝3 小时前
前端【8】HTML+CSS+javascript实战项目----实现一个简单的待办事项列表 (To-Do List)
前端·javascript·css·html
lilu88888884 小时前
AI代码生成器赋能房地产:ScriptEcho如何革新VR/AR房产浏览体验
前端·人工智能·ar·vr
LCG元4 小时前
Vue.js组件开发-实现对视频预览
前端·vue.js·音视频
阿芯爱编程4 小时前
vue3 react区别
前端·react.js·前端框架
烛.照1034 小时前
Nginx部署的前端项目刷新404问题
运维·前端·nginx
YoloMari4 小时前
组件中的emit
前端·javascript·vue.js·微信小程序·uni-app
浪浪山小白兔5 小时前
HTML5 Web Worker 的使用与实践
前端·html·html5
疯狂小料5 小时前
React 路由导航与传参详解
前端·react.js·前端框架
追光少年33226 小时前
Learning Vue 读书笔记 Chapter 2
前端·javascript·vue.js·vue3
前端熊猫6 小时前
JavaScript 的 Promise 对象和 Promise.all 方法的使用
开发语言·前端·javascript