Sass

介绍

Sass是一种样式表语言,已编译为CSS。它允许您使用变量,嵌套规则,mixins,函数等,以及所有与CSS完全兼容的语法。Sass帮助保持大型样式表的井井有条,并易于在项目内和项目间共享设计。

特色

  • 完全兼容 CSS3
  • 在 CSS 语言基础上添加了扩展功能,比如变量、嵌套 (nesting)、混合 (mixin)
  • 对颜色和其它值进行操作的{Sass::Script::Functions 函数}
  • 函数库控制指令之类的高级功能
  • 良好的格式,可对输出格式进行定制
  • 支持 Firebug

如何使用

最终需要使用的是css文件,编写的scss文件

转换工具 gulp / webpack / ruby工具 / 编辑器插件

选用gulp来处理scss文件

安装 sass 模块

cnpm i gulp-sass -S (推荐)

cnpm i gulp-sass-china -S

配置处理scss文件gulp的任务

gulp.task('scss2css', () => {
    gulp.src('scss/**/*')
        .pipe(concat('main.scss')) // 合并scss文件
        .pipe(sass()) // 转为css文件
        .pipe(gulp.dest('dist/css'))
        .pipe(minifyCss()) // 压缩
        .pipe(rename('main.min.css'))
        .pipe(gulp.dest('dist/css'))
        .pipe(connect.reload())
})

// 在watch中监听
 gulp.watch('scss/**/*', ['scss2css'])
// 在build中构建
gulp.task('build', ['copy-html', 'copy-css', 'copy-js', 'copy-data', 'copy-assets', 'scss2css'], () => {
    console.log('success')
})

语法

Sass 有两种语法。 第一种被称为 SCSS (Sassy CSS),是一个 CSS3 语法的扩充版本,这里使用的就是这种语法,所有符合 CSS3 语法的样式表也都是具有相同语法意义的 SCSS 文件。 另外,SCSS 理解大多数 CSS hacks 以及浏览器专属语法,例如IE 古老的 filter 语法。 这种语种语法的样式表文件需要以 .scss 扩展名。

第二种比较老的语法成为缩排语法(或者就称为 “Sass”), 提供了一种更简洁的 CSS 书写方式。 它不使用花括号,而是通过缩排的方式来表达选择符的嵌套层级,I 而且也不使用分号,而是用换行符来分隔属性。 很多人认为这种格式比 SCSS 更容易阅读,书写也更快速。 缩排语法具有 Sass 的所有特色功能, 虽然有些语法上稍有差异; 这些差异在{file:INDENTED_SYNTAX.md 所排语法参考手册}中都有描述。 使用此种语法的样式表文件需要以 .sass 作为扩展名。

变量

单值变量
变量以美元符号$开头,赋值方法与 CSS 属性的写法一样

// scss
$baseColor: red;
.box {
    background-color: $baseColor;
}

// ==> css
.box {
  background-color: red; }

全局变量,局部变量
变量支持块级作用域,嵌套规则内定义的变量只能在嵌套规则内使用(局部变量),不在嵌套规则内定义的变量则可在任何地方使用(全局变量)。将局部变量转换为全局变量可以添加 !global 声明。

全局变量:任何地方都可使用

$blue:#5fc0cd;
.test{
	background:$blue;
}

局部变量:只能在嵌套规则内使用

.test{
   $blue:#5fc0cd;
   background:$blue;
}

注意:当全局变量遇上局部变量,局部变量覆盖全局变量
全局变量中的颜色为蓝色,局部变量中的颜色为黑色,黑色覆盖蓝色,最后的背景颜色呈现为黑色

scss做四则运算

// scss
$baseColor: red;
html {
    color: $baseColor;
    border: 1px solid $baseColor - 80;
    background-color: $baseColor / 2;
    background: $baseColor + 200;
}

// ==> css
html {
  color: red;
  border: 1px solid #af0000;
  background-color: maroon;
  background: #ffc8c8; }

多值变量

多值变量使用 nth(变量名, 索引值) 索引值起始值为1 — 类似于css中 nth-child
还不如写多个单值变量 — 并不是 — 假设需要设定一组button按钮的样式

// scss
$baseColor: red blue;
html {
    background: nth($baseColor, 1);
    color: nth($baseColor, 2);
}
// ==> css
html {
  background: red;
  color: blue; }

复杂变量 - 循环

// scss
$list: (top 30px) (right 30px) (bottom 10px) (left 40px);
@each $name, $value in $list{
    .box-#{$name} {
        width: $value;
    }
}

// ==>
.box-top {
  width: 30px; }

.box-right {
  width: 30px; }

.box-bottom {
  width: 10px; }

.box-left {
  width: 40px; }
// scss
$headers: (h1: 32px, h2: 20px, h3: 14px);
@each $key, $value in $headers {
    #{$key} {
        font-size: $value;
    }
}
// ==> css
h1 {
  font-size: 32px; }

h2 {
  font-size: 20px; }

h3 {
  font-size: 14px; }

嵌套

Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器。它可以避免重复书写父选择器,使结构更加清晰明了,样式的可读性更高。

// scss
html { 
    font-size: 12px;
    body {
        background: #f66;
        header {
            width: 100%;
            height: 40px;
            nav {
                background-color: #00f;
            }
        }
        section {
            width: 100%;
            min-height: 500px;
        }
        footer {
            width: 100%;
            height: 60px;
        }
    }
}
// ==> css
html {
  font-size: 12px; }
  html body {
    background: #f66; }
    html body header {
      width: 100%;
      height: 40px; }
      html body header nav {
        background-color: #00f; }
    html body section {
      width: 100%;
      min-height: 500px; }
    html body footer {
      width: 100%;
      height: 60px; }

混合器

@mixin 混合器可以包含选择器和选择器中的属性,通过 @include 来传参,这样就可以非常方便的复用需要常用的样式了。

无参数

// scss
@mixin marginCenter {
    margin: 0 auto;
}

.container {
    width: 1000px;
    min-height: 600px;
    // margin: 0 auto;
    @include marginCenter();
}

// ==> css
.container {
  width: 1000px;
  min-height: 600px;
  margin: 0 auto; }

有参数

// scss
@mixin margin($top, $right, $bottom, $left) {
    margin: $top $right $bottom $left;
}
.container {
    @include margin(10px, 10px, 20px, 20px);
}

// ==> css
.container {
  margin: 10px 10px 20px 20px; }

解决兼容问题

//scss
@mixin flexbox {
    display:-webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}

.nav {
    ul {
        @include flexbox();
        li{
            color: #333;
        }
    }
}
footer {
    ul {
        @include flexbox();
        li{
            font-size: 14px;
        }
    }
}

// ==> css
.nav ul {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex; }
  .nav ul li {
    color: #333; }

footer ul {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex; }
  footer ul li {
    font-size: 14px; }

混入 默认参数

// scss
@mixin opacity($val: 1) {
    opacity: $val;
}
.box {
    @include opacity();
}
.box1 {
    @include opacity(0.5);
}
// ==> css
.box {
  opacity: 1; }

.box1 {
  opacity: 0.5; }

扩展 / 继承

选择器继承是说一个选择器可以继承另一个选择器定义的所有样式。这个通过@extend语法实现
如果页面的header和footer的样式有共同之处,便可以在footer 使用 @extend来继承 header 的样式,免去重复书写。

// scss
.active {
    background-color: #f66;
    color: #fff;
}
.success {
    // background-color: #f66;
    // color: #fff;
    @extend .active;
    font-size: 30px;
}
// ==> css
.active, .success {
  background-color: #f66;
  color: #fff; }

.success {
  font-size: 30px; }

函数

// scss
@function dark($color, $val) {
    @return $color - $val;
}
@function light($color, $val) {
    @return $color + $val;
}
.text {
    color: dark(red, 200);
}
.text1 {
    color: light(red, 200);
}
// ==> 
.text {
  color: #370000; }

.text1 {
  color: #ffc8c8; }

条件判断

// scss
// @mixin flex($val: 1) {
//     box-flex:$val;
//     -webkit-box-flex:$val;
//     -moz-box-flex:$val;
//     flex:$val;
//     -webkit-flex:$val;
// }

@mixin flex($val) {
    @if $val == auto {
        box-flex:1;
        -webkit-box-flex:1;
        -moz-box-flex:1;
        flex:1;
        -webkit-flex:1;
    } @else {
        box-flex:$val;
        -webkit-box-flex:$val;
        -moz-box-flex:$val;
        flex:$val;
        -webkit-flex:$val;
    }
}

.test {
    @include flex(auto);
}

li {
    @include flex(3);
}
// ==> css
.test {
  box-flex: 1;
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  flex: 1;
  -webkit-flex: 1; }

li {
  box-flex: 3;
  -webkit-box-flex: 3;
  -moz-box-flex: 3;
  flex: 3;
  -webkit-flex: 3; }

导入另一个scss文件

// val.scss 变量
$baseColor: red;
$baseFontSize: 12px;
// base.scss 混入
@mixin flex {
    flex: 1
}
// test.scss 应用
@import 'val.scss';
@import 'base.scss';

.box {
    @include flex();
    font-size: $baseFontSize;
}

// ==》 css
.box {
  flex: 1;
  font-size: 12px; }

常见问题

有些观点认为不要过量使用选择器嵌套比较好,其中原因有:

1.增加编译难度,编译生成的css文件父类过多

2.使得最终代码难以阅读,选择器越具体会使得声明语句越冗长

3.混淆选择器路径和探索下一级选择器的错误率很高

解决方案

我觉得过量使用选择器嵌套确实是不太好的,但是只要使用合理在结构或是代码易读性上都还是有很大帮助的。

使用一致的类命名空间来命名我觉得是个不错的解决办法,一致的类命名既使代码易读,也不会混淆选择器路径。

比如,使用myapp-Header-link 来当做一个类名,组成它的三个部分都有着特定的功能:

1.myapp 首先用来将我们的应用和其他可能运行在同一个 DOM 上的应用隔离开来

2.Header 用来将组件和应用里其他的组件隔离开来

3.link 用来为局部样式效果保存一个局部名称

这样第一个标签类名可以写成myapp,myapp下的头部组件则可以写成myapp-Header,Header下的链接元素则可以写成myapp-Header-link。当使用选择器嵌套的时候,配合使用父选择器&,这样各个部分的结构就很清晰明了,不会混淆。

.myapp{
	width:100%;
	background:blue;
	&-Header{
		height:100px;
		&-link{
			color:red;
		}
	}	
}

参考文献

Sass中文网

https://www.sass.hk/

Sass中文网2

https://www.sasscss.com/

一个健壮且可扩展的 CSS 架构所需的8个简单规则

https://llp0574.github.io/2016/11/17/css-architecture/#3-use-consistent-class-namespacing

Less与Sass 的区别

http://www.cnblogs.com/wangpenghui522/p/5467560.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值