发布于 2026-01-06 1 阅读
0

Sass 的一些酷炫用法 - 第一部分

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;
}
Enter fullscreen mode Exit fullscreen mode

或者,这在很多情况下都非常有用!比如……媒体查询?我们来仔细看看:

$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.
}
Enter fullscreen mode Exit fullscreen mode

很简单吧?😃

现在,您无需在每个媒体查询中定义硬编码值。只需像本例中一样在一个地方进行更改_settings.scss,即可在所有地方获得相同的结果。

使用前缀进行父级引用

您应该熟悉&我们常用的 & 符号前缀。这种语法通常允许您嵌套嵌套的选择器修饰符,并引用其父级。

例如——您希望在鼠标悬停时更改 div 的背景颜色。

.highlight {
  &:hover {
    color: red;
  }
}

// Compiles to css
.highlight:hover {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

但它&也可以用作前缀来引用其父级。

假设你有一个基础选择器,并且只想在存在某个特定类选择器时才应用特定样式,通常我们会这样做:

$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;
}
Enter fullscreen mode Exit fullscreen mode

使用 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;
}
Enter fullscreen mode Exit fullscreen mode

不错吧?省去了一层深度,看起来更整齐了。

将变量定义为默认值

使用 Sass,我们可以借助!default标志位来设置变量的优先级和作用域。
将其放在!default声明的末尾实际上会执行以下操作:

  • 如果你将一个变量定义为null,它将被视为未赋值,并将被赋值为!default
  • 如果变量已被赋值,则不会重新赋值。

感到困惑?好的,我们来讨论一下。

例如,如果我们把文本颜色定义为红色,正常流程如下:

// _my-component.scss
$text-color: red !default;

a {
  color: $text-color;
}

// Compiles to css
a {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

目前为止都明白了吧?好的,我们继续。现在,你可以在导入组件样式时覆盖颜色了。

$text-color: blue;
@import my-component;

// Compiles to css
a {
  color: blue;
}
Enter fullscreen mode Exit fullscreen mode

这意味着该!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;
}
Enter fullscreen mode Exit fullscreen mode

函数:它与 mixin 非常相似,但输出时它只返回一个值。就像其他语言中都有自定义函数一样,在 Sass 中使用自定义函数对你的应用程序非常有益。

自定义函数的返回值可以是任何数据类型,例如数字、字符串、布尔值等。

这里最好的例子之一就是根据基本单位尺寸计算雷姆数。我们在应用程序中大量使用了这种方法,而且这种方法几乎可以在任何地方使用。非常通用!

假设我们用 rem 单位来控制字体大小,每次使用 rem 单位时,都必须手动计算。太麻烦了!是不是?

我们实际的计算方法rem是用目标值除以目标值size/base sizeyour 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);
}
Enter fullscreen mode Exit fullscreen mode

我希望现在您明白为什么自定义函数非常有用,因为它们可以帮助我们避免重复计算。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;
}
Enter fullscreen mode Exit fullscreen mode

我们也可以覆盖默认值。例如

// _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.
}
Enter fullscreen mode Exit fullscreen mode

扩展你的选择器

使用 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;
}
Enter fullscreen mode Exit fullscreen mode

现在我们可以看到,它.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;
}
Enter fullscreen mode Exit fullscreen mode

请注意最后一个属性的不同之处,随着菜单类型数量的增加,每种菜单类型都会出现越来越多的重复样式。这个问题可以通过扩展选择器来解决。

另一个优点是它可以与 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;
}
Enter fullscreen mode Exit fullscreen mode

唯一的区别在于菜单已从输出中消失,因为它只是一个占位符选择器。这非常有用,因为您使用的元素应该只输出到最终的 CSS 中。更多信息,请点击此处阅读有关占位符的内容。

好了,我们来总结一下。我本来也想在这篇博客里讲讲 Control 指令,但这本身就是一个很大的话题。我们会在下一篇博客里探讨这个问题。敬请期待!

感谢阅读。😃

请访问我的博客查看原文

文章来源:https://dev.to/lhuria94/cool-things-you-can-do-with-sass---part-1-1m9a