ass学习笔记2
今天介绍sass在重用代码时最具威力的两个功能。一个是嵌套(Nesting),一个混合(Mixin)。
我们在写CSS通过需要多个后代选择器组合到一起才能定位到目标元素上,而这定义过程,此元素的父元素与其他选择器都有许多相同的部分,嵌套就是把这些相同的部分放到某一层花括号里,然后通过花括号的层层缩进堆砌,找到它们的共性与特性。
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 nav { ul { margin : 0 ; padding : 0 ; list-style : none ; } li { display : inline- block ; } a { display : block ; padding : 6px 12px ; text-decoration : none ; } } //------------------------------ nav ul { margin : 0 ; padding : 0 ; list-style : none ; } nav li { display : inline- block ; } nav a { display : block ; padding : 6px 12px ; text-decoration : none ; } |
当某一天,我们要兼容IE678等低级浏览器,发现它直接用nav不行时,需要改成.nav,我们只要改一处就行了,这大大提高维护性。
sass的嵌套包括两种:一种是选择器嵌套;另一种是属性嵌套。
选择器嵌套是指在一个选择器里面能出现多重花括号,里面的每一重花括号前的选择器会在编译后,直接在前面加一个空白(后代选择器)跟在前方选择器的后面。 如果你不想它们之间出现后代选择器,可以在选择器的前面加一个&进行处理。
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 #top_nav{ line-height : 40px ; text-transform : capitalize ; background-color : #333 ; li{ float : left ; } a{ display : block ; padding : 0 10px ; color : #fff ; &:hover{ color : #ddd ; } } } //------------------------------ nav ul { margin : 0 ; padding : 0 ; list-style : none ; } nav li { display : inline- block ; } nav a { display : block ; padding : 6px 12px ; text-decoration : none ; } |
属性嵌套,与前面的语法差不多,不同的是前面的选择器跟着一个冒号,那么编译后,它就像它转换为一个横扛与后面的选择器连接成一个单词。
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 .fakeshadow { border : { style: solid ; left : { width : 4px ; color : #888 ; } right : { width : 2px ; color : #ccc ; } } } //------------------------------ .fakeshadow { border-style : solid ; border-left-width : 4px ; border-left-color : #888 ; border-right-width : 2px ; border-right-color : #ccc ; } |
sass3.3还添加了一个@at-root,用于跳出嵌套的,但我觉得现在说会破坏文章的流程,跳过。
本文的第二个重点是@mixin,其实就相当于JS的函数,并且在传参方面,已经拥有es6、es7的一些新功能了。
为了与内置方法的风格保持一致,建议大家都使用ruby风格(全部小写,并通过横杠连接)。 它的参数与变量名要求一致,需要以$打头,多个参数与逗号分开。如果参数有默认值,后面跟冒号再跟默认值。 如果想在其他地方使用这个函数,需要通过@include关键字来声明一下。
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 @mixin center- block {//没有参数 margin-left : auto ; margin-right : auto ; } .demo{ @include center- block ();//小括号可以不写,但建议大家都写 } @mixin opacity($opacity: 50 ) {//有参数,并且有默认值 opacity: $opacity / 100 ; filter: alpha(opacity=$opacity); } .opacity{ @include opacity(); //使用默认值 } .opacity -80 { @include opacity( 80 ); //使用传参 } //------------------------------ .demo { margin-left : auto ; margin-right : auto ; } .opacity { opacity: 0.5 ; filter: alpha(opacity= 50 ); } .opacity -80 { opacity: 0.8 ; filter: alpha(opacity= 80 ); } |
我们用@mixin搞一个兼容IE67的浮动函数练练手!
$lte 7: true; @mixin float($ float : left ) { float : $float; @if $lte 7 { display : inline ; } } |
再来一个创建小三角形的函数
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 @mixin triangle($direction, $size, $borderColor ) { content : "" ; height : 0 ; width : 0 ; @if $direction == top { border-bottom :$size solid $borderColor; border-left :$size dashed transparent ; border-right :$size dashed transparent ; } @else if $direction == right { border-left :$size solid $borderColor; border-top :$size dashed transparent ; border-bottom :$size dashed transparent ; } @else if $direction == bottom { border-top :$size solid $borderColor; border-left :$size dashed transparent ; border-right :$size dashed transparent ; } @else if $direction == left { border-right :$size solid $borderColor; border-top :$size dashed transparent ; border-bottom :$size dashed transparent ; } } .top-arrow { @include triangle( top , 1px , red ) } //------------------------------ .top-arrow { content : "" ; height : 0 ; width : 0 ; border-bottom : 1px solid red ; border-left : 1px dashed transparent ; border-right : 1px dashed transparent ; } |
@content传参机制,它相当于在@include 调用语句后添加了一对括号,括号里的内容当作额外的参数来替换 @content所在的位置。 此特性在sass3.2.0中引入,可以用来解决css3的@media等带来的问题。
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 @mixin max- screen ($res){//参数一 @media only screen and ( max-width : $res ) { @content;//参数二 } } @include max- screen ( 480px ) {//传参一 body { color : red }//传参二 } //------------------------------ @media only screen and ( max-width : 480px ) { body { color : red ; } } |
此外,sass还有占位符及与它配套使用的@extend,它们的用法与@mixin, @include相差无几,以后再说。
@function函数,此函数能对样式的规则的属性值进行更精致的计算,并且调用时不需要@include,相当的方便。许多内置函数就是由它创建的。
//颜色处理 lighten( #cc3, 10%) // #d6d65c darken( #cc3, 10%) // #a3a329 grayscale( #cc3) // #808080 complement( #cc3) // #33c rgba( #102030, 0.5) => rgba(16, 32, 48, 0.5) rgba(blue, 0.2) => rgba(0, 0, 255, 0.2) //这个函数将一个颜色格式化成ie滤镜使用,在做css3使用滤镜兼容的时候用得上 ie-hex-str( #abc) => #FFAABBCC ie-hex-str( #3322BB) => #FF3322BB ie-hex-str(rgba(0, 255, 0, 0.5)) => #8000FF00 |
为数组添加更多方法
//定义first()函数,获取列表中的第一个列表项 @function list-first($list){ @return nth($list, 1 ); } //定义last()函数,获取列表中的最后一个列表项 @function list-last($list){ @return nth($list,length($list)); } //移除数组某个元素 @function remove($list, $value, $recursive: false) { $result: (); @for $i from 1 through length($list) { @if type-of(nth($list, $i)) == list and $recursive { $result: append($result, remove(nth($list, $i), $value, $recursive)); } @else if nth($list, $i) != $value { $result: append($result, nth($list, $i)); } } @return $result; } $list: a, b z, c, z, d, z, e, f; $new-list: remove($list, z); // a, b z, c, d, e, f; $new-list: remove($list, z, true); // a, b, c, d, e, f //在某一位置上删除元素 @function remove-nth($list, $index) { $result: null; @if type-of($index) != number { @warn "$index: #{quote($index)} is not a number for `remove-nth`." ; } @else if $index == 0 { @warn "List index 0 must be a non-zero integer for `remove-nth`." ; } @else if abs($index) > length($list) { @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`." ; } @else { $result: (); $index: if($index < 0 , length($list) + $index + 1 , $index); @for $i from 1 through length($list) { @if $i != $index { $result: append($result, nth($list, $i)); } } } @return $result; } $list: a, b, z, c, d, e, f; $new-list: remove-nth($list, 3 ); // a, b, c, d, e, f $new-list: remove-nth($list, 0 ); // error $new-list: remove-nth($list, -2 ); // a, b, z, c, d, f $new-list: remove-nth($list, -10 ); // error $new-list: remove-nth($list, 100 ); // error $new-list: remove-nth($list, zog); // error //对数组进行切片操作 @function slice($list, $start: 1 , $end: length($list)) { $result: null; @if type-of($start) != number or type-of($end) != number { @warn "Either $start or $end are not a number for `slice`." ; } @else if $start > $end { @warn "The start index has to be lesser than or equals to the end index for `slice`." ; } @else if $start < 1 or $end < 1 { @warn "List indexes must be non-zero integers for `slice`." ; } @else if $start > length($list) { @warn "List index is #{$start} but list is only #{length($list)} item long for `slice`." ; } @else if $end > length($list) { @warn "List index is #{$end} but list is only #{length($list)} item long for `slice`." ; } @else { $result: (); @for $i from $start through $end { $result: append($result, nth($list, $i)); } } @return $result; } } $list: a, b, c, d, e, f; $new-list: slice($list, 3 , 5 ); // c, d, e $new-list: slice($list, 4 , 4 ); // d $new-list: slice($list, 5 , 3 ); // error $new-list: slice($list, -1 , 10 ); // error //反转数组 @function reverse($list, $recursive: false) { $result: (); @for $i from length($list)* -1 through -1 { @if type-of(nth($list, abs($i))) == list and $recursive { $result: append($result, reverse(nth($list, abs($i)), $recursive)); } @else { $result: append($result, nth($list, abs($i))); } } @return $result; } $list: a, b, c d e, f, g, h; $new-list: reverse($list); // h, g, f, c d e, b, a $new-list: reverse($list, true); // h, g, f, e d c, b, a //函数全部来自 http://hugogiraudel.com/ 2013 / 08 / 08 /advanced-sass-list-functions/ |
我们再创建一个页面看看unshift方法的效果
<! DOCTYPE html> < html > < head > < title >TODO supply a title</ title > < meta charset="UTF-8"> < meta name="viewport" content="width=device-width"> < link rel="stylesheet" type="text/css" href="css/index.css"> </ head > < body > < div class="text">司徒正美</ div > < a href="http://www.cnblogs.com/rubylouvre">这是链接</ a > </ body > </ html > |
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 $list: b, c, d, e, f; @function unshift($list, $value) { @return join($value, $list); } $newlist: unshift($list, a); // a, b, c, d, e, f body{ background : blanchedalmond; } .text{ &:after{ color : red ; display : block ; border : 1px solid red ; content : "#{$newlist}" ; } } //------------------------------ body { background : blanchedalmond; } .text:after { color : red ; display : block ; border : 1px solid red ; content : "a, b, c, d, e, f" ; } |
我们再定义一个将rem转换为px的函数:
@charset "utf-8" ;//必须设置了这个才能编译有中文的注释 $pixelBase : 16 ; $px-only:true; @function parseInt($n) { @return $n / ($n * 0 + 1 ); } @function rem 2px ($values){ $list: (); @each $value in $values { //遍历数组 $unit : unit($value); //取得其单位 $val : parseInt($value); //取得其值 @if ($px-only) and ($unit == 'rem' ) { $list: append($list, ($val * $pixelBase) + px); } @else if($unit == 'px' ) or ($unit == 'rem' ){ $list: append($list, $value); } @else { @warn 'There is no unit conversion for #{$unit}' ; } } @return $list; } body * { margin :rem 2px ( 1 rem 2 rem 20px 3 rem); padding-bottom :rem 2px ( 0.25 rem); font-size :rem 2px ( 0.875 rem); } //------------------------------ body * { margin : 16px 32px 20px 48px ; padding-bottom : 4px ; font-size : 14px ; } |
有了函数,sass就真正算是一门编程语言了!~