学习Sass(Scss)的一次经历

本文介绍了Sass,一种强大的CSS预处理器,提供了变量、嵌套规则、混合指令等功能,提高了CSS的可维护性和复用性。通过学习Sass,可以更好地理解和编写CSS代码。在VS Code中安装Live SassCompiler插件,可以实现Sass到CSS的实时转换,提升开发效率。
摘要由CSDN通过智能技术生成

成熟、稳定、强大的专业级CSS扩展语言!

在中国广告法里不让带“最”,“第一”这样的字眼,标题我就把最去掉了,但这句话确实让人震撼,它这么牛逼吗?
在这里插入图片描述
那我们走近她,揭开她神秘的面纱,一窥她的芳容。

这是文章的一条旁支

先来看一道题:
如何选中下面flex布局的最后一行

https://jsbin.com/buwicapaji/edit?html,output

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <style>
    *{
      box-sizing: border-box;
    }
    #app{
      width:400px;
      height:400px;
      display:flex;
      flex-wrap:wrap;
    }
    #app>div{
      width:25%;
      border:1px solid;
    }
  </style>
</head>
<body>
<div id="app">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

有朋友给出了答案:

https://codepen.io/yuriuh/pen/qBWGbgO

<div id="app">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
------------------------------
  *{
      box-sizing: border-box;
    }
    #app{
      width:400px;
      height:400px;
      display:flex;
      flex-wrap:wrap;
    }
    #app>div{
      width:25%;
      border:1px solid;
    }
    .item:nth-child(4n+1):nth-last-child(-n+4),
    .item:nth-child(4n+1):nth-last-child(-n+4) ~ .item{
      background: pink;
    }

我认为他用的scss解决的, 你看懂了吗?反正我是没看懂,因为我没学习过scss语言。
我用JS来试着解决这个问题

 <script>
     var item = document.getElementsByClassName("item");
     // var num = item.length % 4; // 1 2 3 0
     var num = item.length % 4 === 0 ? 4 : item.length % 4;
     console.log(num);
     // item[item.length - 1].style.backgroundColor = "pink";
     // item[item.length - 2].style.backgroundColor = "pink";
     // item[item.length - 3].style.backgroundColor = "pink";
     // item[item.length - 4].style.backgroundColor = "pink";
     for (var i = 0; i < num; i++) {
         item[item.length - 1 - i].style.backgroundColor = "pink"
     }
 </script>

思路就是,
整个子元素,个数能被4整除,最后一排有4个,如果不能整除,余数为1则最后一排有一个,余数为2,则最后一排有两个元素,余数为3则最后一排有3个。注释掉的代码是思考的过程和整合为for循环前的尝试。
但我还是不懂他的做法,我觉得他可能用的是sass,我就想着学习一下sass,就有了这篇博文。(实际上这种写法不是sass,因为sass需要编译后浏览器才能识别,而这段代码贴进编辑器,让浏览器运行,直接就显示了,没有编译过程。这个后面再说,先学习sass)

转回正途

什么是CSS预处理器
  • CSS预处理器是一种专门的编程语言,用来为CSS增加一些编程特性,不需要考虑浏览器的兼容性问题,因为CSS预处理器最终编译和输出的仍是标准的CSS样式,可以在CSS预处理器中:使用变量、简单逻辑判断、函数等基本编程技巧。
  • CSS预处理器的主要目标:
    1. 为CSS提供样式复用机制
    2. 减少CSS冗余代码
    3. 提高CSS代码的可维护性
CSS预处理器工作流程
sass
Compiler APP or Script
css
web browser
主要流行的CSS预处理器

Sass、Less、Stylus

  • Sass :https://sass-lang.com/Sass
    2007年诞生,最早也是最成熟的CSS预处理器,有两种语法,分别以*.sass*.scss为扩展名。
  • Less : https://lesscss.org/Less
    2009年出现,受Sass的影响非常大,以*.less 为扩展名
  • Stylus : https://stylus-lang.com/
    2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,以*.styl 为扩展名
CSS预处理器的使用
  1. 集成在前端开发工具中直接使用,如:VS Code、 WebStorm 等
  2. 集成在项目构建工具中,在项目编译(打包)时进行自动转换,如:grunt、gulp、webpack等。
sass
开发工具
Less
Stylus
构建工具
在VS Code 中安装Sass插件

项目开发时,实时进行Sass到CSS的转换

  • 在VS Code中安装Live SassCompiler 插件
  • 在VS Code 控制台打开Live sass watching 模式
  • 在VS Code配置中修改CSS输出目录
"liveSassCompile.setting.formats" :[
{ "format" : "expanded",
"extensionName": ".css",
"savePath" : " ../../"} ]
Sass 核心语法应用
  • 导入
  • 变量
  • 嵌套
  • 混入
  • 继承
导入
  1. @import
    Sass 拓展了 @import 的功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。

Sass 在当前地址,或 Rack, Rails, Merb 的 Sass 文件地址寻找 Sass 文件,如果需要设定其他地址,可以用 :load_paths 选项,或者在命令行中输入 --load-path 命令。

通常,@import 寻找 Sass 文件并将其导入,但在以下情况下,@import 仅作为普通的 CSS 语句,不会导入任何 Sass 文件。

  • 文件拓展名是 .css;
  • 文件名以 http:// 开头;
  • 文件名是 url();
  • @import 包含 media queries。

如果不在上述情况内,文件的拓展名是 .scss 或 .sass,则导入成功。没有指定拓展名,Sass 将会试着寻找文件名相同,拓展名为 .scss 或 .sass 的文件并将其导入。

@import "foo.scss";
//或
@import "foo";

都会导入文件 foo.scss,但是

@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);
// 编译为
@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);

Sass 允许同时导入多个文件,例如同时导入 rounded-corners 与 text-shadow 两个文件:
@import "rounded-corners", "text-shadow";
导入文件也可以使用 #{ } 插值语句,但不是通过变量动态导入 Sass 文件,只能作用于 CSS 的 url() 导入方式:

$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=\#{$family}");
编译为
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");

1.1. 分音 (Partials)
如果需要导入 SCSS 或者 Sass 文件,但又不希望将其编译为 CSS,只需要在文件名前添加下划线,这样会告诉 Sass 不要编译这些文件,但导入语句中却不需要添加下划线。

例如,将文件命名为_colors.scss,便不会编译 _colours.css文件。
@import "colors";
上面的例子,导入的其实是 _colors.scss 文件

注意,不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。

1.2. 嵌套 @import
大多数情况下,一般在文件的最外层(不在嵌套规则内)使用 @import,其实,也可以将 @import 嵌套进 CSS 样式或者 @media 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中。

假设 example.scss 文件包含以下样式:

.example {
  color: red;
}
// 然后导入到 #main 样式内

#main {
  @import "example";
}
//将会被编译为

#main .example {
  color: red;
}
注释 /* / 与 // (Comments: / */ and //)

Sass 支持标准的 CSS 多行注释 /* */,以及单行注释 //,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会,例如:

/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body { color: black; }

// These comments are only one line long each.
// They won't appear in the CSS output,
// since they use the single-line comment syntax.
a { color: green; }

编译为

/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body {
  color: black; }

a {
  color: green; }

将 ! 作为多行注释的第一个字符表示在压缩输出模式下保留这条注释并输出到 CSS 文件中,通常用于添加版权信息。

插值语句 (interpolation) 也可写进多行注释中输出变量值:

$version: "1.2.3";
/* This CSS is generated by My Snazzy Framework version #{$version}. */

编译为

/* This CSS is generated by My Snazzy Framework version 1.2.3. */
嵌套规则(Nested Rules)
  1. Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,例如:
#main p {
  color: #00ff00;
  width: 97%;

  .redbox {
    background-color: #ff0000;
    color: #000000;
  }
}

编译为

#main p {
  color: #00ff00;
  width: 97%; }
  #main p .redbox {
    background-color: #ff0000;
    color: #000000; }

嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理:

#main {
  width: 97%;

  p, div {
    font-size: 2em;
    a { font-weight: bold; }
  }

  pre { font-size: 3em; }
}

编译为

#main {
  width: 97%; }
  #main p, #main div {
    font-size: 2em; }
    #main p a, #main div a {
      font-weight: bold; }
  #main pre {
    font-size: 3em; }
  1. 父选择器 & (Referencing Parent Selectors: &)
    在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,或者当 body 元素有某个 classname 时,可以用 & 代表嵌套规则外层的父选择器。
a {
  font-weight: bold;
  text-decoration: none;
  &:hover { text-decoration: underline; }
  body.firefox & { font-weight: normal; }
}

编译为

a {
  font-weight: bold;
  text-decoration: none; }
  a:hover {
    text-decoration: underline; }
  body.firefox a {
    font-weight: normal; }

编译后的 CSS 文件中 & 将被替换成嵌套外层的父选择器,如果含有多层嵌套,最外层的父选择器会一层一层向下传递:

#main {
  color: black;
  a {
    font-weight: bold;
    &:hover { color: red; }
  }
}

编译为

#main {
  color: black; }
  #main a {
    font-weight: bold; }
    #main a:hover {
      color: red; }

& 必须作为选择器的第一个字符,其后可以跟随后缀生成复合的选择器,例如

#main {
  color: black;
  &-sidebar { border: 1px solid; }
}

编译为

#main {
  color: black; }
  #main-sidebar {
    border: 1px solid; }

当父选择器含有不合适的后缀时,Sass 将会报错。
3. 属性嵌套(Nested Properties)
有些 CSS 属性遵循相同的命名空间 (namespace),比如 font-family, font-size, font-weight 都以 font 作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中,例如:

.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}

编译为

.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; }

命名空间也可以包含自己的属性值,例如:

.funky {
font: 20px/24px {
  family: fantasy;
  weight: bold;
}
}

编译为

.funky {
  font: 20px/24px;
    font-family: fantasy;
    font-weight: bold; }
sass编译后
.funky { font: 20px/24px { family: fantasy; weight: bold; } } .funky { font: 20px/24px; font-family: fantasy; font-weight: bold; }
变量 $ (Variables: $)
  1. SassScript 最普遍的用法就是变量,变量以美元符号开头,赋值方法与 CSS 属性的写法一样,直接使用即调用变量:
$width: 5em;
#main {
  width: $width;
}
  1. 插值语句 #{} (Interpolation: #{})
    如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中。
 $side : left;

  .rounded {
    border-#{$side}-radius: 5px;
  }

#{} 插值语句也可以在属性值中插入 SassScript,大多数情况下,这样可能还不如使用变量方便,但是使用 #{} 可以避免 Sass 运行运算表达式,直接编译 CSS。

p {
  $font-size: 12px;
  $line-height: 30px;
  font: #{$font-size}/#{$line-height};
}
//编译为
p {
  font: 12px/30px; }
混合指令 (Mixin Directives)

混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left。混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。

  1. 定义混合指令 @mixin (Defining a Mixin: @mixin)
    混合指令的用法是在 @mixin 后添加名称与样式,比如名为 large-text 的混合通过下面的代码定义:
@mixin large-text {
  font: {
    family: Arial;
    size: 20px;
    weight: bold;
  }
  color: #ff0000;
}

混合也需要包含选择器和属性,甚至可以用 & 引用父选择器:

@mixin clearfix {
  display: inline-block;
  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  * html & { height: 1px }
}
  1. 引用混合样式 @include (Including a Mixin: @include)
    使用 @include 指令引用混合样式,格式是在其后添加混合名称,以及需要的参数(可选):
.page-title {
  @include large-text;
  padding: 4px;
  margin-top: 10px;
}
//编译为
.page-title {
  font-family: Arial;
  font-size: 20px;
  font-weight: bold;
  color: #ff0000;
  padding: 4px;
  margin-top: 10px; }

也可以在最外层引用混合样式,不会直接定义属性,也不可以使用父选择器。

@mixin silly-links {
  a {
    color: blue;
    background-color: red;
  }
}
@include silly-links;
//编译为
a {
  color: blue;
  background-color: red; }
  

混合样式中也可以包含其他混合样式,比如

@mixin compound {
  @include highlighted-background;
  @include header-text;
}
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }

混合样式中应该只定义后代选择器,这样可以安全的导入到文件的任何位置。

继承
  • 使用 @extend 可以告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。
  • 继承复杂的选择器 (Extending Complex Selectors),Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 .special.cool,a:hover 或者 a.user[href^=“http://”] 等
  • (Multiple Extends)同一个选择器可以继承多个选择器,它所包含的属性将继承所有被继承的选择器。多重继承可以使用逗号分隔选择器名,比如 @extend .error, .attention; 与 @extend .error; @extend.attention 有相同的效果。
  • (Chaining Extends) 链式继承
    当一个选择器延伸给第二个后,可以继续将第二个选择器延伸给第三个

实际上学习Sass时,上面一再提到编译为,实际上我们学习的就是反过来看,这样的代码用Sass是怎么写的。

Sass 与 SCSS 是什么关系?
  • Sass, 一种缩进语法
  • SCSS, 一种 CSS-like 语法

2010年5月,官方推出了一个全新的语法,被叫做 SCSS,意思是 Sassy CSS。这个语法带来了对 CSS 友好的语法,试图弥合 Sass 和 CSS 之间的鸿沟。
SCSS 和 Sass 相比更加贴近 CSS 语法。也就是说,Sass 维护者做了大量的工作,把缩进语法中的!和=换成了 SCSS 中的 $ 和 :。

  • 对于初学者,SCSS 是完全和 CSS 兼容的,这意味着几乎为零的学习曲线。SCSS语法即是:它只是加了一些功能的 CSS。当你和没经验的开发者一起工作时这很重要:他们可以很快开始编码而不需要首先去学习Sass。

  • 此外,SCSS 还是 易于阅读 的,因为它是有语义的,而不是用符号表示。当你读到 @mixin,你就会知道这是一个 mixin 声明;当你看到 @include ,你就是在引用一个 mixin。他并没有用任何缩写,当你大声读出来时所有的都很明了。

  • 还有,现在几乎所有 Sass 的工具,插件和 demo 都是基于 SCSS语法来开发的。随着时间过去,SCSS 会变成大家首选的选择。比如,你现在很难找到一个 Sass 缩进语法的高亮插件,通常都只有 SCSS 的可以用。

要想熟练运用,还要多练习,多运用,其他细节点查看官方文档。

现在再回到那个问题

  • nth-child(-n+3)
    这个表示选择列表中的标签从0到3,即小于3的标签。
  • :nth-last-child(-n+3)
    Represents the last three elements among a group of siblings.
  • css中“~”是:
    为所有相同的父元素中位于 p 元素之后的所有 ul 元素设置背景:
    p~ul{  background:#ff0000;}
  • p~ul 选择前面有 <p>元素的每个 <ul>元素。
    定义和用法
      p~ul选择器 p之后出现的所有ul。
      两种元素必须拥有相同的父元素,但是 ul不必直接紧随 p

这样就明了了,他是怎么做的。

 .item:nth-child(4n+1):nth-last-child(-n+4),
    .item:nth-child(4n+1):nth-last-child(-n+4) ~ .item{
      background: pink;
    }

.item:nth-child(4n+1) 必须在行首和所有元素中最后4个 :nth-last-child(-n+4)两个条件共同锁定了最后一行,第一个元素;再选上这个元素后面的元素 ~;最后一行元素被选中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值