码迷,mamicode.com
首页 > 其他好文 > 详细

Sass学习笔记 -- 变量及变量作用域历史遗留问题

时间:2016-11-10 22:08:50      阅读:726      评论:0      收藏:0      [点我收藏+]

标签:sass scss 变量 #{}

sass有两种后缀名文件:

一种后缀名为sass,写选择器时不能使用大括号和分号

一种后缀名为scss,使用大括号和分号

//后缀名为sass的语法,不能出现大括号和分号
$highlight-color: #abcdef

.selected
  border: 1px $highlight-color solid
  
//后缀名为scss的语法,跟css一样,需要大括号和分号
$highlight-color: #abcdef;

.selected{
  border:1px solid $highlight-color;
}


Sass的一个重要特性就是它为CSS引入了变量。你可以把反复使用的CSS属性值定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。或者,对于仅使用过一次的属性值,你可以赋予其一个易懂的变量名,让人一眼就知道这个属性值的用途


Sass使用“$”来标识变量,比如: $highlight-color, $width


变量声明

1、普通变量

Sass变量的声明跟CSS属性的声明很像,后面紧跟变量名,变量名和值之间用冒号分隔开

$highlight-color: #abcdef;


这就意味着变量$highlight-color现在的值是#abcdef,这时的变量还没有生效,除非你引用了这个变量

.selected{
  border:1px solid $highlight-color;
}


2、默认变量

如果值后面加 "!default" 则表示默认值

"!default" 

//scss
$color:red;
$color:blue;
p{
  color:$color;
}

//css编译
p {
  color: blue; }


"!default" 

//scss
$color:red;
$color:blue !default;
p{
  color:$color;
}

//css编译
p {
  color: red; }


sass编译css是从上到下的,后面会覆盖前面的,所以第一段无!default的解析的是blue,而第二段代码由于有了!default,打破了这个规则,使用了前面定义的red


//scss
$baseLineHeight:2px; //这个写在带有!default的变量后面就没有任何意义了
$baseLineHeight:1.5px !default;

.box{
  line-height:$baseLineHeight;
}
//css编译
.box {
  line-height: 2px; }


3、#{}  让一切变成字符串

一般我们定义的变量都为属性值,可直接使用,但是如果变量作为属性、选择器或在某些特殊情况下等则必须要以#{$variables}形式使用。

//scss
$borderDirection: top !default;
$baseFontSize: 12px !default;
$baseLineHeight:1.5 !default;

//应用于class和属性
.border-#{$borderDirection}{
  border-#{$borderDirection}:1px solid #ddd;
}
//应用于复杂的属性值
body{
  font:#{$baseFontSize}/#{$baseLineHeight};
}

//css编译
.border-top {
  border-top: 1px solid #ddd; }

body {
  font: 12px/1.5; }
//scss
@mixin firefox-message($selector) {
  body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
  }
}

@include firefox-message(".header");

//css编译
body.firefox .header:before {
  content: "Hi, Firefox users!"; }

如果不用行不行呢?不妨试试看:

//scss
body{
  font:$baseFontSize/$baseLineHeight;
}

//css编译
body {
  font: 8px; }


字体成了8px,因为误做了除法,上面的border-top如果不加#{}的话,无法编译


4、多值变量

多值变量分为list类型和map类型,简单来说list类型有点像js中的数组,而map类型有点像js中的对象。

(1)、list

list数据可通过空格,逗号或小括号分隔多个值,可用nth($var,$index)取值。关于list数据操作还有很多其他函数如length($list),join($list1,$list2,[$separator]),append($list,$value,[$separator])等


//一维数据
$px: 5px 10px 20px 30px;

//二维数据,相当于js中的二维数组
$px: 5px 10px, 20px 30px;
$px: (5px 10px) (20px 30px);
//scss
$linkColor: #f00 #eee !default;//第一个值为默认值,第二个值为鼠标滑过值
a{
  color:nth($linkColor,1);
  &:hover{
    color:nth($linkColor,2);
  }
}

//css编译
a {
  color: #f00; }
  a:hover {
    color: #eee; }


(2)、map

map数据以key和value成对出现,其中value又可以是list。格式为:$map: (key1: value1, key2: value2, key3: value3);。可通过map-get($map,$key)取值。关于map数据还有很多其他函数如map-merge($map1,$map2),map-keys($map),map-values($map)等


//scss
$headings:(h1:2em, h2:1.5em, h3:1em);
@each $header, $size in $headings{
  #{$header}{
    font-size:$size;
}
}

//css编译
h1 {
  font-size: 2em; }

h2 {
  font-size: 1.5em; }

h3 {
  font-size: 1em; }


上面的代码中,把map数据的属性看作是$header,把属性值看作是$size进行遍历(当成了js对象去理解,所以称之为属性和属性值,这种说法不一定对)


变量运算

你能够运用‘加’或‘减’操作符来对相同类型的变量进行运算,如果我们想要手动的轻微的加深一个颜色值,可以通过‘-‘来减去#101,同样我们可以通过‘+’来将字体值增大10px。

//scss
$red:#f00;
$fontSize:12px;

.bar{
  color:$red+#101;
  font-size:$fontSize+10px;
}

//css编译
.bar {
  color: #ff0011;
  font-size: 22px; }


全局变量和局部变量

首先声明:当前sass版本是3.4.22,与之前的3.3版本相比,有关全局变量这块有所不同。跟着原来的文档学习,在编译的时候出现了差异,困扰了我很久,去一些交流群问还被人夹枪带棒的嘲笑,最后非常庆幸得到大漠老师的指导,指出版本的差异并分享了较新的文档资料,在这里再次感谢大漠老师!!!

大漠老师文章:http://www.w3cplus.com/preprocessor/understanding-variable-scope-in-sass.html


在当前大部分文档中都有这么一句话“sass没有局部变量”,并且随处可见这种示例

技术分享


大家不妨把sass代码重新编译一下,我们得到的结果却是:

技术分享

所以,如果跟我一样是sass初学者的话,就跳过你看到的那些老的文档关于变量作用域的介绍吧


sass变量作用域支持两种类型变量:全局变量和局部变量

全局变量:默认情况下,所有定义在任何选择器之外的变量被认为是全局变量。这就意味着他们可以在样式表中任意地方被访问

$bg-color: green;


局部变量:定义在选择器之内的变量称之为局部变量


先看第一个例子,首先定义一个混合器,在里面添加一个$btn-bg-color变量,这是一个局部变量,它只在mixin内部可见

@mixin button-style {
  $btn-bg-color: lightblue;
  color: $btn-bg-color;
}


接下来,调用这个mixin

button {
  @include button-style;
}

//执行css编译
button {
  color: lightblue;
}


如果不是一个mixin,而是一个选择器来调用这个局部变量,可以想象,应该是无法调用的吧

技术分享


嵌套选择器

如果我们在一个选择器内部声明了一个变量,嵌套在里面的其他选择器中都可以访问它

//scss
.wrap {
    $bg-color: red;

    &:after {
        background: lighten($bg-color, 10%);
    }
}

//css
.wrap:after {
  background: #ff3333;
}


再看一个例子,我们定义了一个函数,然后在嵌套的选择器中使用这个函数

//scss
@function my-function() {
    $text-color: black;
    @return $text-color;
}

.wrap {
    color: my-function();
}

//css
.wrap {
  color: black;
}



我们稍加修改一下:

//scss
@function my-function() {
    $text-color: black;
    @return $text-color;
}

.wrap {
    color: my-function();

    &:after{
        background: $text-color;
    }
}

技术分享


编译的结果是变量$text-color未定义,因为它不是直接定义在选择器里面,而是在选择器内部调用了定义的函数


全局变量和局部变量可以定义相同的变量名,我们定义了三个相同变量名的变量,只是他们具有不同的值。第一个是全局变量,其他两个是局部变量

//scss
//定义一个全局变量
$text-color: tomato;

//定义一个混合器
@mixin button-style {
  $text-color: lime;
  color: $text-color;
}

@mixin link-style {
  $text-color: black;
  color: $text-color;
}

//调用混合器
button {
  @include button-style;
}

a {
  @include link-style;
}

//调用变量
.wrap {
  background: $text-color;
}

//css
button {
  color: lime; }

a {
  color: black; }

.wrap {
  background: tomato; }



Global标志

"!global"可以改变一个局部变量的作用范围,回到我们一开始探讨sass版本的那个例子

//scss
p{
    $color:blue !global;
    color:$color;//blue
}
a{
    color:$color;//本来应该是Undefined variable
}

技术分享


理论上,$color是定义在p里面的局部变量,a选择器里面的color应该是访问不到的,但是我们通过"!global"标志可以让$color发挥一个全局变量的作用


检查一个变量是否存在

Sass提供了两个函数,用来测试一个变量是否存在。我们可以使用variable-exists或global-variable-exists函数来检查我们的局部变量或全局变量是否分别存在

//scss
$text-color: tomato;
@if(global_variable_exists(text-color)){
  #mainTitle{
    color:$text-color;
  }
}

//css
#mainTitle {
  color: tomato; }


有一定英语基础的朋友,也可以从下面两个网站学习

http://sass-lang.com/documentation/file.SASS_REFERENCE.html

https://webdesign.tutsplus.com/articles/understanding-variable-scope-in-sass--cms-23498


本文出自 “dapengtalk” 博客,请务必保留此出处http://dapengtalk.blog.51cto.com/11549574/1871447

Sass学习笔记 -- 变量及变量作用域历史遗留问题

标签:sass scss 变量 #{}

原文地址:http://dapengtalk.blog.51cto.com/11549574/1871447

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!