scss
comments 注释
注释
- // 开头的注释,为静默注释,不会编译到 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;
}文档注释 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 变量完全不同。
- Sass 变量都被 Sass 编译掉了。CSS 变量包含在 CSS 输出中。
- CSS 变量对于不同的元素可以有不同的值,但 Sass 变量一次只有一个值。
- Sass 变量是命令式的,这意味着如果你使用一个变量然后改变它的值,之前的使用将保持不变。
- 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 的差异
- @use 仅使变量、函数和 mixin 在当前文件的范围内可用。它永远不会将它们添加到全局范围。这可以很容易地找出你的 Sass 文件引用的每个名称的来源,并且意味着你可以使用较短的名称而不会有任何冲突的风险。
- @use 每个文件只加载一次。这可以确保您最终不会意外地多次重复依赖项的 CSS 。
- @use 必须出现在文件的开头,并且不能嵌套在样式规则中。
- 每个@use 规则只能有一个 URL。
- @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(); // 加引号