SCSS入门

538 阅读3分钟

前言

因为刚刚自己前段学完SCSS,故写篇博客,来再次复习一哈。 看完这篇文章你将会学到:

  1. 如何快速配置SCSS环境
  2. SCSS的基础语法
  3. SCSS响应式
  4. 你会发现Less、Stylus、Sass/SCSS 基本差不多学会一个,学其他的就很快

SASS/SCSS文档

以下只说部分语法,更多语法请查看 👉🏻 中文文档

配置环境

默认是已经装了 node npm/yarn

mkdir sass-v1
cd sass-v1

npm init -y
npm i -D parcel
npx parcel index.html

本文用parcel代替Webpack,它不需要任何配置就能使用Webpack功能的一个工具 如果觉得复杂可以用 codepen 在线写代码

截屏2021-10-19 下午3.13.41.png 1.png

CSS和SCSS的区别

header {
  color: red;
  font-size: 18px;
}
header {
  color: red;
  p {
    font-size: 18px;
  }
}

SCSS的基础语法

<nav>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
</nav>
$grey: #ccc;
$gray: $grey;
$border-width: 2px;

// $border-color: red 默认red
@mixin debug($border-color: red) {
  border: 1px solid $border-color;
  // background: $gray;
}

// 把一些好用的、常用的代码放到这里 placeholder
%box {
  box-shadow: 0 0 2px #ccc;
}


nav {
  @include debug; // 机械的把代码考过来

  > ul {
    background: white;
    background: $gray;

    @include debug(red); // 把代码拷过来

    > li {
      @include debug(green); // 拷贝样式
      @extend %box; // 这个的意思是把 li 放到%box 那里(考到%box里),不拷贝样式而是把选择器提到样式的前面
    }
  }
}

截屏2021-10-19 下午3.18.37.png

codepen代码链接🔗

选择器扩展

BEM命名法

Block Element Modifier
block: 主要名词 user-card element: div里的哥哥元素 user-card__name
modifier: 某一个元素的不同状态 user-card--active
优化
啰嗦的BEM命名法: .user-card__picture--active
优化后的: .userCard-picture .active
class = "userCard-picture active"

嵌套的选择器


nav {
    font-size: 24px;

  > ul {
    background: red;

    > li {
      background: pink;
    }
  }
}

& 符号

<div class="userCard">
  <div class="userCard-name">你好</div>
  <div class="userCard-picture"> 嗯嗯安啊
    <div class="userCard-picture-hhh">
      hellow
      <ul class="userCard-picture-hhh-j">
        <li>1</li>
        <li>2</li>
        <li>3</li>
      </ul>
    </div>
  </div>
  <div class="userCard-content"></div>
</div>
.userCard {
  width: 100px;

  // 写成 .active 表示你是.userCard里面的后代元素, &.active 表示ta自己被激活
  &.active { // 转成CSS是 .userCard.active 如果 .userCard 拥有 .active 这么个类,它的背景就是黄色
    background: yellow;
  }

  // & 指的是当前所属的选择器

  &-picture {
    background-color: $grey;
  }

  &-name {
    $red: #f60;
    background: {
      color: #bd1000;
    }
    font: {
      size: 20px;
      weight: bold;
    }
    color: blue;

    &:hover {
      color: $red;
    }
  }
  &-picture {
    $red: #bd1000;
    &:hover{
      color: $red;
    }
    &-hhh {
      background: aqua;
      &-j {
        margin: 0;
        padding: 0;
        list-style: none;
        li {
          color: $red;
        }
      }
    }
  }
  &-content {
    $pink: pink;
    $width: 250px;
    // 符合预期的 1:1 div
    width: $width;
    margin-top: $width / 2;
    height: $width;
    border-radius: $width / 2;
    border: 1px solid $gray;
    background-color: change-color($color: $pink, $green: 255);
    &:hover {
      background: {
        color: $pink;
      }
    }
  }
}

嵌套属性

// 加了冒号
font: {
    size: 24px;
    weight: bold;
    family: monospace;
}

background: {
  color: $pink;
  image: url(../img/btn.jpg);
}

注释

单行 // 多行 /* */

变量

$grey: #ccc;  // 把#ccc赋值给 变量 $grey 
$gray: $grey; // $grey === $gray 为了防止自己拼错
$width: 1px;
 > ul {
     $grey: red; //  变量可以有作用域,在这个作用域中是 red ,后面加 !global 就是全局声明
     border: 1px solid $grey;
     > li {
         $width: 120px; // 可以做一个符合自己预期 1:1 的 div
         width: $width;
         height: $width;
     }
 }
 

一个属性放在多个地方,可以全局的改,可以让不同的变量是同一个,如果有多个$red,就采用就近原则。
SCSS里面的 - 和 _ 不会报错。

mixin

案例一

// $border-color: red  参数默认red
@mixin debug($border-color: red) {
  border: 1px solid $border-color;
  // 把一堆代码放到mixin里
}

nav {
  @include debug; // include的特点是机械的把代码考过来,$border-color默认的值是 red

  > ul {
    $grey: #red  // 变量可以有作用域,在这个作用域中是 red 
    background: white;
    background: $gray;

    @include debug(pink); // 将pink这个参数传给$border-color,把代码拷过来

    > li {
      @include debug(green); // 拷贝样式,传参数 green
    }
  }
}

案例二

@mixin box($width: 100px, height: 100px) {
  box-shadow: 0 0 5px black;
  margin: 10px;
  width: $width;
  height: $height;
}
.smallBox {
  @include box(); // 使用默认的
}
.bigBox {
  @include box(300px, 300px);
}

article {
  > section {
    .textAside {
      @include box(20px, 20px)
    }
  }
}

placeholder

// 把一些好用的、常用的代码放到这里 placeholder,占位符选择器,把使用@extend %box的选择器提到这里
%box {
  box-shadow: 0 0 2px #ccc;
}

nav {

  > ul {
    background: white;
    background: $gray;
    
    > li {
      @extend %box;  // extend的意思是把你的选择器复制到前面去(article,li) 这个的意思是把 li 放到%box 那里(考到%box里),不拷贝样式而是把选择器提到样式的前面
    }
  }
}

placeholder它可以是的我们的代码更加简洁

运算

  1. $width: 300px; =>width: $width/3;
  2. width: (300px/3)
  3. width: 300px/3 - 0 用来做奇偶性,width: 100%3px => 1px
  4. color: $red + #888
  5. color: change-color($color: $red, $green: 255)
  6. color: fade-out($color: $red, $amount: 0.5)=>fade-out($red, 0.5)

字符串差值

$red: #f60;
&::before {
  content: '「 #{$red}'; // #{}的意思就是把 $red的值赋值过来
}
&::after {
  content: '」';
}

@keyframes

案例一

@keyframes x {
  10% {
    color: red;
  }
  20% {
    color: red;
  }
  30% {
    color: red;
  }
  40% {
    color: red;
  }
  50% {
    color: red;
  }  
}

变成SCSS👇

$z: 10%;
@keyframes x {
  @for $i from 1 to 6 {
    #{$i * $z} {
      color:red;
    }
  }
}

案例二

@keyframes x2 {
  0% {
    transform: translateX(-$n);
  }
  25% {
    transform: translateX($n);
  }
  50% {
    transform: translateX(-$n);
  }
  75% {
    transform: translateX($n);
  }
  100% {
    transform: translateX(0);
  }  
}

变成SCSS👇

$step: 25%;
@keyframes x2 {
  @for $i from 0 to 4 {
    #{$i * $step} {
      @if $i % 2 == 0 {
        transform: translateX(-$n);
      } @else {
        transform: translateX($n);
      }
    }
  }
  100% {
    transform: translateX(0);
  }
} 

思考

如何放弃px、%,使用 vw(页面宽度)计算,它所有的宽度都以页面宽度的基准来算 设计师给的设计图以不同手机的宽为基准的话,你得去一个个算,好麻烦=-=,那该如何解决呢🤔?使用函数👇

function

@function px($npx) {
  @return $npx/375 * 100vw; // 以375宽的屏幕为基准算
  // @return $value/2 + px; 把单位缩小50%
}

.icon {
  width: px(70); // 70为设计图宽
  height: px(70);
}

对某个东西统一计算 function ,复用属性值的计算逻辑的
vw的兼容性有些许差,如图👇

vw.png

SCSS响应式

  1. 使用 vw 来进行动态缩放
  2. 使用函数将 px => vw 的计算过程简化
@function px($npx) {
  @return $npx/375 * vw;
}
  1. 使用flex布局(加一个flex-shrink: 0: 不会变形)

media 媒体查询

@media(max-width: 500px) {
  > ul {
    display:none
  }
  .menu {
    display: blockl;
  }
}

通过mixin简化

// 定义
@mixin phone {
  @media (max-width: 500px) {
    @concent;
  }
}
@mixin ipad {
  @media(min-width:501px) and (max-width: 1024px) {
    @concent;
  }
}
@mixin pc {
  @media(min-width:1025px){
    @content;
  }
}
// 使用
@include phone {
//这里面是@content
  > ul {
    display: none;
    .menu {
      display: block;
    }
  }
}
@include ipad { }
@include pc {}

🌰

定义

@mixin df($fd:null,$jc:null,$ai:null,$as:null) {
 display:flex;
 flex-direction:$fd;
 justify-content:$jc;
 align-items:$ai;
 align-self:$as;
}

调用

// 用谁调谁

@include df($jc:center,$ai:center)
h1 { font-size: 2em; } h2 { font-size: 1.5em; } h3 { font-size: 1.2em; }
// 使用以下写法就可以
@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  #{$header} {
    font-size: $size;
  }
}

导入SCSS

@import "xxx"; 

@import "xxxx.scss";

以上两种方式都可以导入