Skip to content
On this page

通过mixin简化响应式代码

代码展示

有的响应式代码可能需要写一些适配代码,例如

css
.home {
  width: 200px;
  height: 300px;
}
@media screen and (min-width: 992px) and (max-width: 1200px) {
  .home {
    height: 800px;
  }
}
@media screen and (min-width: 1200px) and (max-width: 1920px) {
  .home {
    height: 1000px;
  }
}

如果每个文件都要写@media screen ...这样的代码,会很费时间,可以通过Sassmixin来简化代码。

可以定义一个mixin函数,通过传入的不同尺寸,生成不同的响应式代码

  • 定义一个响应式的不同尺寸对应不同宽度的map结构
scss
// 定义一个尺寸对应的宽度map
$layouts: (
 'xs': (null, 768px),
 'sm': (768px, 992px),
 'md': (992px, 1200px),
 'lg': (1200px, 1920px),
 'xl': (1920px, null),
);

每个尺寸对应的值设置为一个list,我们规定list的第一个项为min-width,第二项为max-width,如果没有就设置为null

  • 定义mixin函数,该函数接收$breakpoint参数,默认为md,该参数的值就是定义的mapkey,然后取出当前配置的min-widthmax-width的值,然后判断该值的类型生成代码,我们还想在mixin函数中写该尺寸对应的样式,可以使用@content,将样式传到@media screen

mixin的代码如下,当然mixin可以单独提出去一个作为单独文件

scss
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
// 定义一个尺寸对应的宽度map
$layouts: (
    'xs': (null, 768px),
    'sm': (768px, 992px),
    'md': (992px, 1200px),
    'lg': (1200px, 1920px),
    'xl': (1920px, null),
);

@mixin respond-to($breakpoint: 'md') {
  // 从一个键值对取值 $sizeList 是一个数组
  $sizeList: map.get($layouts, $breakpoint);
  // 取出 数组 的第一项 和 第二项
  $min: list.nth($sizeList, 1);
  $max: list.nth($sizeList, 2);
  // 最小值为null 表示是 xs
  @if meta.type-of($min) == 'null' {
    @media screen and (max-width: $max){
      @content;
    }
  }
    // 最大值是 null 表示是最大尺寸 xl
  @else if meta.type-of($max) == 'null' {
    @media screen and (min-width: $min){
      @content;
    }
  }
  @else {
    @media screen and (min-width: $min) and (max-width: $max){
      @content;
    }
  }
}

可以达到下面的效果

原始的home.scss文件:

scss
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
// 定义一个尺寸对应的宽度map
$layouts: (
    'xs': (null, 768px),
    'sm': (768px, 992px),
    'md': (992px, 1200px),
    'lg': (1200px, 1920px),
    'xl': (1920px, null),
);

@mixin respond-to($breakpoint: 'md') {
  // 从一个键值对取值 $sizeList 是一个数组
  $sizeList: map.get($layouts, $breakpoint);
  // 取出 数组 的第一项 和 第二项
  $min: list.nth($sizeList, 1);
  $max: list.nth($sizeList, 2);
  // 最小值为null 表示是 xs
  @if meta.type-of($min) == 'null' {
    @media screen and (max-width: $max){
      @content;
    }
  } 
  // 最大值是 null 表示是最大尺寸 xl
  @else if meta.type-of($max) == 'null' {
    @media screen and (min-width: $min){
      @content;
    }
  }
  @else {
    @media screen and (min-width: $min) and (max-width: $max){
      @content;
    }
  }
}

.home {
  width: 200px;
  height: 300px;
  display: flex;
  @include respond-to('xs') {
    width: 300px;
    font-size: 14px;
  };
  @include respond-to('sm') {
    width: 500px;
    font-size: 16px;
  };
  @include respond-to('md') {
    width: 800px;
    font-size: 18px;
  };
  @include respond-to('lg') {
    width: 1000px;
    font-size: 24px;
  };
  @include respond-to('xl') {
    width: 100vw;
    font-size: 26px;
  };
}

编译后的home.css

css
.home {
    width: 200px;
    height: 300px;
    display: flex;
}
@media screen and (max-width: 768px) {
    .home {
        width: 300px;
        font-size: 14px;
    }
}
@media screen and (min-width: 768px) and (max-width: 992px) {
    .home {
        width: 500px;
        font-size: 16px;
    }
}
@media screen and (min-width: 992px) and (max-width: 1200px) {
    .home {
        width: 800px;
        font-size: 18px;
    }
}
@media screen and (min-width: 1200px) and (max-width: 1920px) {
    .home {
        width: 1000px;
        font-size: 24px;
    }
}
@media screen and (min-width: 1920px) {
    .home {
        width: 100vw;
        font-size: 26px;
    }
}

这样想修改对应尺寸或者样式,就很方便了

其他

查看代码

效果预览