本文是Sass Guidelines中文版本最后一篇,在这篇文章中主要涵盖了Sass中的循环处理、排错以及工具方面的使用。并且对整个指南做了一个最终总结。
因为Sass提供了如lists和maps这样的复杂数据结构,所以对于提供给开发者遍历这些数据结构的能力也无需惊讶。
然而,循环的出现意味着存在本不可能出现在Sass中的复杂逻辑。在使用循环之前,务必确定这么做是有道理的,并且确认这么做可以解决问题。
@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
时也要尊重这些指南,保持代码的可读性:
@each
总是在新的一行开始}
总是在空的一行,除非下一行还有{
当需要聚合伪类: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有这个变化;使用它可能会造成混乱。
最后,确保遵循规范以保持可读性:
for
前添加空行;}
),否则在所有右闭大括号(}
)后面添加新行。绝对没有必要在真实的Sass项目中使用@while
循环——不要使用它。
如果提到经常被开发者忽略的特性,那应该就是动态输出错误和提醒的功能了。事实上,Sass自带三条自定义指令从标准输出系统(CLI,编译程序……)中打印内容:
@debug
;@warn
;@error
.先让我们把@debug
放一边,毕竟它主要是用作调试SassScript,而这并不是我们的重点。然后我们就剩下了相互间没有明显差异的@warn
和@error
,唯一的不同是其中一个可以中断编译器的工作,而另一个不能。我想让你猜猜具体每一个都是做什么的。
现在,在一个Sass项目中往往存在大量的错误和提醒。基本上任何混合宏和函数出错都会发生特定类型或参数的错误,或者显示假设的提醒。
使用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;
}
如果碰巧值是无单位的,这个函数就会默认单位是像素。就这一点而论,一个假设可能会带来风险,所以软件应该能够预测风险并提醒使用者。
错误,与提示有所不同,将会中断编译器的下一步进程。基本上,它们中断编译并像堆栈跟踪一样在输出流中显示相关信息,这对调试很有帮助。因此,如果程序无法继续执行就应该抛出错误。如有可能,尝试解决这个问题并以显示提醒的方式代替。
举个例子,假设你创建了一个map-get()
函数来从特定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);
}
和Sass一样受欢迎的CSS预处理器的优秀之处就在于,它提供了包括框架、插件、库和工具在内的整套开发环境。Sass诞生8年以来,其本身的特性和everything that can be written in Sass has been written in Sass一文中的观点越来越相近。
不过,我的建议是最小程度的依赖于各种工具。管理依赖可能会是你特别不想面对的事情。此外,在Sass中很少需要外部依赖。
Compass是Sass中最主要的框架。其开发者Chris Eppstein,是Sass的两位核心开发者之一。如果你想听一下我的看法,我想说这个框架一直很流行。
不过,我已经不再使用Compass了,主要原因是它很大程度上拖慢了Sass。Ruby Sass本身就比较慢,所以在此之上增加更多功能并无益处。
实际上,我们通常只使用了框架本身的一点点功能,而完整的Compass是庞大的。混合宏的跨浏览器兼容功能也只是冰山一角。数学函数、图像辅助、幽灵图……使用这个优秀的工具有太多的好处了。
不幸的是,这就是所有的语法糖而且没有一个是杀手级的特性。精灵图生成器虽然非常优秀,但也会报出一两个错误。不过Grunticon 和Grumpicon就运行的很好,而且它们还有可以被插入到构建过程的优势。
虽然我不建议使用Compass,但我也不会禁止使用它,特别是当它不兼容LibSass的时候(即使它正朝这个方向努力)。如果你感觉使用起来还不错,这当然可以,但是我认为最终你也不会从中收获更多。
Ruby Sass目前正着手进行一些很棒的优化,目标是通过运用诸多函数和混合宏实现具有深度逻辑的样式。它们应该显著改善性能,而这往往是Compass和其他框架拖慢Sass的原因。
随着响应式网页设计地遍地开花,栅格系统布局已经成为了一种必然选择。为了固定大小并使设计风格统一,我们通常使用网格来给元素布局。为了避免反复地布局工作,一些非凡的想法认为应该使它们保持可复用性。
还是长话短说吧:我并非栅格系统的拥趸。当然我确实看到了它的潜力,但大多的是矫枉过正,而且主要是被设计师用来绘制红栏白底的原型。你还记得上一次有thank-God-I-have-this-tool-to-build-this-2-5-3.1-π-grid如此赞叹的时间吗?那就对了,从来没有过。因为在多数情况下,你只是想使用12列栅格布局,毫不奇特。
如果你正在项目中使用类似Bootstrap和Foundation的CSS框架,我建议善用它们来避免额外的依赖,因为此时它们很有可能就包含了一套栅格系统,。
如果你尚未依赖于特定的栅格系统,那么也许会乐意了解这里介绍的两个由Sass支持的栅格引擎:Susy和Singularity。它们都可以满足你的需求,所以只需从中挑选喜欢的一个来用即可并且可以放心即使是你的苛刻需求—哪怕是最多变的—也可以被实现。
或者你可以处理地更轻松些,就像使用 CSSWizardry Grids的感觉。总而言之,任何选择都不会对你的代码风格有过多影响,所以这一点上一切取决于你。
审查代码是非常重要的事情。通常来说,遵从一份样式指南的规范可以帮助减少代码质量上的问题,但是没有人的工作是无懈可击的,何况总有些地方需要改善。所以,可以认为,审查代码和注释文档一样重要。
SCSS-lint是一个帮你保持SCSS文件简洁而又具有可读性的工具。它是完全可定制化的,并且非常易于和其他工具集成。
幸运的是,本文档的描述非常类似于SCSS-lint的使用建议。为了根据Sass样式指南配置SCSS-lint,建议如下配置:
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: tru
UrlFormat:
enabled: false
UrlQuotes:
enabled: true
VendorPrefixes:
enabled: true
identifier_list: base
include: []
exclude: []
ZeroUnit:
enabled: true
如果你想将SCSS-lint插入到Grunt构建过程中,那么Grunt插件grunt-scss-lint一定会对你有所帮助。此外,如果你在寻找一个运行SCSS-lint的简洁工具,那么Thoughtbot (Bourbon, Neat...)正在开发的Hound也会对你有所帮助。
总而言之,希望做到如下规范:
@extend
;@while
循环;本文根据Hugo Giraudel的《Sass Guidelines》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:Sass Guidelines。
出处:http://www.w3cplus.com/preprocessor/sass-guidelin-part-7.html