css不是一种真正意义上的编程语言,只能死板并且重复的进行。
为了解决css的这些缺点,能够对css进行预处理的"中间语言"就产生了,以此来实现某些编程特性。
也就是在编写中间语言过程中,可以使用编程方式和思维,中间语言不能直接被浏览器所解析。
将这个中间语言编译成真正的css,供浏览器解析使用。
sass是最早的css预处理语言之一。
为了适应编程风格的需求,sass在编程风格上做了一些修改,现在称之为scss。
scss增加了一些新的功能,增强了对css3的支持,其语法完全兼容css3,并且继承了sass的强大功能。
scss即是sass的扩展。
它可以最大程度的减少你的css代码冗余度。
sass代码如下:
#sidebar
width: 30%
background-color: #faa
scss代码如下:
#sidebar {
width: 30%;
background-color: #faa;
}
可以看到scss和sass的区别主要在于大括号的有无,在sass中代码对缩进敏感,scss中带有大括号即可随意变更格式
声明变量
使用$符号声明一个变量
highlight-color,
并赋值为#F90然后在后面的代码中进行引用
$highlight-color: #F90;
.selected {
border: 1px solid $highlight-color;
}
编译后:
.selected {
border: 1px solid #F90;
}
变量分隔符
scss认为中划线和下划线是完全相等的
$link-color: blue;
a {
color: $link_color;
}
变量作用域
局部变量与全局变量
局部变量:定义在选择器之内的变量,使用范围是该选择器与子选择器
全局变量:定义在选择器之外的变量,子选择器中也定义了同名变量,则会覆盖全局变量
全局变量:
$bg-color: green;
div{
color:$bg-color;
}
局部变量:
div{
$border-width:5px;
color:$bg-color;
border:$border-width solid red;
}
更改局部变量的作用域范围
在变量后面添加 !global ,并声明选择器为 @mixin 混合器,最后使用 @include 引用该混合器,即可在其他选择器中使用该局部变量
@mixin button-style {
$btn-bg-color: lightblue !global;
color: $btn-bg-color;
}
button {
@include button-style;
}
.wrap {
background: $btn-bg-color;
}
编译后:
button {
color: lightblue;
}
.wrap {
background: lightblue;
}
设置变量的默认值
在变量后面添加 !default 即可指定默认值
在浏览器编译时,如果该变量已经有值,那么不使用默认值,如果没有值,则使用默认值
$content:"softwhy.com";
$content: "antzone" !default;
#main {
content: $content;
}
编译后:
#main {
content: "softwhy.com";
}
编译后保留注释
// 编译后在css文件中不保留注释
/* */ 编译后在css文件中保留注释
$padding: 50px;
div {
//antzone
padding:$padding;
}
$padding: 50px;
div {
/*antzone*/
padding : $padding;
}
嵌套写法
#content {
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
编译后:
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }
---------------------------------------------------
nav, aside {
a {color: blue}
}
编译后:
nav a, aside a {
color: blue
}
&父选择器标识符
&即代表当前元素的父类
article a {
color: blue;
&:hover { color: red }
}
编译后:
article a {
color: blue;
}
article a:hover {
color: red;
}
错误写法:
article a {
color: blue;
:hover { color: red }
}
错误写法编译后:
article a {
color: blue;
}
article a :hover {
color: red;
}
@import引入外部文件
css的@import命令会造成多次HTTP请求,导致效率低下
scss将引入的文件合并至目标中
scss的文件在引入时皆可以省略扩展名
@import "colors.scss";
scss文件的扩展名省略掉
@import "colors";
局部引入
blue-theme.scss
aside {
background: blue;
color: white;
}
.blue-theme {@import "blue-theme"}
.blue-theme aside {
background: blue;
color: #fff;
}
partial部分文件
那些专门为@import命令而编写的sass文件,并不需要生成对应的独立css文件,这样的sass文件称为局部文件。
对此,sass有一个特殊的约定来命名这些文件,预定规则如下:
局部文件的文件名以下划线开头
这样在编译的时候就不会生成对应的css文件了,只会单纯的作为一个导入文件使用。
@import themes/_night-sky.scss
省略扩展名
@import themes/_night-sky
字符串类型传参
接收时使用使用 #{} 包含参数即可解释参数为无引号字符串,便于在 mixin 中引用选择器名
防止运算符之间的冲突
@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
}
@include firefox-message(".header");
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
-----------------------------------------------
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
p {
font: 12px/30px;
}
-----------------------------------------------
p {
$font-size: 12px;
$line-height: 30px;
font: $font-size/$line-height;
}
p {
font: 0.4;
}
list 列表
如果列表长度不超过一行,始终单行显示
列表使用逗号分隔
末尾不加逗号
嵌套列表时使用括号,其他不需要添加括号
列表第一项的索引是1,而不是0
操作list的函数:
(1).length($list):返回一个列表的长度值。
(2).nth($list, $n):返回一个列表中指定的某个标签值。
(3).join($list1, $list2, [$separator]):将两个列给连接在一起,变成一个列表。
(4).append($list1, $val, [$separator]):将某个值放在列表的最后。
(5).zip($lists…):将几个列表结合成一个多维的列表。
(6).index($list, $value):返回一个值在列表中的位置值。
创建一个空列表
$list: ();
标准写法
$font-stack: 'Helvetica', 'Arial', sans-serif;
嵌套写法
$list: (
("item-1.1", "item-1.2", "item-1.3"),
("item-2.1", "item-2.2", "item-2.3"),
("item-3.1", "item-3.2", "item-3.3")
);
map对象
与list相同,只不过存储的值是key:value键值对的形式存在
操作map的函数:
(1).map-get($map,$key):根据给定key,返回map中对应的value。
(2).map-merge($map1,$map2):将两个map合并成一个新的map。
(3).map-remove($map,$key):从map中删除一个key,返回一个新map。
(4).map-keys($map):返回map中所有的key。
(5).map-values($map):返回map中所有的value。
(6).map-has-key($map,$key):根据给定key判断map是否有对应value,有返回true,否则false。
(7).keywords($args):返回一个函数的参数,这个参数可以动态的设置key和value。
普通map
$map: (
$key1: value1,
$key2: value2,
$key3: value3
)
嵌套map
$map: (
key1: value1,
key2: (
key-1: value-1,
key-2: value-2,
),
key3: value3
);
字符串连接符
根据等式前方是否具备引号来生成运算后结果是否具备引号
p:before {
content: "softwhy.com " + scss;
font-family: sans- + "serif";
}
p:before {
content: "softwhy.com scss";
font-family: sans-serif;
}
算术运算符
只有相同单位才可以进行运算,否则会报错
div {
/*不执行除法操作,原样输出*/
font-size: 16px / 24px;
/*使用插值语法之后,原样输出*/
font-size: #{$base-size} / #{$line-height};
/* 使用括号包裹之后,执行除法操作*/
font-size: (16px / 24px);
/* 使用变量,执行除法操作*/
font-size: $base-size / $line-height;
/* 调用函数,执行除法操作*/
opacity: random(4) / 5;
/* 使用算术操作符,执行除法操作*/
padding-right: 2px / 4px + 3px;
}
比较运算符
@mixin font-fl($font){
&:after {
@if(type-of($font) == string) {
content: 'My font is: #{$font}.';
}
@else {
content: 'Sorry, the argument #{$font} is a #{type-of($font)}.';
}
}
}
h2{
@include font-fl(sans-serif);
}
运算结果:
h2:after {
content: 'My font is: sans-serif.';
}
例子:
$padding: 50px;
h2 {
@if($padding <= 20px) {
padding: $padding;
} @else {
padding: $padding / 2;
}
}
逻辑运算符
and or not
例子:
$num:5;
$x:1;
p {
@if ($num>5 or $x<2) { border: 1px solid; }
}
结果:
p {
border: 1px solid;
}
@if() 指令
如果表达式的返回值不是false或者null,就返回指定的样式
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
p {
color: green;
}
@for 指令
用于循环输出,具有两种循环方式
@for $var from
through 索引区间是[start,end] @for $var from
to 索引区间是[start,end-1]
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
编译后:
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
@each指令
主要用于对于list或者map的遍历输出
list:
@each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
.puma-icon {
background-image: url("/images/puma.png");
}
.sea-slug-icon {
background-image: url("/images/sea-slug.png");
}
.egret-icon {
background-image: url("/images/egret.png");
}
.salamander-icon {
background-image: url("/images/salamander.png");
}
map:
$ppl: ( one:bob, two:john, three:bill, four:mike );
@each $key, $usr in $ppl {
.#{$usr}-avatar {
background-image: url('/img/#{$usr}.png');
}
}
.bob-avatar {
background-image: url("/img/bob.png");
}
.john-avatar {
background-image: url("/img/john.png");
}
.bill-avatar {
background-image: url("/img/bill.png");
}
.mike-avatar {
background-image: url("/img/mike.png");
}
@while指令
如果表达式的返回值为false,则停止循环
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
.item-6 {
width: 12em;
}
.item-4 {
width: 8em;
}
.item-2 {
width: 4em;
}
@media指令
主要针对于设备进行不同样式的定义
判断设备是否为横屏
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
}
编译后:
.sidebar {
width: 300px;
}
@media screen and (orientation: landscape) {
.sidebar {
width: 500px;
}
}
@at-root指令
添加了@at-root的子元素不参与父元素的样式,会跳出嵌套
@media与@supports指令不会使其跳出嵌套,需要使用without和with配合使用
.parent{
color:red;
@at-root .child {
width:200px;
height:50px;
}
}
编译后:
.parent {
color: red;
}
.child {
width: 200px;
height: 50px;
}
-----------------------------------------
.parent {
background:red;
@at-root {
.child-1 {
width:200px;
height:100px;
}
.child-2 {
width:150px;
height:50px;
}
}
}
编译后:
.parent {
background: red;
}
.child-1 {
width: 200px;
height: 100px;
}
.child-2 {
width: 150px;
height: 50px;
}
without和with
默认@at-root只会跳出选择器嵌套,而不能跳出@media或@support指令。
默认的@at-root就是@at-root (without:rule)。
如果要跳出这两种指令,则需使用@at-root (without: media),@at-root (without: support)。
supports :检查浏览器是否支持该属性
media :检测媒体(横屏竖屏)
without:跳出指令
@media print {
.parent{
color:#f00;
@at-root .child {
width:200px;
height:50px;
}
}
}
只能够跳出.parent,但是不能够跳出@media
编译后:
@media print {
.parent {
color: #f00;
}
.child {
width: 200px;
height: 50px;
}
}
---------------------------------------
@media print {
.parent{
color:red;
@at-root (without: media) {
.child {
width:200px;
height:50px;
}
}
}
}
只跳出media,并不会跳出.parent
编译后:
@media print {
.parent {
color: red;
}
}
.parent .child {
width: 200px;
height: 50px;
}
------------------------------------------
@media print {
.parent{
color:red;
@at-root (without: all) {
.child {
width:200px;
height:50px;
}
}
}
}
跳出全部
编译后:
@media print {
.parent {
color: red;
}
}
.child {
width: 200px;
height: 50px;
}
with:不跳出指定的指令,其他的全部跳出
@media print {
@supports ( transform-origin: 5% 5% ) {
@at-root (with: supports){
.foo {
color: green;
color: gray;
}
}
}
}
编译后:
@supports (transform-origin: 5% 5%) {
.foo {
color: green;
color: gray;
}
}
@content指令
在使用@include引用混合器的时候传递给混合器
当使用@include引用混合器的时候,里面所定义的css代码就会插入到@content所在的位置
@mixin antzone {
#head {
@content;
}
}
@include antzone {
#logo {
width:180px;
height:50px;
}
}
#head #logo {
width: 180px;
height: 50px;
}
@mixin混合器
如果存在大段可以重复使用的css代码,使用混合器可以方便的引用它
@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
编译后:
notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
-------------------------------------
直接在最外层引用
@mixin silly-links {
a {
color: blue;
background-color: red;
}
}
@include silly-links;
编译后:
a {
color: blue;
background-color: red;
}
-------------------------------------
嵌套引用
@mixin child-corners {
border-radius: 5px;
}
@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
@include child-corners;
}
notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
编译后:
notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
混合器没带参数,那么可以省略小括号;如果带有参数,必须带有小括号
参数与参数之间用逗号分隔如果没有传递此参数,那么就直接使用默认值。
如果传递了此参数,那么新的参数将会覆盖默认参数
@mixin setborder($color, $width: 2px) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p {
@include setborder(green);
}
h1 {
@include setborder(green, 4px);
}
---------------------------------------------
@mixin setborder($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
h1 {
@include setborder($color: green, $width: 4px);
}
参数变量(...)也可以在@include引用混合器的时候,将值列表中的值逐条作为参数引用:
@mixin colorlist($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$values: #ccc, #0ff, #fff;
.orignal{
@include colorlist($values...);
}
非必传值可以使用null来代替
如果只传了一个参数,接收时时两个参数,并且没有默认值,则会报错
@mixin antzone-div($color, $font-size) {
color:$color;
font-size:$font-size;
}
div{
@include antzone-div(blue, null);
}
@mixin和class 区别:
类名是在html使用,而混合器是在样式表中应用的
class具有语义化含义,主要是描述元素的含义
mixin混合器是展示行的描述,用来描述应用了后产生什么样的效果
混合器和类配合使用可以写出整洁的html和css
@extend
继承来自选择器的样式
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
编译后:
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
在@media中使用extend不可以继承@media之外的类
!optional指令
!optional标记前面的扩展不必须生成一个新的选择器,即使不存在也不会报错
p{
color:red;
@extend .notice !optional
}
编译:
p {
color: red;
}
% 占位符
如果定义的样式选择器在页面中没有使用过时,就可以使用%去定义选择器,不会进行编译
%icon {
color:red;
margin: 0 .5em;
}
.error-icon {
@extend %icon;
/*code*/
}
.seriousError-icon {
@extend %icon;
/*code*/
}
编译后:
.error-icon, .seriousError-icon {
color: red;
margin: 0 .5em;
}
.error-icon {
/*code*/
}
.seriousError-icon {
/*code*/
}
使用function定义函数
@function开头声明一个函数,函数内部使用@return返回一个值,参数可以省略
@function column-width($col, $total) {
@return percentage($col/$total);
}
.col-3 {
width: column-width(3, 8);
}
编译后:
.col-3 {
width: 37.5%;
}