SCSS 权威指南
作者:Supun Kavinda ✏️
最初,前端开发只是编写 HTML、CSS 和 JavaScript。然而,在过去十年左右的时间里,它变得越来越复杂,也越来越有趣。随着该领域的不断发展,掌握最新的前端技术并学习如何更高效地构建网站变得越来越重要。
在本指南中,我们将演示如何使用 SCSS——可以将其视为一种拥有超能力的 CSS 编写方式。我将其分为三个部分:
- SCSS简介
- SCSS 语言语法
- 在实际应用中使用 SCSS
如果您已经了解该语言并且只想学习如何在您的应用程序中使用它,请随意跳到第三部分。
1. SCSS(和 Sass)简介
SCSS(或 Sass)的官方描述是“超强 CSS ”,它提供了一种使用更强大的 CSS 语法为网站编写样式的方法。通常,浏览器无法处理 SCSS 的特性,例如函数、混合宏和嵌套。我们需要将它们转换为常规 CSS 文件才能在浏览器中运行。
SCSS 和 Sass 有什么区别?
这是大多数初学者容易混淆的地方。SCSS 和 Sass 是同一概念的两种语法。它们之间的区别在于 UI。
SCSS | 萨斯 |
代表 Sassy CSS | 代表“Syntactically Awesome Style Sheets” |
类似于 CSS (使用花括号和分号) | 使用严格缩进 (如Python) |
任何有效的 CSS 都是有效的 SCSS | CSS 代码不能用作 SASS |
.scss 扩大 |
.sass 扩大 |
以下是 SCSS 的一个例子:
body {
background-color:#000;
color:#fff;
}
下面是一个 Sass 的例子:
body
background-color:#000;
color:#fff;
选择哪种语言完全取决于你。不用担心——你可以使用该sass-convert
工具轻松地将 SCSS 转换为 Sass,反之亦然。
在本文中,我将主要关注 SCSS,原因有二。
- SCSS 的语法与 CSS 类似。因此,对于已经了解 CSS 的人来说,很容易解释其进步之处。
- 掌握 SCSS 后,只需几分钟即可学习 SASS。(提醒:两者概念相同。)
为什么选择 SCSS?
TL;DR:CSS 不够强大。
CSS 很酷,但还不够酷。SCSS 的创建者们有很多想法,希望能够让开发者的工作更轻松,并决定将它们打造成一门全新的语言。实际上,需要明确的是,Sass 是这门新语言的原始版本;SCSS 是他们后来创建的改进版本。
如何在您的网站中使用 SCSS
遗憾的是,SCSS 的功能尚未被纳入CSS 规范,因此浏览器尚不支持。要在 Web 浏览器中运行 SCSS 代码,必须先将其转换为 CSS。稍后我们将讨论可用于此目的的工具以及如何自动化此过程。
2. SCSS语言语法
在本节中,我假设你已经有一些 CSS 经验。我将逐一介绍 SCSS 的功能,并解释每个功能的语法。
SCSS 规则的结构
SCSS 的结构与 CSS 的结构相同。首先,使用 ID、类或其他CSS 选择器选择一个或多个元素。然后,添加样式。
在此示例中,我们选择具有类的元素button
并添加一些属性。这在 CSS 代码和 SCSS 代码中均有效。需要注意的是,SCSS 支持所有CSS 属性。
.button {
display:inline-block;
font-size:14px;
padding:4px 10px;
}
SCSS 中的注释
SCSS 中允许//
(单行)和(多行)注释。/* */
// this is a single-line comment
/* this is a multi-line comment */
现在让我们回顾一下 SCSS 的基本增强功能。我们将在最后一节讨论如何将 SCSS 编译为 CSS。目前,您可以使用CodePen编写和测试代码。请确保在 CSS 设置中选择 SCSS 作为预处理器。
下面的例子,我会用一个简单的故事:你正在用 SCSS,而你那位超级酷炫的老派程序员爷爷却还在为 CSS 苦苦挣扎。让我们开始吧!
嵌套
您的祖父使用 CSS 将导航栏设计成如下样式:
nav {
background-color:#333;
padding:1em;
}
nav ul {
margin:0;
padding:0;
list-style:none;
}
nav ul li {
display:inline-block;
}
但您可以使用 SCSS 来实现,如下所示:
nav {
background-color:#333;
padding:1em;
ul {
margin:0;
padding:0;
list-style:none;
li {
display:inline-block;
}
}
}
是不是更有条理、更简洁?跟你爷爷比起来,你有两个主要优势:
- 您知道及其子项的所有样式
nav
都在花括号之间,因此您无需在文件或多个文件中查找它们 - 你只需编写更少的代码,因此不会出现重复
但是请记住,嵌套越深,CSS 文件就会变得越大,浏览器需要做更多工作来设置元素的样式。尽量保持选择器尽可能浅。例如,我们可以通过将样式移到li
外层作用域来节省一些字节。
nav {
background-color:#333;
padding:1em;
ul {
margin:0;
padding:0;
list-style:none;
}
li {
display:inline-block;
}
}
对于较大的项目,这可以节省大量带宽。
确保此过程不会产生任何冲突至关重要。例如:
content {
ul {
li {
font-style:italic;
}
}
ol {
li {
font-decoration:underline;
}
}
}
在这种情况下,我们不能将元素的样式带到li
外部范围,因为它们有不同的规则。
底线是:嵌套使代码更清晰、更有条理、更简洁,但要注意不要过度使用它。
&
在嵌套中使用
你爷爷炫耀了一下他的神奇按钮,鼠标悬停在上面时,按钮会变色。他的 CSS 代码如下:
button {
background-color: #535353;
color: #000;
}
button:hover {
background-color: #000;
color: #fff;
}
&
通过使用嵌套字符,您可以更轻松地使用 SCSS 实现相同的效果。
button {
background-color: #535353;
color: #000;
&:hover {
background-color: #000;
color: #fff;
}
}
&
始终指的是上方的选择。以下是一些用例。
.some-class {
&:hover {
/* when hovered */
}
&:focus {
/* when focused */
}
& > button {
/* selector equls to .some-class > button */
}
&-cool {
/*** Notice this! ****/
// selects .some-class-cool elements
}
}
变量
变量用于存储数据。在 SCSS 中,你可以将任何CSS 值(即使带有单位)保存在变量中。变量使用符号 定义$
。
变量声明:
$my-font: Nunito, sans-serif;
$my-font-color: #ffd969;
$content-width: 660px;
变量用法:
body {
font-family: $my-font;
color: $my-font-color;
content {
width: $content-width;
}
}
当 Sass 转换为 CSS 时,所有变量都会被替换为其原始值。SCSS 变量有助于保持网站或 Web 应用中字体、颜色和其他值的一致性。
SCSS 和 CSS 变量之间的区别
SCSS 变量在转换为 CSS 变量时会被替换为值。这些转换在传递给浏览器之前进行,因此浏览器甚至不知道变量的存在,它们只看到值。另一方面,CSS 变量的功能则更加强大。
CSS Tricks概述了 CSS 变量的几个优点:
- 它们级联;您可以在任何选择器内设置变量来设置或覆盖其当前值
- 当变量的值发生变化(例如,媒体查询或其他状态)时,浏览器会根据需要重新绘制
- 您可以在 JavaScript 中访问和操作变量
$my-global-variable: "I'm global";
div {
$my-local-variables: "I'm local";
}
这是否意味着爷爷赢了?并非如此:你可以在 SCSS 样式表中使用 CSS 变量,因为任何有效的 CSS 也是有效的 SCSS。如果你对 CSS 变量感兴趣,可以在这里了解更多信息。
SCSS 变量范围
需要注意以下几点:
- 顶层定义的所有变量都是全局的
- 块中定义的所有变量(即花括号内)都是局部的
- 块可以访问本地和全局变量$my-global-variable: “I'm global”; div { $my-local-variables: “I'm local”; }
更改 SCSS 变量的值
更改变量值的方式与声明变量相同。更改变量值后,后续使用将具有新值,而先前使用的值保持不变。
$color: #fefefe;
.content {
background-color: $color;
}
$color: #939393;
.footer {
background-color: $color;
}
这里,.content
将具有背景颜色#fefefe
,而.footer
将具有#939393
。除非我们添加修饰符,否则全局变量不会改变!global
。
$color: #111;
.content {
$color: #222; // this is a new local variable
background-color: $color; # 222
}
.footer {
$color: #333 !global; // changes the global variable
}
Mixins
让我们再次超越您祖父的 CSS,这次使用 mixins。
mixin 是一组可重复使用的 CSS 声明。其语法类似于JavaScript 中的函数function
。使用指令代替关键字@mixin
。您还可以使用参数。通过语句调用 mixin @include
。
下面展示了如何使用 mixins 将元素定位到绝对中心:
@mixin absolute-center() {
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
}
.element-1 {
@include absolute-center();
}
.element-2 {
@include absolute-center();
color:blue;
}
首先,我们定义了absolute-center
mixin。然后,我们在多个块中使用它。
带参数的混合
下面是如何在 mixins 中使用参数的示例。
@mixin square($size) {
width:$size;
height:$size;
}
div {
@include square(60px);
background-color:#000;
}
带有可选参数的 Mixins
可选参数可以按照我们声明 SCSS 变量的方式定义。
@mixin square($width: 40px) {
width:$size;
height:$size;
}
与内容块混合
我们可以将 CSS 规则发送给 mixin,而不是参数。这些规则可以在 mixin 中使用@content
。
@mixin hover-not-disabled {
&:not([disabled]):hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover-not-disabled {
border-color: blue;
}
}
这种方法可以让我们减少部分的重复&:not([disabled]):hover
。
导入 SCSS(@import
和@use
)
在创建大型应用程序时,代码分块是一项重要的实践。你爷爷可以通过创建多个 CSS 文件并将它们全部添加到 HTML 文档来实现这一点。
<link rel="stylesheet" href="/path/to/css/1"></link>
<link rel="stylesheet" href="/path/to/css/2"></link>
<link rel="stylesheet" href="/path/to/css/3"></link>
<link rel="stylesheet" href="/path/to/css/4"></link>
<link rel="stylesheet" href="/path/to/css/5"></link>
爷爷的流程很繁琐,需要浏览器发出很多 HTTP 请求,这可能会降低他的网站速度。
SCSS 更好一些,因为它允许你在将代码发送到浏览器之前合并分块文件。这样,你只需要链接一个 CSS 文件(通常命名为something.bundle.css
)。
@import
下面的示例演示了如何使用分块文件并将其导入到一个父文件中@import
。
normalize.scss
:
body {
padding:0;
margin:0;
}
body, html {
width:100%;
min-height:100%;
}
styles.scss
:
@import 'normalize';
content {
max-width:660px;
// and more styles
}
假设normalize.scss
和都styles.scss
在同一个文件夹中,我们可以将一个导入到另一个,如上所示。
使用 时@import
,所有变量、混合宏等都将变为全局可访问的,这在文件结构复杂且使用库的情况下会造成问题。因此,官方现在已不建议使用@import
。
解决方案是@use
。
@use
的基本用法@use
与 相同@import
。
styles.scss
:
@use 'normalize';
// other styles
导入的文件@use
称为模块。要使用这些模块的混合宏或变量,我们必须使用命名空间来调用它们。默认情况下,命名空间就是文件名(不带扩展名)。
src/_colors.scss
:
$accent-color: #535353;
@mixin dark-background {
background-color:#000;
color:#fff;
}
styles.scss
:
@use 'src/colors';
body {
color: colors.$accent-color;
}
.dark-region {
@include colors.dark-background;
}
您还可以使用自定义命名空间as
。
@use 'src/colors' as c;
body {
color: c.$accent-color;
}
当_
SCSS 文件的文件名前面加上 时,解析器会知道这是一个部分文件,并且仅用于导入。导入时,该_
部分是可选的。请注意,我们以前src/colors
导入的是src/_colors.scss
。
算术运算符
无需 Grandpa 的 CSS 函数,你也能在 SCSS 中进行一些数学运算calc()
。你可以使用+,-,/,*,%
、直接值和变量进行计算。
$content-width: 600px;
content {
width:$content-width;
}
.inner-content {
width: $content-width - 60px; // substraction
}
.outer-content {
width: $content-width + 60px; // addition
}
流量控制规则
流量控制规则有四种类型:@if
/ @else
、@each
、@for
和@while
。
@if
and @else
– 类似于JavaScript 中的if
and 。else
// ex: using in mixins
@mixin theme($is-dark: false) {
@if $is-dark {
// styles for dark
}
@else {
// styles for light
}
}
@each
与 JavaScript类似for of
。
// creating automated
$sizes: 40px, 50px, 80px;
@each $size in $sizes {
.icon-#{$size} {
font-size: $size;
height: $size;
width: $size;
}
}
注意:该#{$size}
符号用于使用变量创建动态属性名称和选择器。这称为插值。
@for
类似于for
JavaScript 中的循环。
@for $i from 1 through 4 {
.bubble-#{$i} {
transition-delay: .3 * $i;
}
}
@while
(不常用)类似于while
JavaScript 中的循环。
到目前为止,你已经了解了 SCSS 的定义和历史、它的工作原理、SCSS 和 Sass 的区别以及 SCSS 语言的语法。现在是时候实际创建一些东西来证明你的 SCSS 比你爷爷的 CSS 更好了。
3. 在实际应用中使用 SCSS
在本部分中,我们将演示两种将 Sass 编译为 CSS 的方法。
在开始之前,我们必须安装sass
命令行,这是预处理 CSS 最简单的工具。如果你使用 npm,请使用以下代码。
npm i -g sass
查看安装指南,了解安装命令行的其他方法sass
。
使用sass
命令行,您可以将.scss
和.sass
文件解析为.css
。它会自动根据扩展名检测 SCSS 和 Sass 文件并使用正确的解析器。
sass source.scss destination.css
使用 SCSS 设计一个简单的博客页面
为了演示sass
命令行并回顾上面概述的概念,让我们设计一个包含一个组件的简单博客:内容(我们将跳过页眉和页脚以使其更清晰)。
首先,在本地机器上创建一个文件夹(我将其命名为my-blog
)并导航到那里。
cd /path/to/my-blog
然后,再创建两个文件夹。
mkdir source build
我们将把.scss
文件放在文件夹中source
,并将预处理的.css
文件放在build
文件夹中。
index.html
接下来,在根目录中创建一个文件,在您最喜欢的文本编辑器中打开它,并添加一些 HTML 代码。
<!-- index.html -->
<html>
<head>
<link rel="stylesheet" href="build/index.css">
</head>
<body>
<content>
<content>
Blog content goes here
</content>
</content>
</body>
</html>
现在是时候创建新的 SCSS 文件了。我们的主文件是source/index.scss
,它将包含其他文件。
要开始编写 SCSS,我们需要设置一个source/index.scss
用于build/index.css
实时编译的观察器。--watch
在sass
命令行中使用 选项。
sass --watch source/index.scss build/index.css
最后,创建分块的 SCSS 文件。
// index.scss
@use 'normalize';
@use 'Content';
@use 'Footer';
body {
background-color:#fafafa;
font-family: Segoe UI, sans-serif;
}
// _normalize.scss
body, html {
margin:0;
padding:0;
}
* {
box-sizing:border-box;
}
content {
display:block;
}
// _colors.scss
$content-box: #fff;
$footer: #222;
$footer-font: #fff;
为了便于识别,我按照以下Content.scss
格式命名组件的样式文件。
// Content.scss
@use 'colors' as colors;
body > content {
padding:40px;
margin:auto;
width:660px;
max-width:100%;
& > content {
background-color: colors.$content-box;
min-height:600px; // to look cool
border-radius:20px;
box-shadow:10px 10px 40px rgba(0,0,0,0.06);
padding:40px;
}
}
现在我们已经创建了一个基本的博客页面,让我们添加一些媒体查询。
添加媒体查询
假设我们需要<content>
在移动设备(<600px
)中移除父元素的 padding。我们可以通过两种方式来实现。
传统的 CSS 方式是全局添加媒体查询。
@media screen and (max-width:600px) {
body > content {
padding:0;
}
}
SCSS 的方式是在选择器内添加媒体查询。
body > content {
@media screen and (max-width:600px) {
padding:0;
}
}
两种方法都有效;您可以根据自己的喜好选择。有些开发者会将所有媒体查询保存在一个文件中(例如Mobile.scss
)。
带有 webpack 或 Gulp 的 SCSS
虽然sass
命令行简单易用,但如果您使用webpack或Gulp等打包工具,则可以在打包时使用插件将 SCSS 解析为 CSS。请查看以下各打包工具的指南。打包工具的优势之一是您可以同时进行解析、自动添加前缀和压缩。
结论
现在您应该已经了解了 SCSS 的基础知识以及它在实际中的应用。我们已经讨论了 SCSS 最常用的功能,但我建议您查看SASS 文档以进行更深入的了解。熟悉 SCSS 之后,您可能需要了解SCSS 的内置模块,它们可以让您在创建复杂的应用程序时更加轻松。
至于你那超酷的开发人员爷爷 — — 告诉他与时俱进,转向 SCSS。
您的前端是否占用了用户的 CPU?
随着 Web 前端日益复杂,资源占用大的功能对浏览器的要求也越来越高。如果您有兴趣监控和跟踪生产环境中所有用户的客户端 CPU 使用率、内存使用率等数据,不妨尝试 LogRocket。
LogRocket就像 Web 应用的 DVR,记录 Web 应用或网站中发生的一切。您无需猜测问题发生的原因,而是可以汇总和报告关键的前端性能指标、重放用户会话以及应用程序状态、记录网络请求并自动显示所有错误。
实现 Web 应用程序调试方式的现代化 —开始免费监控。
SCSS 权威指南一文最先出现在LogRocket 博客上。
文章来源:https://dev.to/bnevilleoneill/the-definitive-guide-to-scss-1ign