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就真正算是一门编程语言了!~