• home > webfront > style > sass >

    SASS详解@mixins/@include/@extend/@at-root

    Author:zhoulujun Date:

    Sass 支持所有CSS3的 @规则,以及一些已知的其他特定的Sass "指令 "。@at-root限定输出在文档的根层级上,而不是被嵌套在其父选择器下。@extend 继承另一选择器样式@mixin 指令允许我们定义一个可以在整个样式表中重复使用的

    Sass 支持所有CSS3的 @规则,以及一些已知的其他特定的Sass "指令"。这些在 Sass 都有对应的效果,更多资料请查看 控制指令 (control directives) 。今天重点讲mixins/include/extend

    • @at-root限定输出在文档的根层级上,而不是被嵌套在其父选择器下。

    • @extend 继承另一选择器样式

    • @mixin 指令允许我们定义一个可以在整个样式表中重复使用的样式。

    • @include 指令可以将混入(mixin)引入到文档中。

    @extend

    当一个样式类(class)含有另一个类的所有样式,并且它自己的特定样式。我们使用@extend

    .error {
      border: 1px #f00;
      background-color: #fdd;
    }
    .seriousError {
      @extend .error;
      border-width: 3px;
    }

    编译为

    .error, .seriousError {
      border: 1px #f00;
      background-color: #fdd;
    }
    
    .seriousError {
      border-width: 3px;
    }


    @extend通过在样式表中出现被扩展选择器(例如.error)的地方插入扩展选择器(例如.seriousError)

    混合(mixins)

    混入(mixin)通过 @mixin 指令定义。在它后面跟混入的名称和任选的arguments(参数),以及混入的内容块。

    Mixin有点像C语言的宏(macro),是可以重用的代码块。使用@mixin命令,定义一个代码块。

    @mixin命令应用

    使用@mixin命令,可以指定参数和缺省值。

    @mixin left($value: 10px) {
        float: left;
        margin-right: $value;
    }

    使用的时候,根据需要加入参数:

    div {
        @include left(20px);
      }

    下面是一个mixin的实例,用来生成浏览器前缀。

    @mixin rounded($vert, $horz, $radius: 10px) {
        border-#{$vert}-#{$horz}-radius: $radius;
        -moz-border-radius-#{$vert}#{$horz}: $radius;
        -webkit-border-#{$vert}-#{$horz}-radius: $radius;
    }
    #navbar li { @include rounded(top, left); }
    #footer { @include rounded(top, left, 5px); }

    再来个复杂点的

    scss换肤

    • 添加全局样式,动态改变主题

    • 通过scss 定义多套主题

    • 使用混合模式动态取值

    // 1.主题定义
    $theme-default: (
      font-color: red,
      font-size: 14px,
      background: pink,
    );
    
    $theme-green: (
      font-color: green,
      font-size:18px,
      background: yellow,
    );
    
    $theme-blue: (
      font-color: blue,
      font-size:24px,
      background: #fff,
    );
    
    //  2.将定义好到主题添加到map中
    $themes:(
      default:$theme-default,
      green:$theme-green,
      blue:$theme-blue,
    );
    
    // 4. 调用混合指令themify() ,定义规则,此处到规则会替换@content
    @mixin mytheme{
      @include themify() {
        color: themed("font-color");
        font-size: themed("font-size");
        .test-theme {
          background: themed("background");
        }
      }
    };
    
    // 3.定义混合指令, 切换主题,并将主题中到所有规则添加到theme-map中
    @mixin themify() {
      @each $theme-name, $map in $themes {
        // & 表示父级元素
        // !global 表示覆盖原来的
        .theme-#{$theme-name} & {
          $theme-map: () !global;
          // 循环合并键值对
          @each $key, $value in $map {
            $theme-map: map-merge($theme-map, ($key: $value)) !global;
          }
          // 表示包含 下面函数 themed()
          @content;
          $theme-map: null !global;
        }
      }
    }
    
    // 通过key获取map中到值
    @function themed($key) {
      @return map-get($theme-map, $key);
    }


    这里需要熟悉 Sass Maps的语法

    Sass Maps的语法

    Maps代表一个键和值对集合,其中键用于查找值。

    Sass的map使用一个括号,并用冒号将键值与值分隔开来,并且使用逗号将一对键值/值隔开。下面是一个有效的Sass的map:

    $map: ( 
        key1: value1, 
        key2: value2,
        nextKey: nextvalue,
        other-key: other-value 
    );

    键值不一定是字符串,他可以是任何类型。甚至是null,甚至是map。

    • map中的最后一对键值/值后面的逗号可以省略

    • 键值必须是唯一的

    • 键值/值可以是Sass的任何类型,包括列表和其他的Sass map

    Maps的主要操作使用的是 SassScript 函数map-get函数用于查找map中的值,map-merge函数用于添加值到map中的值, @each 指令可以用来为 map 中的每个键值对添加样式。map中键值对的顺序和map创建时始终相同。

    • map-get()方法来找出某个key的value

    • map-has-key()检测出某个key是否存在

    • map-merge()合并两个甚至更多个maps成一个

    $colors: (
      light: #ccc,
      dark: #000
    );
    
    $brand-colors: (
      main: red,
      alternative: blue
    );
    .element {
      //判断是否存在light颜色
      @if map-has-key($colors, light){
        color: map-get($colors, light);
      } @else {
        color: map-get($brand-colors, light);
        content: 'color Map has not this key.'
      }
    }
    // 合并maps
    $merged: map-merge($colors, $brand-colors);
    .element {
      content: map-get($merged, alternative);
    }

    这个只是用法说明

    sass map的经典案例

    // _m-buttons.scss
    $buttons: (
      error: (#d82d2d, #666),
      success: (#52bf4a, #fff),
      warning: (#c23435, #fff)
    );
    
    .m-button {
      display: inling-block;
      padding: .5em;
      background: #ccc;
      color: #666;
    
      @each $name, $colors in $buttons {
        $bgcolor: nth($colors, 1);
        $fontcolor: nth($colors, 2);
    
        &--#{$name} {
          background-color: $bgcolor;
          color: $fontcolor;
        }
      }
    }


    参考文章:

    介绍Sass Maps:用法跟例子 https://aotu.io/notes/2015/12/09/an-introduction-to-sass-maps/index.html

    使用Sass Maps https://www.w3cplus.com/preprocessor/using-sass-maps.html

    新手也可以輕鬆玩轉 SASS - @mixin and @include https://5xruby.tw/posts/play-sass-mixin-and-include/

    extend、mixin、function使用時機 https://icguanyu.github.io/scss/scss_2/

    Sass (3.4.21) 中文文档 https://www.html.cn/doc/sass/#mixins



    转载本站文章《SASS详解@mixins/@include/@extend/@at-root》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/style/sass/2020_0827_8550.html