掘金文章归档 · 第 60 篇 CSS 布局系列 5/9 SCSS · mixin

scss 的 mixin 混入

mixin 简化 media 适配 + @for 循环批量生成样式

原文作者:随意_(掘金) | juejin.cn/post/7408086757794185266 | 发布于 2024-08-29 | 阅读 353 · 约 3 分钟

0前言

有些是工作总结,有些是技术文档搬运,有些是某视频刷到的,均会经过实践,留作总结,按需取舍。

1举栗 1:mixin 简化 media 适配

<style lang="scss" scoped>
$breakpoints: (
  "phone": (
    320px,
    480px
  ),
  "pad": (
    481px,
    768px
  ),
  "pc": (
    769px,
    1024px
  ),
  "tv": (
    1024px
  )
);

@mixin respond-to($breakname) {
  $bp: map-get($breakpoints, $breakname);
  @if type-of($bp) == "list" {
    $min: nth($bp, 1);
    $max: nth($bp, 2);
    @media screen and (min-width: $min) and (max-width: $max) {
      @content;
    }
  } @else {
    @media screen and (min-width: $bp) {
      @content;
    }
  }
}

.test {
  height: 100px;
  @include respond-to("phone") {
    background-color: red;
  }
  @include respond-to("pad") {
    background-color: green;
  }
  @include respond-to("pc") {
    background-color: yellow;
  }
  @include respond-to("tv") {
    background-color: purple;
  }
}
</style>

代码解释

这段代码是使用 Sass(特别是 SCSS 语法)编写的,它定义了一套响应式设计的工具,允许开发者根据不同的屏幕尺寸(如手机、平板、电脑、电视)来应用不同的样式。这种方法使得前端开发更加灵活和高效,尤其是在需要处理多种屏幕尺寸的响应式网页设计中。下面是详细解释:

1. 定义断点(Breakpoints)

首先,代码定义了一个名为 $breakpoints 的 Sass 映射(map),其中包含了四个键值对,每个键代表一个设备类型(如 "phone"、"pad"、"pc"、"tv"),每个值是一个元组(tuple)或单个值,表示该设备类型对应的屏幕宽度范围。元组包含两个值,分别表示最小宽度和最大宽度(对于 "tv" 只定义了一个最小宽度,因为电视屏幕尺寸可能非常大,通常不需要定义最大宽度)。

2. 定义 Mixin

接下来,定义了一个名为 respond-to 的 mixin,它接受一个参数 $breakname(设备类型的名称)。这个 mixin 的作用是根据传入的设备类型名称,动态生成对应的媒体查询(media query)。

3. 使用 Mixin

最后,在 .test 类中,通过调用 respond-to mixin 并传入不同的设备类型名称(如 "phone"、"pad"、"pc"、"tv"),来定义不同屏幕尺寸下的背景颜色。

当这段 Sass 代码被编译成 CSS 时,它将为 .test 类生成多个媒体查询块,每个块针对不同的屏幕尺寸范围应用不同的背景颜色。这样,网页就能根据不同的设备屏幕尺寸来自动调整样式,实现响应式设计。

转义为 css 代码如下

.test {
  height: 100px;
}

@media screen and (min-width: 320px) and (max-width: 480px) {
  .test {
    background-color: red;
  }
}

@media screen and (min-width: 481px) and (max-width: 768px) {
  .test {
    background-color: green;
  }
}

@media screen and (min-width: 769px) and (max-width: 1024px) {
  .test {
    background-color: yellow;
  }
}

@media screen and (min-width: 1024px) {
  .test {
    background-color: purple;
  }
}

2举栗 2:利用循环简化重复代码

.card-item {
  height: 100%;
  width: 19.5%;
  background-color: #f2f5fa;
  position: relative;
  padding-right: calc(var(--xs) * 5);

  @mixin card-item-style($background-image) {
    background: url($background-image) no-repeat;
    background-size: cover;
    color: #ffffff;
    text-align: left;

    .num {
      font-size: calc(var(--xxs) * 7);
    }
  }

  @for $i from 1 through 5 {
    &.card-item#{$i} {
      @include card-item-style("@/assets/images/jb/icon#{$i}.svg");
    }
  }
}

代码解释

这段代码是使用了 Sass(一种 CSS 预处理器)的语法编写的,它包含了一些特定的 Sass 特性,如 mixins(混合)和 for 循环。下面我将详细解释这段代码的各个部分:

1. .card-item 选择器

这是一个 CSS 类选择器,用于选择所有具有 card-item 类的 HTML 元素。它设置了这些元素的高度为 100%(相对于其父元素的高度),宽度为 19.5%,背景颜色为 #f2f5fa,定位方式为相对定位,并且在其右侧添加了基于 CSS 变量 --xs 的 padding(--xs 的值乘以 5)。

2. @mixin card-item-style($background-image)

这是一个 Sass mixin,它接受一个参数 $background-image,该参数预期是一个图像 URL。mixin 内部定义了一系列样式规则,包括设置背景图像(使用传入的 $background-image 参数),设置背景图像的大小为 cover(即图像覆盖整个元素区域,同时保持其宽高比),设置文本颜色为白色,设置文本对齐方式为左对齐。此外,它还定义了一个嵌套的 .num 选择器,用于设置类名为 num 的子元素的字体大小为 CSS 变量 --xxs 的 7 倍。

3. @for $i from 1 through 5 循环

这是一个 Sass 循环,它从 1 迭代到 5(包括 1 和 5)。对于循环中的每个 $i 值,它都会生成一个复合选择器 .card-item.card-item#{$i},这里使用了 Sass 的字符串插值功能来动态生成类名(如 .card-item.card-item1、.card-item.card-item2 等)。对于每个这样的复合选择器,它都调用了之前定义的 card-item-style mixin,并将一个字符串(由 "@/assets/images/jb/icon" 和 $i 的值组成,再加上 .svg 扩展名)作为 $background-image 参数传递给 mixin。

注意点

转译为 css 如下

.card-item {
  height: 100%;
  width: 19%;
  background-color: #f2f5fa;
  position: relative;
  padding-right: calc(var(--xs) * 5);

  &.card-item1 {
    background: url("@/assets/images/jb/icon1.svg") no-repeat;
    background-size: cover;
    color: #ffffff;
    text-align: left;

    .num {
      font-size: calc(var(--xxs) * 7);
    }
  }

  &.card-item2 {
    background: url("@/assets/images/jb/icon2.svg") no-repeat;
    background-size: cover;
    color: #ffffff;
    text-align: left;

    .num {
      font-size: calc(var(--xxs) * 7);
    }
  }

  &.card-item3 {
    background: url("@/assets/images/jb/icon3.svg") no-repeat;
    background-size: cover;
    color: #ffffff;
    text-align: left;

    .num {
      font-size: calc(var(--xxs) * 7);
    }
  }

  &.card-item4 {
    background: url("@/assets/images/jb/icon4.svg") no-repeat;
    background-size: cover;
    color: #ffffff;
    text-align: left;

    .num {
      font-size: calc(var(--xxs) * 7);
    }
  }

  &.card-item5 {
    background: url("@/assets/images/jb/icon5.svg") no-repeat;
    background-size: cover;
    color: #ffffff;
    text-align: left;

    .num {
      font-size: calc(var(--xxs) * 7);
    }
  }
}
📌 mixin 收样式、@for 收重复——五个卡片只写一份逻辑,编译后自动展开为五份完整 CSS。