Sass/Scss 学习总结(二) 之 语法学习

语法

Sass 有两种语法格式。首先是 SCSS (Sassy CSS) ,也是本学习教程所使用的格式 , 这种格式仅在 CSS3 语法的基础上进行扩展,这意味着每个CSS样式表是一个同等的SCSS文件。此外,SCSS 也支持大多数 CSS hacks 写法 以及浏览器专属前缀语法 (vendor-specific syntax),例如,IE 古老的 filter 语法。 这种语法的样式表文件需要以 .scss 作为拓展名。

另一种,也是最早的语法,被称为缩进语法 (Indented Sass),或者通常说的 "Sass",它提供了一种更加简介的方式来书写CSS。它使用缩进而不是花括号来表示选择器的嵌套,用换行而不是分号来分隔属性,一些人认为这样做比 SCSS 更容易阅读,书写也更快速。 缩排语法具有 Sass 的所有特色功能, 虽然有些语法上稍有差异; 具体差异在缩进语法参考中都有描述。 使用此种语法的样式表文件需要以 .sass 作为扩展名。

// 文件后缀名为sass的语法
body
    background: #eee
    font-size:12px
p
    background: #0982c1

// 文件后缀名为scss的语法  
body {
    background: #eee;
    font-size:12px;
}
p {
    background: #0982c1;
}

任何一种语法的文件可以直接 import(导入) 到另一种语法的文件中使用,只要使用 sass-convert 命令行工具,就可以将一种语法转换为另一种语法:

# 将 style.sass 转化为 style.scss
$ sass-convert style.sass style.scss

# 将 style.scss 转化为 style.sass
$ sass-convert style.scss style.ss

请注意,此命令不会生成 CSS 文件,如果想生成 CSS 文件,请使用 sass 命令,如:

# 将 input.scss 转化为 output.css
$ sass input.scss output.css

还可以使用 --watch 参数监视文件的改动并更新 css

sass --watch input.scss:output.css

如果你的目录里有很多 scss 文件,还可以用 sass 监视整个目录

sass --watch app/sass:public/stylesheets

更多的 sass 使用命令,可以通过 sass --help 列出完整的帮助文档


注释

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; }

编译后的 CSS 文件

/* 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; }

默认情况下,将 SASS 文件转化为 CSS 文件是不压缩的,如果在编译时使用 --style compressed 参数,将会把输出压缩后的 css 样式,这时候,多行注释也是会删除的,如将上面的 SCSS 用下面命令编译:

$ sass --style compressed b.scss b.css

编译后的 CSS 文件

body{color:black}a{color:green}

如果多行注释的第一个字母是 !,那么注释总是会被保留到输出的 CSS 中,即使在压缩输出模式下,这可用于在你生成的CSS中添加版权声,例如:

/*! This CSS is generated by My Snazzy Framework version 1.0.0 . */
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; }

编译后的 CSS 文件

/*! This CSS is generated by My Snazzy Framework version 1.0.0 . */body{color:black}a{color:green}

注意:如果遇到中文注释报错的情况,请使用以下方法,找到 ruby 的安装目录,如,我的安装目录为:

C:\Ruby23-x64\lib\ruby\gems\2.3.0\gems\sass-3.4.23\lib\sass

在这个目录里有一个 engine.rb 文件,打开,在第54行(也就是 require XX之后),添加如下代码

Encoding.default_external = Encoding.find('utf-8')

保存,重新打开命令行,再编译即可。


嵌套

SCSS 中选择器的嵌套指的是在一个选择器中嵌套另一个选择器来实现继承。比如说,我们在CSS中多个元素有一个相同的父元素,那么写样式会变得乏味,我们需要一遍一遍的在每个元素前写这个父元素,除非给特定的元素添加类名或ID。

section { 
    margin: 10px; 
} 
section nav { 
    height: 25px; 
} 
section nav a { 
    color: #0982c1; 
} 
section nav a:hover { 
    text-decoration: underline; 
}

如果使用SCSS中的选择器嵌套特性,我们可以在父元素的大括号 {} 里写这些元素。同时可以使用 & 符号来引用元素的父选择器。这有助于避免父选择器重复,相对于复杂的CSS布局中多层嵌套的选择器 要简单得多。如,我们让上面的 CSS 换成 SCSS 文件:

section { 
    margin: 10px; 
    nav { 
        height: 25px; 
	a { 
	    color: #0982c1; 
    	    &:hover { 
	        text-decoration: underline; 
	    }
	}
    }
}


属性嵌套

CSS中有一些属性遵循相同的“命名空间”;比如,font-family, font-size, 和 font-weight都在font命名空间中。在CSS中,如果你想在同一个命名空间中设置一串属性,你必须每次都输出来。Sass为此提供了一个快捷方式:只需要输入一次命名空间,然后在其内部嵌套子属性。例如:

// CSS 格式的写法
// -------------------------------

.funky {
    font-family: "fantasy";
    font-size: 12px;
    font-weight: bold;
}

// SCSS 格式的写法
// -------------------------------
.funky {
    font: {
	family: "fantasy";
	size: 12px;
	weight: bold;
    }
}

在属性嵌套时,对于“多属性标签”也可以定义自己的属性值,例如:

// SCSS 格式的写法
// -------------------------------

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

// 编译后的 CSS 文件
// -------------------------------

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


群组选择器的嵌套

在 CSS 里边,选择器 h1, h2 和 h3 会同时命中 h1元素、h2元素、h3元素。与此类似,.button, button 会命中 button 元素和类名为 .button 的元素。这种选择器称为群组选择器,群组选择器的规则会对命中群组中的任何一个选择器的元素生效。

.button, button 
{
    margin: 0;
}

当看到上边这段代码时,你可能还没意识到会有重复性的工作。但会很快发现:如果你需要在一个特定的容器元素内对这样一个群组选择器进行修饰,情况就不同了。css 的写法会让你在群组选择器中的每一个选择器前都重复一遍容器元素的选择器。

.container h1, .container h2, .container h3 { 
    margin-bottom: .8em 
}

非常幸运,sass 的嵌套特性在这种场景下也非常有用。当 sass 解开一个群组选择器规则内嵌的规则时,它会把每一个内嵌选择器的规则都正确地解出来:

.container {
    h1, h2, h3 {
        margin-bottom: .8em
    }
}

首先 sass 将 .container 和 h1 、h2 和 h3 分别组合,然后将三 者重新组合成一个群组选择器,生成你前边看到的普通 css 样式。


引用父选择符:&

一般情况下,SASS 在编译一个嵌套规则时,会把父选择器通过一个空格连接到子选择器的前面,如:

// SCSS 文件
nav {
    ul {
	li {
    	    color: red;
	}
    }
}

// 编译后的 CSS 文件
nav ul li {
  color: red; 
}

有时候需要在内选择器里直接使用嵌套外层的父选择器,最常见的一种情况是当你为链接之类的元素写:hover这种伪类时,你并不希望以后代选择器的方式连接。在这些情况下,你可以 & 字符来明确地表示插入指定父选择器。 例如:

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

编译后的 CSS 文件

a {
    font-weight: bold;
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

body.firefox a {
    font-weight: normal;
}

& 将替换为呈现在CSS文件中的父选择器。这意味着,如果你有一个多层嵌套的规则,父选择器将在被 & 替换之前完全分解。例如:

// SCSS 文件
// -----------------------

#main {
    color: black;

    div {
	span & {
	    font-size: 12px;
	}

	& span {
	    font-size : 14px;
	}
    }
}


// 编译后的 CSS 文件,注意 & 位置不同,编译出来的样式也不同
// -----------------------

#main {
    color: black;
}

span #main div {
    font-size: 12px;
}

#main div span {
    font-size: 14px;
}

另外,父选择器 & 是可以做为一个选择器的前缀的,例如:

// SCSS 文件
// -----------------------

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

// 编译后的 CSS 文件
// -----------------------

#main {
    color: black;
}

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

父选择器 & 被作为一个后缀的时候,Sass 将抛出一个错误。例如:

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

如果没有父选择器,& 的值将是空,这可以在判断时,做为判断条件,以后在学习 @if 时会学习,如:

mixin does-parent-exist {
    @if & {
        &:hover {
    	    color: red;
	}
    } @else {
	a {
	    color: red;
	}
    }
}


未经允许不得转载:易读小屋  »  Sass/Scss 学习总结(二) 之 语法学习