Skip to main content

scss

comments 注释

  1. 注释

    • // 开头的注释,为静默注释,不会编译到 css 中
    • /xxx/ 多行注释,会被编译
    // This comment won't be included in the CSS.

    /* But this comment will, except in compressed mode. */

    /* It can also contain interpolation:
    * 1 + 1 = #{1 + 1} */

    /*! This comment will be included even in compressed mode. */

    p .sans {
    font: Helvetica,
    // So can single-line commments.
    sans-serif;
    }

    编译成 css

    /* But this comment will, except in compressed mode. */
    /* It can also contain interpolation:
    * 1 + 1 = 2 */
    /*! This comment will be included even in compressed mode. */
    p .sans {
    font: Helvetica, sans-serif;
    }
  2. 文档注释 Sass 编写样式库时,可以使用注释来记录您的库提供的 mixins、函数(functions)、变量(variables)和占位符选择器(placeholder selectors)

    sassdoc: http://sassdoc.com/upgrading/

    /// @param {number} $base
    /// The number to multiply by itself.
    /// @param {integer (unitless)} $exponent
    /// The number of `$base`s to multiply together.
    /// @return {number} `$base` to the power of `$exponent`.
    @function pow($base, $exponent) {
    $result: 1;
    @for $_ from 1 through $exponent {
    $result: $result * $base;
    }
    @return $result;
    }

url

css 中 url(url)中的 url 可以带引号也可以不带引号

$roboto-font-path: '../fonts/roboto';

@font-face {
// This is parsed as a normal function call that takes a quoted string.
src: url('#{$roboto-font-path}/Roboto-Thin.woff2') format('woff2');
font-family: 'Roboto';
font-weight: 100;
}

@font-face {
// This is parsed as a normal function call that takes an arithmetic
// expression.
src: url($roboto-font-path + '/Roboto-Light.woff2') format('woff2');
font-family: 'Roboto';
font-weight: 300;
}

@font-face {
// This is parsed as an interpolated special function.
src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format('woff2');
font-family: 'Roboto';
font-weight: 400;
}
%toolbelt {
box-sizing: border-box;
border-top: 1px rgba(#000, 0.12) solid;
padding: 16px 0;
width: 100%;

&:hover {
border: 2px rgba(#000, 0.5) solid;
}
}

.action-buttons {
@extend %toolbelt;
color: #4285f4;
}

.reset-buttons {
@extend %toolbelt;
color: #cddc39;
}
.reset-buttons,
.action-buttons {
box-sizing: border-box;
border-top: 1px rgba(0, 0, 0, 0.12) solid;
padding: 16px 0;
width: 100%;
}
.reset-buttons:hover,
.action-buttons:hover {
border: 2px rgba(0, 0, 0, 0.5) solid;
}

.action-buttons {
color: #4285f4;
}

.reset-buttons {
color: #cddc39;
}

变量(Variables)

scss 变量

CSS 有自己的变量,与 Sass 变量完全不同。

  1. Sass 变量都被 Sass 编译掉了。CSS 变量包含在 CSS 输出中。
  2. CSS 变量对于不同的元素可以有不同的值,但 Sass 变量一次只有一个值。
  3. Sass 变量是命令式的,这意味着如果你使用一个变量然后改变它的值,之前的使用将保持不变。
  4. CSS 变量是声明性的,这意味着如果您更改值,它将影响早期使用和后期使用。

Scss 不能修改由内置模块定义的变量。

$dark-theme: true !default;
$primary-color: #f8bbd0 !default;
$accent-color: #6a1b9a !default;

@if $dark-theme {
$primary-color: darken($primary-color, 60%);
$accent-color: lighten($accent-color, 60%);
}

.button {
background-color: $primary-color;
border: 1px solid $accent-color;
border-radius: 3px;
}
.button {
background-color: #750c30;
border: 1px solid #f5ebfc;
border-radius: 3px;
}

map

$theme-colors: (
'success': #28a745,
'info': #17a2b8,
'warning': #ffc107,
);

.alert {
background-color: map.get($theme-colors, 'warning');
}
.alert {
background-color: #ffc107;
}

插值(Interpolation)

在需要的地方包装一个 #{}

基本

@mixin corner-icon($name, $top-or-bottom, $left-or-right) {
.icon-#{$name} {
background-image: url("/icons/#{$name}.svg");
position: absolute;
#{$top-or-bottom}: 0;
#{$left-or-right}: 0;
}
}
@include corner-icon("mail", top, left);
.icon-mail {
background-image: url('/icons/mail.svg');
position: absolute;
top: 0;
left: 0;
}

sassScript

@mixin inline-animation($duration) {
$name: inline-#{unique-id()};

@keyframes #{$name} {
@content;
}

animation-name: $name;
animation-duration: $duration;
animation-iteration-count: infinite;
}

.pulse {
@include inline-animation(2s) {
from {
background-color: yellow;
}
to {
background-color: red;
}
}
}
.pulse {
animation-name: inline-u7372ot;
animation-duration: 2s;
animation-iteration-count: infinite;
}
@keyframes inline-u7372ot {
from {
background-color: yellow;
}
to {
background-color: red;
}
}

规则(Rules)

1.@use

概述

@use 从其他 Sass 样式表中加载 mixins、函数和变量,并将来自多个样式表的 CSS 组合在一起。

按照惯例,仅打算作为模块加载而不是自行编译的 Sass 文件以(如_code.scss) 开头。这些被称为 partials,它们告诉 Sass 工具不要尝试自己编译这些文件。您可以在导入部分时省略.

修改默认配置

// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;

code {
border-radius: $border-radius;
box-shadow: $box-shadow;
}
// style.scss
@use 'library' with (
$black: #222,
$border-radius: 0.1rem
);
code {
border-radius: 0.1rem;
box-shadow: 0 0.5rem 1rem rgba(34, 34, 34, 0.15);
}

重新分配变量

// _library.scss
$color: red;
// _override.scss
@use 'library';
library.$color: blue;
// style.scss
@use 'library';
@use 'override';
@debug library.$color; //=> blue

索引文件

// foundation/_code.scss
code {
padding: .25em;
line-height: 0;
}
// foundation/_lists.scss
ul, ol {
text-align: left;

& & {
padding: {
bottom: 0;
left: 0;
}
}
}
// foundation/_index.scss
@use 'code';
@use 'lists';
// style.scss
@use 'foundation';
code {
padding: 0.25em;
line-height: 0;
}

ul,
ol {
text-align: left;
}
ul ul,
ol ol {
padding-bottom: 0;
padding-left: 0;
}

和 import 的差异

  1. @use 仅使变量、函数和 mixin 在当前文件的范围内可用。它永远不会将它们添加到全局范围。这可以很容易地找出你的 Sass 文件引用的每个名称的来源,并且意味着你可以使用较短的名称而不会有任何冲突的风险。
  2. @use 每个文件只加载一次。这可以确保您最终不会意外地多次重复依赖项的 CSS 。
  3. @use 必须出现在文件的开头,并且不能嵌套在样式规则中。
  4. 每个@use 规则只能有一个 URL。
  5. @use 需要在其 URL 周围加上引号,即使在使用缩进语法时也是如此。

2.@forward

@forward 转发模块

转发

// src/_list.scss
@mixin list-reset {
margin: 0;
padding: 0;
list-style: none;
}
// bootstrap.scss
@forward 'src/list';
// styles.scss
@use 'bootstrap';

li {
@include bootstrap.list-reset;
}
li {
margin: 0;
padding: 0;
list-style: none;
}

添加前缀

编写@forward "<url>" as <prefix>-\*的,它将给定的前缀添加到模块转发的每个 mixin、函数和变量名的开头。

// src/_list.scss
@mixin reset {
margin: 0;
padding: 0;
list-style: none;
}
// bootstrap.scss
@forward "src/list" as list-*;
// styles.scss
@use "bootstrap";

li {
@include bootstrap.list-reset;
}
li {
margin: 0;
padding: 0;
list-style: none;
}

控制转发

- @forward "<url>" hide members... hide 表格意味着不应该转发列出的成员,但其他所有内容都应该转发
- @forward "<url>" show members... show 形式意味着只应转发指定的成员
// src/_list.scss
$horizontal-list-gap: 2em;

@mixin list-reset {
margin: 0;
padding: 0;
list-style: none;
}

@mixin list-horizontal {
@include list-rest;

li {
display: inline-block;
margin: {
left: -2px;
right: $horizontal-list-gap;
}
}
}
// bootstrap.scss
@forward "src/list" hide list-reset, $horizontal-list-gap;

模块转发

// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;

code {
border-radius: $border-radius;
box-shadow: $box-shadow;
}
// _opinionated.scss
@forward 'library' with (
$black: #222 !default,
$border-radius: 0.1rem !default
);
// style.scss
@use 'opinionated' with ($black: #333);
code {
border-radius: 0.1rem;
box-shadow: 0 0.5rem 1rem rgba(51, 51, 51, 0.15);
}

3.mixin 和 include

该规则编写为@mixin <name> { ... } @mixin name(<arguments...>) { ... } @include 将 Mixin 包含到当前上下文中,该规则写为

  • @include <name>
  • @include <name>(<arguments...>),其中包含 mixin 的名称。

概述

@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;

[dir=rtl] & {
#{$property}: $rtl-value;
}
}

.sidebar {
@include rtl(float, left, right);
}
.sidebar {
float: left;
}
[dir='rtl'] .sidebar {
float: right;
}

可选参数

@mixin replace-text($image, $x: 50%, $y: 50%) {
text-indent: -99999em;
overflow: hidden;
text-align: left;

background: {
image: $image;
repeat: no-repeat;
position: $x $y;
}
}

.mail-icon {
@include replace-text(url("/images/mail.svg"), 0);
}
.mail-icon {
text-indent: -99999em;
overflow: hidden;
text-align: left;
background-image: url('/images/mail.svg');
background-repeat: no-repeat;
background-position: 0 50%;
}

关键字参数

@mixin square($size, $radius: 0) {
width: $size;
height: $size;

@if $radius != 0 {
border-radius: $radius;
}
}

.avatar {
@include square(100px, $radius: 4px);
}
.avatar {
width: 100px;
height: 100px;
border-radius: 4px;
}

剩余参数

@mixin order($height, $selectors...) {
@for $i from 0 to length($selectors) {
#{nth($selectors, $i + 1)} {
position: absolute;
height: $height;
margin-top: $i * $height;
}
}
}
@include order(150px, "input.name", "input.address", "input.zip");
input.name {
position: absolute;
height: 150px;
margin-top: 0px;
}

input.address {
position: absolute;
height: 150px;
margin-top: 150px;
}

input.zip {
position: absolute;
height: 150px;
margin-top: 300px;
}

任意关键字参数

该 meta.keywords()函数接受一个参数列表并返回任何额外的关键字,这些关键字作为从参数名称(不包括)到这些参数值的映射传递给 mixin.

@use 'sass:meta';

@mixin syntax-colors($args...) {
@debug meta.keywords($args);
// (string: #080, comment: #800, variable: #60b)

@each $name, $color in meta.keywords($args) {
pre span.stx-#{$name} {
color: $color;
}
}
}

@include syntax-colors($string: #080, $comment: #800, $variable: #60b);
pre span.stx-string {
color: #080;
}

pre span.stx-comment {
color: #800;
}

pre span.stx-variable {
color: #60b;
}

传递任意参数

$form-selectors: "input.name", "input.address", "input.zip" !default;

@include order(150px, $form-selectors...);

内容快

1
@mixin hover {
&:not([disabled]):hover {
@content;
}
}

.button {
border: 1px solid black;

@include hover {
border-width: 2px;
}
}
.button {
border: 1px solid black;
}
.button:not([disabled]):hover {
border-width: 2px;
}
2.传参数
@mixin media($types...) {
@each $type in $types {
@media #{$type} {
@content($type);
}
}
}
@include media(screen, print) using ($type) {
h1 {
font-size: 40px;
@if $type == print {
font-family: Calluna;
}
}
}
@media screen {
h1 {
font-size: 40px;
}
}
@media print {
h1 {
font-size: 40px;
font-family: Calluna;
}
}
3

mixin 可以将参数传递给它的内容块,就像它通过编写将参数传递给另一个 mixin 一样@content(<arguments...>)。编写内容块的用户可以通过编写来接受参数@include <name> using (<arguments...>)。内容块的参数列表就像 mixin 的参数列表一样工作,通过@content 工作传递给它的参数就像将参数传递给 mixin。

@mixin media($types...) {
@each $type in $types {
@media #{$type} {
@content ($type);
}
}
}

@include media(screen, print) using ($type) {
h1 {
font-size: 40px;

@if $type == print {
font-family: Calluna;
}
}
}
@media screen {
h1 {
font-size: 40px;
}
}
@media print {
h1 {
font-size: 40px;
font-family: Calluna;
}
}

函数(function)

基本用法

@function pow($base, $exponent) {
$result: 1;
@for $_ from 1 through $exponent {
$result: $result * $base;
}
@return $result;
}

.sidebar {
float: left;
margin-left: pow(4, 3) * 1px;
}
.sidebar {
float: left;
margin-left: 64px;
}

参数

通常,函数声明的每个参数都必须在包含该函数时传递。但是,您可以通过定义一个默认值来使参数成为可选参数,如果该参数未传递,则将使用该默认值.

@function invert($color, $amount: 100%) {
$inverse: change-color($color, $hue: hue($color) + 180);
@return mix($inverse, $color, $amount);
}

$primary-color: #036;
.header {
background-color: invert($primary-color, 80%);
}

扩展运算符

@function sum($numbers...) {
$sum: 0;
@each $number in $numbers {
$sum: $sum + $number;
}
@return $sum;
}

.micro {
width: sum(50px, 30px, 100px);
}
.micro {
width: 180px;
}

传递任意参数 1

$widths: 50px, 30px, 100px;
.micro {
width: min($widths...);
}

return

@returnat 规则指示用作调用函数结果的值。它只允许在@function 正文中,并且每个都@function 必须以 @return 结束

extend

demo1

.error1 {
background-color: #fee;

&:hover {
background-color: #fdd;
}
}

.error1--serious {
@extend .error1;

border-width: 3px;
}
.error1,
.error1--serious {
background-color: #fee;
}
.error1:hover,
.error1--serious:hover {
background-color: #fdd;
}

.error1--serious {
border-width: 3px;
}

demo2

.icon {
transition: background-color ease 0.2s;
margin: 0 0.5em;
}

.error-icon {
@extend .icon;
/*错误图标指定的样式... */
}

.info-icon {
@extend .icon;
/* 信息图标指定的样式... */
}
.icon,
.error-icon,
.info-icon {
transition: background-color ease 0.2s;
margin: 0 0.5em;
}

.error-icon {
/*错误图标指定的样式... */
}

.info-icon {
/* 信息图标指定的样式... */
}

占位符 %placeholder

%icon {
transition: background-color ease 0.2s;
margin: 0 0.5em;
}

.error-icon {
@extend %icon;
/*错误图标指定的样式... */
}

.info-icon {
@extend %icon;
/* 信息图标指定的样式... */
}
.error-icon,
.info-icon {
transition: background-color ease 0.2s;
margin: 0 0.5em;
}

.error-icon {
/*错误图标指定的样式... */
}

.info-icon {
/* 信息图标指定的样式... */
}

at-root

@at-root 只会摆脱样式规则

@at-root (with: <rules...>) { ... };(with: ...)查询排除除列出的规则之外的所有规则。 @at-root (without: <rules...>) { ... };(without: ...)查询告诉 Sass 哪些规则应该被排除;

Flow Control

if

@if <expression> { ... }

@mixin avatar($size, $circle: false) {
width: $size;
height: $size;

@if $circle {
border-radius: $size / 2;
}
}

.square-av {
@include avatar(100px, $circle: false);
}
.circle-av {
@include avatar(100px, $circle: true);
}

@else

$light-background: #f2ece4;
$light-text: #036;
$dark-background: #6b717f;
$dark-text: #d2e1dd;

@mixin theme-colors($light-theme: true) {
@if $light-theme {
background-color: $light-background;
color: $light-text;
} @else {
background-color: $dark-background;
color: $dark-text;
}
}
.banner {
@include theme-colors($light-theme: true);
body.dark & {
@include theme-colors($light-theme: false);
}
}

@else if

@use "sass:math";

@mixin triangle($size, $color, $direction) {
height: 0;
width: 0;

border-color: transparent;
border-style: solid;
border-width: math.div($size, 2);

@if $direction == up {
border-bottom-color: $color;
} @else if $direction == right {
border-left-color: $color;
} @else if $direction == down {
border-top-color: $color;
} @else if $direction == left {
border-right-color: $color;
} @else {
@error "Unknown direction #{$direction}.";
}
}

.next {
@include triangle(5px, black, right);
}

真假

如果要检查字符串是否包含空格,则只需编写 string.index($string, " ") 空字符串、空列表和数字 0 在 Sass 中都是真值。

each

循环列表map

@each <variable> in <expression> { ... },表达式返回一个列表

1.列表

$sizes: 40px, 50px, 80px;

@each $size in $sizes {
.icon-#{$size} {
font-size: $size;
height: $size;
width: $size;
}
}
.icon-40px {
font-size: 40px;
height: 40px;
width: 40px;
}

.icon-50px {
font-size: 50px;
height: 50px;
width: 50px;
}

.icon-80px {
font-size: 80px;
height: 80px;
width: 80px;
}

2.map

$icons: (
'eye': '\f112',
'start': '\f12e',
'stop': '\f12f',
);

@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: 'Icon Font';
content: $glyph;
}
}

3.解构

变量匹配内部列表的结构。每个变量名都分配给列表中相应位置的值,或者 null 如果列表没有足够的值。

$icons: 'eye' '\f112'12px, 'start' '\f12e'16px, 'stop' '\f12f'10px;

@each $name, $glyph, $size in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: 'Icon Font';
content: $glyph;
font-size: $size;
}
}

for

@for <variable> from <expression> to <expression> { ... } to 使用,则排除最终数字 @for <variable> from <expression> through <expression> { ... } through 使用,则包括在内。

$base-color: #036;

@for $i from 1 through 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
@for $i from 1 to 3 {
li:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
ul:nth-child(3n + 1) {
background-color: #004080;
}

ul:nth-child(3n + 2) {
background-color: #004d99;
}

ul:nth-child(3n + 3) {
background-color: #0059b3;
}

li:nth-child(3n + 1) {
background-color: #004080;
}

li:nth-child(3n + 2) {
background-color: #004d99;
}

while

@use "sass:math";

/// Divides `$value` by `$ratio` until it's below `$base`.
@function scale-below($value, $base, $ratio: 1.618) {
@while $value > $base {
$value: math.div($value, $ratio);
}
@return $value;
}

$normal-font-size: 16px;
sup {
font-size: scale-below(20px, 16px);
}

values

number

string

string.unquote(); // 去除引号 string.quote(); // 加引号