总结概要
最后更新于:2022-04-01 10:48:25
总而言之,希望做到如下规范:
* 使用两个空格代表缩进,而不是使用tab键;
* 理想上,每行保持为 80 个字符宽度;
* 正确书写多行 CSS 规则;
* 有意义的使用空格。
* 使用单引号包裹字符串和 URL;
* 数字尾部不使用 0 ,并且强制在小于 1 的数字前使用 0;
* 使用括号包裹运算表达式;
* 不使用幻数;
* 颜色表示法的先后顺序:关键字 > HSL > RGB > 十六进制;
* 使用逗号分隔列表;
* 列表尾部没有逗号(当它们是内联状态时);
* map 尾部有逗号;
* 除了伪类和伪元素,不使用选择器嵌套;
* 使用连字符分隔的命名方式;
* 范围广泛的注释;
* 支持 SassDoc 的 API 注释;
* 限制使用 `@extend`;
* 使用简单的混合宏;
* 尽可能少地使用循环,不使用 `@while` 循环;
* 减少依赖的数量;
* 有意义地使用警告和错误提醒。
SCSS-Lint
最后更新于:2022-04-01 10:48:22
审查代码是非常重要的事情。通常来说,遵从一份样式指南的规范可以帮助减少代码质量上的问题,但是没有人的工作是无懈可击的,何况总有些地方需要改善。所以,可以认为,审查代码和注释文档一样重要。
[SCSS-lint](https://github.com/causes/scss-lint) 是一个帮你保持 SCSS 文件简洁而又具有可读性的工具。它是完全可定制化的,并且非常易于和其他工具集成。
幸运的是,本文档的描述非常类似于 SCSS-lint 的使用建议。为了根据 Sass 样式指南配置 SCSS-lint,建议如下配置:
~~~
# For SCSS-Lint v0.32.0
linters:
BangFormat:
enabled: true
space_before_bang: true
space_after_bang: false
BorderZero:
enabled: true
ColorKeyword:
enabled: false
Comment:
enabled: false
DebugStatement:
enabled: true
DeclarationOrder:
enabled: true
DuplicateProperty:
enabled: false
ElsePlacement:
enabled: true
style: same_line
EmptyLineBetweenBlocks:
enabled: true
ignore_single_line_blocks: false
EmptyRule:
enabled: true
FinalNewline:
enabled: true
present: true
HexLength:
enabled: true
style: short
HexNotation:
enabled: true
style: lowercase
HexValidation:
enabled: true
IdSelector:
enabled: true
ImportPath:
enabled: true
leading_underscore: false
filename_extension: false
Indentation:
enabled: true
character: space
width: 2
LeadingZero:
enabled: true
style: include_zero
MergeableSelector:
enabled: false
force_nesting: false
NameFormat:
enabled: true
convention: hyphenated_lowercase
allow_leading_underscore: true
NestingDepth:
enabled: true
max_depth: 3
PlaceholderInExtend:
enabled: true
PropertySortOrder:
enabled: false
ignore_unspecified: false
PropertySpelling:
enabled: true
extra_properties: []
QualifyingElement:
enabled: true
allow_element_with_attribute: false
allow_element_with_class: false
allow_element_with_id: false
SelectorDepth:
enabled: true
max_depth: 3
SelectorFormat:
enabled: true
convention: hyphenated_lowercase
class_convention: '^(?:u|is|has)\-[a-z][a-zA-Z0-9]*$|^(?!u|is|has)[a-zA-Z][a-zA-Z0-9]*(?:\-[a-z][a-zA-Z0-9]*)?(?:\-\-[a-z][a-zA-Z0-9]*)?$'
Shorthand:
enabled: true
SingleLinePerProperty:
enabled: true
allow_single_line_rule_sets: false
SingleLinePerSelector:
enabled: true
SpaceAfterComma:
enabled: true
SpaceAfterPropertyColon:
enabled: true
style: one_space
SpaceAfterPropertyName:
enabled: true
SpaceBeforeBrace:
enabled: true
style: space
allow_single_line_padding: true
SpaceBetweenParens:
enabled: true
spaces: 0
StringQuotes:
enabled: true
style: single_quotes
TrailingSemicolon:
enabled: true
TrailingZero:
enabled: true
UnnecessaryMantissa:
enabled: true
UnnecessaryParentReference:
enabled: true
UrlFormat:
enabled: false
UrlQuotes:
enabled: true
VendorPrefixes:
enabled: true
identifier_list: base
include: []
exclude: []
ZeroUnit:
enabled: true
~~~
如果你想将 SCSS-lint 插入到 Grunt 构建过程中,那么 Grunt 插件[grunt-scss-lint](https://github.com/ahmednuaman/grunt-scss-lint) 一定会对你有所帮助。
此外,如果你在寻找一个运行 SCSS-lint 的简洁工具,那么 [Thoughtbot](http://thoughtbot.com/)(Bourbon, Neat...) 正在开发的 [Hound](https://houndci.com/) 也会对你有所帮助。
## 扩展阅读
* [SCSS-lint](https://github.com/causes/scss-lint)
* [Clean Up your Sass with SCSS-lint](http://blog.martinhujer.cz/clean-up-your-sass-with-scss-lint/)
* [Improving Sass code quality on theguardian.com](http://www.theguardian.com/info/developer-blog/2014/may/13/improving-sass-code-quality-on-theguardiancom)
* [grunt-scss-lint](https://github.com/ahmednuaman/grunt-scss-lint)
* [An Auto-Enforceable SCSS Styleguide](http://davidtheclark.com/scss-lint-styleguide/)
栅格系统
最后更新于:2022-04-01 10:48:20
随着响应式网页设计地遍地开花,栅格系统布局已经成为了一种必然选择。为了固定大小并使设计风格统一,我们通常使用网格来给元素布局。为了避免反复地布局工作,一些非凡的想法认为应该使它们保持可复用性。
还是长话短说吧:我并非栅格系统的拥趸。当然我确实看到了它的潜力,但大多的是矫枉过正,而且主要是被设计师用来绘制红栏白底的原型。你还记得上一次有 _thank-God-I-have-this-tool-to-build-this-2-5-3.1-π-grid_ 如此赞叹的时间吗?那就对了,从来没有过。因为在多数情况下,你只是想使用12列栅格布局,毫不奇特。
如果你正在项目中使用类似 [Bootstrap](http://getbootstrap.com/) 和 [Foundation](http://foundation.zurb.com/) 的 CSS 框架,我建议善用它们来避免额外的依赖,因为此时它们很有可能就包含了一套栅格系统,。
如果你尚未依赖于特定的栅格系统,那么也许会乐意了解这里介绍的两个由 Sass 支持的栅格引擎:[Susy](http://susy.oddbird.net/) 和 [Singularity](http://singularity.gs/)。它们都可以满足你的需求,所以只需从中挑选喜欢的一个来用即可并且可以放心即使是你的苛刻需求—哪怕是最多变的—也可以被实现。
或者你可以处理地更轻松些,就像使用 [CSSWizardry Grids](https://github.com/csswizardry/csswizardry-grids) 的感觉。总而言之,任何选择都不会对你的代码风格有过多影响,所以这一点上一切取决于你。
###### 扩展阅读
* [Singularity](http://singularity.gs/)
* [Singularity: Grids Without Limits](http://fourword.fourkitchens.com/article/singularity-grids-without-limits)
* [Singularity Grid System](http://www.mediacurrent.com/blog/singularity-grid-system)
* [Susy](http://susy.oddbird.net/)
* [Build Web Layouts Easily with Susy](http://css-tricks.com/build-web-layouts-easily-susy/)
* [A Complete Tutorial to Susy 2](http://www.zell-weekeat.com/susy2-tutorial/)
* [Sass Grids: From Neat to Susy](http://www.sitepoint.com/sass-grids-neat-susy/)
* [Bootstrap’s Grid System vs Susy: a Comparison](http://www.sitepoint.com/bootstraps-grid-system-vs-susy-comparison/)
* [How to Use Susy: Superpowered Sass Grids](http://webdesign.tutsplus.com/tutorials/how-to-use-susy-superpowered-sass-grids--cms-22744)
* [A Creative Grid System with Sass and calc()](http://www.sitepoint.com/creative-grid-system-sass-calc/)
Compass
最后更新于:2022-04-01 10:48:18
[Compass](http://compass-style.org/) 是 Sass 中最主要的框架。其开发者 [Chris Eppstein](https://twitter.com/chriseppstein),是 Sass 的两位核心开发者之一。如果你想听一下我的看法,我想说这个框架一直很流行。
不过,我已经不再使用 Compass 了,主要原因是它很大程度上拖慢了 Sass。Ruby Sass 本身就比较慢,所以在此之上增加更多功能并无益处。
实际上,我们通常只使用了框架本身的一点点功能,而完整的 Compass 是庞大的。混合宏的跨浏览器兼容功能也只是冰山一角。数学函数、图像辅助、幽灵图……使用这个优秀的工具有太多的好处了。
不幸的是,这就是所有的语法糖而且没有一个是杀手级的特性。精灵图生成器虽然_非常优秀_,但也会报出一两个错误。不过 [Grunticon](https://github.com/filamentgroup/grunticon) 和 [Grumpicon](http://grumpicon.com/) 就运行的很好,而且它们还有可以被插入到构建过程的优势。
虽然我不建议使用 Compass,但我也不会禁止使用它,特别是当它不兼容 LibSass 的时候(即使它正朝这个方向努力)。如果你感觉使用起来还不错,这当然可以,但是我认为最终你也不会从中收获更多。
Ruby Sass 目前正着手进行一些很棒的优化,目标是通过运用诸多函数和混合宏实现具有深度逻辑的样式。它们应该显著改善性能,而这往往是 Compass 和其他框架拖慢 Sass 的原因。
## 扩展阅读
* [Compass](http://compass-style.org/)
* [Sass Frameworks: Compass or Bourbon](http://www.sitepoint.com/compass-or-bourbon-sass-frameworks/)
* [Why I don’t use Compass anymore](http://www.sitepoint.com/dont-use-compass-anymore/)
* [Is Compass to Sass with jQuery is to JavaScript?](http://www.sitepoint.com/compass-sass-jquery-javascript/)
工具
最后更新于:2022-04-01 10:48:16
和 Sass 一样受欢迎的 CSS 预处理器的优秀之处就在于,它提供了包括框架、插件、库和工具在内的整套开发环境。Sass 诞生 8 年以来,其本身的特性和[everything that can be written in Sass has been written in Sass](http://hugogiraudel.com/2014/10/27/rethinking-atwoods-law/) 一文中的观点越来越相近。
不过,我的建议是最小程度的依赖于各种工具。管理依赖可能会是你特别不想面对的事情。此外,在 Sass 中很少需要外部依赖。
错误
最后更新于:2022-04-01 10:48:13
错误,与提示有所不同,将会中断编译器的下一步进程。基本上,它们中断编译并像堆栈跟踪一样在输出流中显示相关信息,这对调试很有帮助。因此,如果程序无法继续执行就应该抛出错误。如有可能,尝试解决这个问题并以显示提醒的方式代替。
举个例子,假设你创建了一个 getter 函数来从特定 map 中获取值。如果想要获取的值并不在 map 中,就可能会抛出错误。
~~~
/// Z-indexes map, gathering all Z layers of the application
/// @access private
/// @type Map
/// @prop {String} key - Layer’s name
/// @prop {Number} value - Z value mapped to the key
$z-indexes: (
'modal': 5000,
'dropdown': 4000,
'default': 1,
'below': -1,
);
/// Get a z-index value from a layer name
/// @access public
/// @param {String} $layer - Layer's name
/// @return {Number}
/// @require $z-indexes
@function z($layer) {
@if not map-has-key($z-indexes, $layer) {
@error 'There is no layer named `#{$layer}` in $z-indexes. '
+ 'Layer should be one of #{map-keys($z-indexes)}.';
}
@return map-get($z-indexes, $layer);
}
~~~
警告
最后更新于:2022-04-01 10:48:11
使用 [Sass-MQ](https://github.com/sass-mq/sass-mq) 中的这个函数可以转换 `px` 为 `em`,展示如下:
~~~
@function mq-px2em($px, $base-font-size: $mq-base-font-size) {
@if unitless($px) {
@warn 'Assuming #{$px} to be in pixels, attempting to convert it into pixels.';
@return mq-px2em($px + 0px);
} @else if unit($px) == em {
@return $px;
}
@return ($px / $base-font-size) * 1em;
}
~~~
如果碰巧值是无单位的,这个函数就会默认单位是像素。就这一点而论,一个假设可能会带来风险,所以软件应该能够预测风险并提醒使用者。
警告和错误
最后更新于:2022-04-01 10:48:09
如果提到经常被开发者忽略的特性,那应该就是动态输出错误和提醒的功能了。事实上,Sass 自带三条自定义指令从标准输出系统(CLI,编译程序……)中打印内容:
* `@debug`;
* `@warn`;
* `@error`.
先让我们把 `@debug` 放一边,毕竟它主要是用作调试 SassScript,而这并不是我们的重点。然后我们就剩下了相互间没有明显差异的 `@warn` 和 `@error`,唯一的不同是其中一个可以中断编译器的工作,而另一个不能。我想让你猜猜具体每一个都是做什么的。
现在,在一个 Sass 项目中往往存在大量的错误和提醒。基本上任何混合宏和函数出错都会发生特定类型或参数的错误,或者显示假设的提醒。
###### 扩展阅读
* [An Introduction To Error Handling](http://webdesign.tutsplus.com/tutorials/an-introduction-to-error-handling-in-sass--cms-19996)
* [Building a Logger Mixin](http://webdesign.tutsplus.com/tutorials/building-a-logger-mixin-in-sass--cms-22070)
* [SassyLogger](https://github.com/HugoGiraudel/SassyLogger)
While
最后更新于:2022-04-01 10:48:07
绝对没有必要在真实的 Sass 项目中使用 `@while` 循环——**不要使用它**。
For
最后更新于:2022-04-01 10:48:04
当需要聚合伪类 `:nth-*` 的时候,使用 `@for` 循环很有用。除了这些使用场景,如果_必须_迭代最好还是使用 `@each` 循环。
~~~
@for $i from 1 through 10 {
.foo:nth-of-type(#{$i}) {
border-color: hsl($i * 36, 50%, 50%);
}
}
~~~
要坚持一贯的传统,始终使用 `$i` 作为变量名,除非有非常好的原因,否则永远不要使用 `to` 关键字:而是始终使用 `through`。许多开发者甚至不知道 Sass 有这个变化;使用它可能会造成混乱。
最后,确保遵循规范以保持可读性:
* `each` 前添加空行;
* 除非下一行是右闭大括号(`}`),否则在所有右闭大括号(`}`)后面添加新行。
Each
最后更新于:2022-04-01 10:48:02
`@each` 循环绝对是Sass提供的三个循环方式中最常用的。它提供了一个简洁的 API 来迭代列表或 map。
~~~
@each $theme in $themes {
.section-#{$theme} {
background-color: map-get($colors, $theme);
}
}
~~~
当迭代一个 map 时,通常使用 `$key` 和 `$value` 作为变量名称来确保一致性。
~~~
@each $key, $value in $map {
.section-#{$key} {
background-color: $value;
}
}
~~~
同时遵守下述规则,确保可读性:
* `each` 前添加空行;
* 除非下一行是右闭大括号(`}`),否则在所有右闭大括号(`}`)后面添加新行。
循环
最后更新于:2022-04-01 10:48:00
因为Sass提供了如 [lists](http://sass-guidelin.es/zh/?utm_source=tuicool#lists) 和 [maps](http://sass-guidelin.es/zh/?utm_source=tuicool#maps) 这样的复杂数据结构,所以对于提供给开发者遍历这些数据结构的能力也无需惊讶。
然而,循环的出现意味着存在本不可能出现在Sass中的复杂逻辑。在使用循环之前,务必确定这么做是有道理的,并且确认这么做可以解决问题。
条件语句
最后更新于:2022-04-01 10:47:58
你可能早已知晓,Sass 通过 `@if` 和 `@else` 指令提供了条件语句。除非你的代码中有偏复杂的逻辑,否则没必要在日常开发的样式表中使用条件语句。实际上,条件语句主要适用于库和框架。
无论何时,如果你感觉需要它们,请遵守下述准则:
* 除非必要,不然不需要括号;
* 务必在 `@if` 之前添加空行;
* 务必在左开大括号(`{`)后换行;
* `@else` 语句和它前面的右闭大括号(`}`)写在同一行;
* 务必在右闭大括号(`}`)后添加空行,除非下一行还是右闭大括号(`}`),那么就在最后一个右闭大括号(`}`)后添加空行。
~~~
// Yep
@if $support-legacy {
// ...
} @else {
// ...
}
// Nope
@if ($support-legacy == true) {
// ...
}
@else {
// ...
}
~~~
测试一个错误值时,通常使用 `not` 关键字而不是比较与 `false` 或 `null` 等值。
~~~
// Yep
@if not index($list, $item) {
// ...
}
// Nope
@if index($list, $item) == null {
// ...
}
~~~
通常将变量置于语句的左侧,而将结果置于右侧。如果使用相反的顺序,通常会增加阅读难度,特别是对于没有经验的开发者。
~~~
// Yep
@if $value == 42 {
// ...
}
// Nope
@if 42 == $value {
// ...
}
~~~
当使用条件语句并在一些条件下有内联函数返回不同结果时,始终要确保最外层函数有一个 `@return` 语句。
~~~
// Yep
@function dummy($condition) {
@if $condition {
@return true;
}
@return false;
}
// Nope
@function dummy($condition) {
@if $condition {
@return true;
} @else {
@return false;
}
}
~~~
如果你喜欢 Sass Guidelines,请支持它
[ 支持 Sass Guidelines](https://gum.co/sass-guidelines)
混合宏和浏览器前缀
最后更新于:2022-04-01 10:47:55
通过使用自定义混合宏来处理 CSS 中未被支持或部分支持的浏览器前缀,是非常有吸引力的一种做法。但我们不希望这么做。首先,如果你可以使用[Autoprefixer](https://github.com/postcss/autoprefixer),那就使用它。它会从你的项目中移除Sass代码,会一直更新并一定会进行比你手动添加前缀更棒的处理。
不行的是,Autoprefixer 并不是总被支持的。如果你使用 [Bourbon](http://bourbon.io/) 或[Compass](http://compass-style.org/),你可能就已经知道它们都提供了一个混合宏的集合,用来为你处理浏览器前缀,那就用它们吧。
如果你不能使用 Autoprefixe,甚至也不能使用 Bourbon 和 Compass,那么接下来唯一的方式,就是使用自己的混合宏处理带有前缀的 CSS 属性。但是,请不要为每个属性建立混合宏,更不要无脑输出每个浏览器的前缀(有些根本就不存在)。
~~~
// Nope
@mixin transform($value) {
-webkit-transform: $value;
-moz-transform: $value;
transform: $value;
}
~~~
比较好的做法是
~~~
/// Mixin helper to output vendor prefixes
/// @access public
/// @author HugoGiraudel
/// @param {String} $property - Unprefixed CSS property
/// @param {*} $value - Raw CSS value
/// @param {List} $prefixes - List of prefixes to output
@mixin prefix($property, $value, $prefixes: ()) {
@each $prefix in $prefixes {
-#{$prefix}-#{$property}: $value;
}
#{$property}: $value;
}
~~~
然后就可以非常简单地使用混合宏了:
~~~
.foo {
@include prefix(transform, rotate(90deg), ('webkit', 'ms'));
}
~~~
请记住,这是一个糟糕的解决方案。例如,他不能处理那些需要复杂的前缀,比如 `flexbox`。在这个意义上说,使用 Autoprefixer 是一个更好地选择。
## 扩展阅读
* [Autoprefixer](https://github.com/postcss/autoprefixer)
* [Building a Linear-Gradient Mixin](http://www.sitepoint.com/building-linear-gradient-mixin-sass/)
参数列表
最后更新于:2022-04-01 10:47:53
当混合宏需要处理数量不明的参数时,通常使用 `arglist` 而不是列表。可以认为 `arglist` 是 Sass 中隐藏而未被记录的第八个数据类型,通常当需要任意数量参数的时候,被隐式使用到参数中含有 `...` 标志的混合宏和函数中。
~~~
@mixin shadows($shadows...) {
// type-of($shadows) == 'arglist'
// ...
}
~~~
现在,当要建立一个接收多个参数(默认为 3 或者更多)的混合宏时,在将它们合并为列表或者 map 之前,要反复考量这样做是否比一个个的单独存在更易于使用。
Sass 的混合宏和函数声明非常智能,你只需给函数/混合宏一个列表或 map,它会自动解析为一系列的参数。
~~~
@mixin dummy($a, $b, $c) {
// ...
}
// Yep
@include dummy(true, 42, 'kittens');
// Yep but nope
$params: (true, 42, 'kittens');
$value: dummy(nth($params, 1), nth($params, 2), nth($params, 3));
// Yep
$params: (true, 42, 'kittens');
@include dummy($params...);
// Yep
$params: (
'c': 'kittens',
'a': true,
'b': 42,
);
@include dummy($params...);
~~~
## 扩展阅读
* [Sass Multiple Arguments, Lists or Arglist](http://www.sitepoint.com/sass-multiple-arguments-lists-or-arglist/)
基础
最后更新于:2022-04-01 10:47:51
话虽如此,混合宏确实非常有用,你应该学习使用它。经验告诉我们,如果你发现有一组 CSS 属性经常因同一个原因一起出现(非巧合),那么你就可以使用混合宏来代替。比如[Nicolas Gallagher的清除浮动](http://nicolasgallagher.com/micro-clearfix-hack/)应当放入一个混合宏的实例。
~~~
/// Helper to clear inner floats
/// @author Nicolas Gallagher
/// @link http://nicolasgallagher.com/micro-clearfix-hack/ Micro Clearfix
@mixin clearfix {
&::after {
content: '';
display: table;
clear: both;
}
}
~~~
另一个有效的实例是通过在混合宏中绑定 `width` 和 `height` 属性,可以为元素设置宽高。这样不仅会淡化不同类型代码间的差异,也便于阅读。
~~~
/// Helper to size an element
/// @author Hugo Giraudel
/// @param {Length} $width
/// @param {Length} $height
@mixin size($width, $height: $width) {
width: $width;
height: $height;
}
~~~
## 扩展阅读
* [Sass Mixins to Kickstart your Project](http://www.sitepoint.com/sass-mixins-kickstart-project/)
* [A Sass Mixin for CSS Triangles](http://www.sitepoint.com/sass-mixin-css-triangles/)
* [Building a Linear-Gradient Mixin](http://www.sitepoint.com/building-linear-gradient-mixin-sass/)
混合宏
最后更新于:2022-04-01 10:47:49
混合宏是整个 Sass 语言中最常用的功能之一。这是重用和减少重复组件的关键。这么做有很棒的原因:混合宏允许开发者在样式表中定义可复用样式,减少了对非语义类的需求,比如`.float-left`。
它们可以包含所有的 CSS 规则,并且在 Sass 文档允许的任何地方都表现良好。它们甚至可以像函数一样接受参数。不用多说,充满了无尽的可能。
不过我有必要提醒你滥用混合宏的破坏力量。再次重申一遍,使用混合宏的关键是**简洁**。建立混入大量逻辑而极具力量的混合宏看上去确实很有诱惑力。这就是所谓的过度开发,大多数开发者常常因此陷入困境。不要过度逻辑化你的代码,尽量保持一切简洁。如果一个混合宏最后超过了 20 行,那么它应该被分离成更小的块甚至是重建。
扩展
最后更新于:2022-04-01 10:47:46
`@extend` 指令是几年前使 Sass 风靡一时的重要特性之一。该指令作为一个警示,告知 Sass 对元素 A 的样式化正好存在与选择器B共通的地方。不用多说,这是书写模块化 CSS 的好助手。
然而我感觉必须提醒你谨慎使用这个特性。正因灵活多变,所以 `@extend` 还是一个棘手的概念,某些时候可能弊大于利,特别是被滥用时。当扩展一个选择器时,除非你对整个代码库有深入的了解,不然肯定没法回答诸如下面的问题:
* 当前选择器要追加到哪里?
* 我是否会碰上意料之外的副作用?
* 这条简单的扩展将会产生多大的CSS?
如你所知,结果的可能即包括没有任何影响,也包括灾难性副作用。因此,我的第一建议是完全避免使用 `@extend` 指令。这听起来有些残酷,但最终会拯救你于水火之中。
俗话说的好:
> 永远不要说不可能。
> — Apparently, [not Beyonce](https://github.com/HugoGiraudel/sass-guidelines/issues/31#issuecomment-69112419).
扩展选择器在有些情境下是有用和值得的。始终牢记这些规则,那样就不会是自己陷入困境:
* 从单一模块扩展,而不是多个不同的模块;
* 只使用占位符扩展,而不使用实际的选择器;
* 确保用来扩展的占位符是样式表中尽可能小的。
如果你要使用扩展,我想提醒你它也不能与 `@media` 块元素融洽相处。如你所知,Sass 不能在一个媒体查询中扩展外部的选择器。当你这么做的时候,编译器轻易就会崩溃,并提醒你不能这么干。这不是好消息,特别是几乎所有人都知道媒体查询功能。
~~~
.foo {
content: 'foo';
}
@media print {
.bar {
// This doesn't work. Worse: it crashes.
@extend .foo;
}
}
~~~
> 无法在 `@media` 内部 `@extend` 一个外部选择器。 只可以使用相同指令 `@extend` 选择器。
这就是常说的 `@extend` 可以通过合并选择器而不是复制属性帮助减小文件大小。这种说法是对的,不过一旦经 [Gzip](http://en.wikipedia.org/wiki/Gzip) 处理后这点差异完全可以忽略不计。
也就是说,如果你无法使用 Gzip(或相同工具),在你足够精通的前提下使用`@extend` 方式也是不错的。
总而言之,除非在某些特殊情况下,否则我**建议不要使用 `@extend` 指令**,但我不会禁用它。
## 扩展阅读
* [What Nobody Told you About Sass Extend](http://www.sitepoint.com/sass-extend-nobody-told-you/)
* [Why You Should Avoid Extend](http://www.sitepoint.com/avoid-sass-extend/)
* [Don’t Over Extend Yourself](http://pressupinc.com/blog/2014/11/dont-overextend-yourself-in-sass/)
* [When to Use Extend; When to Use a Mixin](http://csswizardry.com/2014/11/when-to-use-extend-when-to-use-a-mixin/)
多变量或maps
最后更新于:2022-04-01 10:47:44
使用 maps 比使用多个不同的变量有明显优势。最重要的优势就是 map 的遍历功能,这在多个不同变量中是不可能实现的。
另一个支持使用 map 的原因,是它可以创建 `map-get()` 函数以提供友好 API 的功能。比如,思考一下下述 Sass 代码:
~~~
/// Z-indexes map, gathering all Z layers of the application
/// @access private
/// @type Map
/// @prop {String} key - Layer's name
/// @prop {Number} value - Z value mapped to the key
$z-indexes: (
'modal': 5000,
'dropdown': 4000,
'default': 1,
'below': -1,
);
/// Get a z-index value from a layer name
/// @access public
/// @param {String} $layer - Layer’s name
/// @return {Number}
/// @require $z-indexes
@function z($layer) {
@return map-get($z-indexes, $layer);
}
~~~
!global标识符
最后更新于:2022-04-01 10:47:42
`!global` 标志应该只在局部范围的全局变量被覆盖时使用。定义根级别的变量时,`!global` 标志应该省略。
~~~
// Yep
$baseline: 2em;
// Nope
$baseline: 2em !global;
~~~