Sass 的一些酷炫用法 - 第一部分
我使用 Sass 已经两年多了,现在我成了它的忠实粉丝。虽然我们之前用 CSS 写代码也还不错,但它始终无法提供 Sass 所具备的那种灵活性,比如随着应用规模的不断扩大,管理样式表的复杂性就变得轻而易举。好了,我的经验就说到这里吧,今天我们还有很多精彩的内容要讲!
什么是Sass?
它是一款 CSS 预处理器,如果你开始在谷歌上搜索,就会得到这个结果,这没错,但请记住这一点,因为它还有更多内容。
Sass 允许你使用变量、嵌套、继承等特性,而且语法与 CSS 完全兼容。当你想要减少重复代码,让庞大的样式表更加井然有序时,这真的非常方便。
重要提示:它不是 CSS 的替代品,而是一个解释器/转译器,最终会输出 CSS。
你肯定在想,那么 Sass 和 Scss 有什么区别呢?
Sass 本身分为两种语法/文件类型:.sass& .scss。
Sass(旧语法)并未被大众广泛接受。主要原因是它使用缩进而非花括号,并且不需要分号,这增加了编写代码时出现人为错误的概率。
Scss (新语法)之所以被广泛接受,是因为它与我们编写 CSS 的方式非常相似。使用 Scss 可谓双赢,我们既可以像编写 CSS 一样编写样式表,又能享受到 Sass 的优势。太棒了!
从现在开始,本文将假定您了解 Sass,并精通其基础知识和实际用法;如果您不了解,请参考此处了解更多信息。
事不宜迟,让我们来看看编写 SCSS 时可以使用的一些实用工具:
使用变量作为选择器
我们可以定义自己的选择器,并在样式表中使用它。
例如:
// Define your base selector.
$header-base-class: '.header';
#{$header-base-class} {
background: white;
}
// Compiles to css
.header {
background: white;
}
或者,这在很多情况下都非常有用!比如……媒体查询?我们来仔细看看:
$small-only: 640px (Define somewhere else like maybe in _settings.scss)
@media (max-width: #{$small-only}) {
// Here do your thing, the styles will only be applied to viewport < $small-only breakpoint.
}
很简单吧?😃
现在,您无需在每个媒体查询中定义硬编码值。只需像本例中一样在一个地方进行更改_settings.scss,即可在所有地方获得相同的结果。
使用前缀进行父级引用
您应该熟悉&我们常用的 & 符号前缀。这种语法通常允许您嵌套嵌套的选择器修饰符,并引用其父级。
例如——您希望在鼠标悬停时更改 div 的背景颜色。
.highlight {
&:hover {
color: red;
}
}
// Compiles to css
.highlight:hover {
color: red;
}
但它&也可以用作前缀来引用其父级。
假设你有一个基础选择器,并且只想在存在某个特定类选择器时才应用特定样式,通常我们会这样做:
$base-item-selector: '.base-selector';
#{$base-item-selector} {
&--conditional-selector {
#{$base-item-selector} {
&__details {
display: none;
}
}
}
}
// Compiles to css
.base-selector--conditional-selector .base-selector__details {
display: none;
}
使用 Parent 引用前缀,我们可以将其修改为:
#{$base-item-selector} {
&--conditional-selector & { // See the usage of ampersand here
&__details {
display: none;
}
}
}
// This will also compiles to similar css.
.base-selector--conditional-selector .base-selector__details {
display: none;
}
不错吧?省去了一层深度,看起来更整齐了。
将变量定义为默认值
使用 Sass,我们可以借助!default标志位来设置变量的优先级和作用域。
将其放在!default声明的末尾实际上会执行以下操作:
- 如果你将一个变量定义为
null,它将被视为未赋值,并将被赋值为!default。 - 如果变量已被赋值,则不会重新赋值。
感到困惑?好的,我们来讨论一下。
例如,如果我们把文本颜色定义为红色,正常流程如下:
// _my-component.scss
$text-color: red !default;
a {
color: $text-color;
}
// Compiles to css
a {
color: red;
}
目前为止都明白了吧?好的,我们继续。现在,你可以在导入组件样式时覆盖颜色了。
$text-color: blue;
@import ‘my-component’;
// Compiles to css
a {
color: blue;
}
这意味着该!default标志只有在值尚未被预先赋值/实例化时才会生效,否则将被覆盖。
这是编写模块化 CSS 的一种重要方法。因此,为了提高可访问性,我们通常会将大部分变量定义在一个文件中。!default当与 mixin 和插件类型的代码一起使用时,该标志非常有用。
这里还有另一个有趣的例子。
Mixins 和自定义函数
Mixin 和函数都属于同一类,因为它们都接受变量作为参数,但它们的职责略有不同。让我们逐一讨论。
Mixin: Mixin 可以接受参数并执行所需的计算,但 mixin 的输出将是一个 CSS 规则。
当用 . 调用时,它将展开自身@include。
例如,假设我们需要在应用程序中定义不同的字体样式。那么创建 mixin 就更有意义了:
// _my-typography-rules.scss
@mixin my-typography-small {
font-size: .75rem;
font-weight: 300;
letter-spacing: .01em;
line-height: 1;
}
// _my-component.scss
#{$base-selector} {
@include my-typography-small;
}
// Compiles to
.base-selector {
font-size: .75rem;
font-weight: 300;
letter-spacing: .01em;
line-height: 1;
}
函数:它与 mixin 非常相似,但输出时它只返回一个值。就像其他语言中都有自定义函数一样,在 Sass 中使用自定义函数对你的应用程序非常有益。
自定义函数的返回值可以是任何数据类型,例如数字、字符串、布尔值等。
这里最好的例子之一就是根据基本单位尺寸计算雷姆数。我们在应用程序中大量使用了这种方法,而且这种方法几乎可以在任何地方使用。非常通用!
假设我们用 rem 单位来控制字体大小,每次使用 rem 单位时,都必须手动计算。太麻烦了!是不是?
我们实际的计算方法rem是用目标值除以目标值size/base size。your result因此,下面的函数将给出我们想要的结果,我们可以在整个应用程序中使用它。
//_utility.scss
/**
* Calculate rems based on a base unit.
*/
@function remCalc($size, $base) {
$remSize: $size / $font-base-size;
@return #{$remSize}rem;
}
// _my-component.scss
a {
font-size: remCalc(20, $font-base-size);
}
我希望现在您明白为什么自定义函数非常有用,因为它们可以帮助我们避免重复计算。SCSS 提供了大量的内置函数,您可以在这里查看。
最好总是先查看内置函数,而不是每次都自己创建函数。
默认参数
既然我们刚刚讲完了 mixin 和自定义函数,现在是时候谈谈默认参数了。它们之间其实有点关联。
Mixins 和自定义函数都支持参数,更棒的是,我们还可以定义默认参数。
例如:
@mixin abc-with-margin($x, $y, $z, $margin: 20px) {
// Do your stuff with x, y, z.
margin: $margin;
}
// _my-component.scss
#{$selector} {
@include abc-with-margin(12, 23, 34);
}
// Compiles to css
.selector {
// Stuff we did with x,y,z.
margin: 20px;
}
我们也可以覆盖默认值。例如
// _my-component.scss
#{$selector} {
@include abc-with-margin(12, 23, 34, 10px);
}
// Compiles to css
.selector {
// Stuff we did with x,y,z.
margin: 10px; // Overridden.
}
扩展你的选择器
使用 SCSS,您可以将选择器的样式合并到 CSS 输出中。由于我们会继承父类或其他属性,这与其他编程语言非常相似,但具体过程却截然不同。同样,其目的是为了重用不同选择器的样式,从而避免重写已在使用的代码。
.menu {
background-color: white;
}
.header-menu {
@extend .menu;
color: black;
}
// Compiles to css
.menu, .header-menu {
background-color: white;
}
.header-menu {
color: black;
}
现在我们可以看到,它.header-menu不仅拥有 `.menu` 的所有属性,.menu还继承了它原有的属性。这是传统的继承方式,对吧?现在,`.menu` 定义的任何内容都会被继承,.header-menu并且也可以轻松地被覆盖。
你肯定在想,为什么我们不能直接用 mixin 就完事了,为什么还要用另一种逻辑?我这就告诉你为什么不行。
如果我们接受混合口味:
@mixin menu {
background-color: white;
font-size: 1rem;
font-weight: bold;
color: grey;
padding: 20px;
}
.header-menu {
@include menu;
color: black;
}
.footer-menu {
@include menu;
color: black;
}
// Compiles to css
.header-menu {
background-color: white;
font-size: 1rem;
font-weight: bold;
color: grey;
padding: 20px;
color: black;
}
.footer-menu {
background-color: white;
font-size: 1rem;
font-weight: bold;
color: grey;
padding: 20px;
color: black;
}
请注意最后一个属性的不同之处,随着菜单类型数量的增加,每种菜单类型都会出现越来越多的重复样式。这个问题可以通过扩展选择器来解决。
另一个优点是它可以与 Foundation、Bootstrap 等 UI 库一起使用。一篇值得一读的文章介绍了我们如何扩展复杂的选择器(链接在此)。
占位符
我们将借助之前的例子,我们创建了一个.menu选择器,以便子选择器可以继承样式。但如果这个选择器根本不存在,或者除了通过其子类之外没有在任何地方使用,那我们最好还是把它删除。
在继续之前,先澄清几点:
.menu被视为一个类别。#menu被视为 id。%menu被视为占位符。
以免我们把它们混淆。
这将产生与之前相同的输出结果。
例如:
%menu {
background-color: white;
}
.header-menu {
@extend %menu;
color: black;
}
.footer-menu {
@extend %menu;
color: gray;
}
// Compiles to css
.header-menu, .footer-menu {
background-color: white;
}
.header-menu {
color: black;
}
.header-menu {
color: gray;
}
唯一的区别在于菜单已从输出中消失,因为它只是一个占位符选择器。这非常有用,因为您使用的元素应该只输出到最终的 CSS 中。更多信息,请点击此处阅读有关占位符的内容。
好了,我们来总结一下。我本来也想在这篇博客里讲讲 Control 指令,但这本身就是一个很大的话题。我们会在下一篇博客里探讨这个问题。敬请期待!
感谢阅读。😃
请访问我的博客查看原文。
文章来源:https://dev.to/lhuria94/cool-things-you-can-do-with-sass---part-1-1m9a