scss 超入门实作

拜读Alex前辈的scss教学,做个笔记。

建置专案

css资料夹是空的,scss资料夹里面有个style.scss,也是空的。

http://img2.58codes.com/2024/20112573AfNgt7nb5v.png

index.html,body内的程式码。

<div class="tabList">    <header>      <ul>        <li><a href="javascript:void(0)">A</a></li>        <li><a href="javascript:void(0)">B</a></li>        <li><a href="javascript:void(0)">C</a></li>        <li><a href="javascript:void(0)">D</a></li>        <li><a href="javascript:void(0)">E</a></li>      </ul>    </header>    <div>      <ul>        <li>          <h3>Microsoft 微软Surface Pro</h3>          <p>原价$41888★狂降一万二!</p>          <p>29888</p>        </li>        <li>          <h3>Microsoft 微软Surface Pro</h3>          <p>原价$41888★狂降一万二!</p>          <p>29888</p>        </li>        <li>          <h3>Microsoft 微软Surface Pro</h3>          <p>原价$41888★狂降一万二!</p>          <p>29888</p>        </li>      </ul>    </div>  </div>

预备工具

Prepros 这套工具可以帮助我们将SCSS转成CSS。

建立编辑SCSS所需的环境

Prepros下载安装完成后,打开软体。
http://img2.58codes.com/2024/20112573vVUynkPuol.png

将专案拖曳至Prepros内。
http://img2.58codes.com/2024/20112573A89C5l9yb7.png
此时,Prepros会持续监控专案的scss状态。

在开发过程中,Prepros不能关闭,不然会无法及时将scss转译成css。

回到专案,开始撰写scss。

巢状(Nesting)

巢状(Nesting)可说是新手接触scss的第一个功能,也是最容易理解的。

style.scss

.tabList {  > header {    color: red;  }  > div {    color: green;  }}

.tabList代表选取tabList class,在.tabList大括号里面的>(大于)代表子代选取器。

所以

> header {    color: red;  }

表示选取.tabList子代中的header元素,并将其color属性设定为红色。

以此类推,上一段的程式码,表示选取.tabList子代中的header和div元素,并将其color属性设定为红色和绿色。

完成之后,存档。

这时在视窗的右下角会出现这个图示。
http://img2.58codes.com/2024/20112573TUfggxs6pH.png
表示,成功将scss转译成css。

这时会发现css资料夹多了一个style.css,档名同原本的style.scss。

在开发过程,基本上我们可以专注于style.scss就好,至于style.css,Prepros会自动帮我们产生。

之后要做任何修改,请在style.scss,不要在style.css。

Why? 你都用scss了,干嘛还回头用css。

虽然说浏览器只认css,在css修改没有问题,但既然都用scss,就不用再回css了吧。

注意,请记得在index.html引入style.css。

再往下一层修改其他样式。

.tabList {  > header {    > ul {      list-style: none;      font-size: 0;    }    li {      display: inline-block;      width: calc(100% / 6);      font-size: 16px;    }  }  div {    color: red;  }}

使用>选取header子代中的ul,以及后代中的li。

至于这段程式码的功能请看参考影片,这篇会着重于scss的开发技巧。

注解

scss的注解有两种方式:/ /跟/* */。

那这两种的差别是,/ /(双斜线)不会被编译成css,换言之,使用/ /(双斜线)的注解,只会scss看到,css看不到。

相反地,/* */会被编译成css,所以css会看到。

//你看不到我!你看不到我!/*多行注解会显示*/

变数(Variable)

上一段程式码中,li的width是使用calc方式算出来的,这是css的语法,所以会直接显示于css,不会转译。

那有没有办法直接在scss算出来结果,再转css。

有,使用变数(Variable)可以做到这点。

既然讲到变数,就表示已经开始涉略到写程式思维了。

简单讲,变数就像一个容器,可以为这个容器取名,里面放的,是我们要运算的值,通常会是数值。

scss宣告变数的方式

$width: 100%;$buttonNumber: 6;

以$为开头,再取变数名称,之后,将值设定给这个变数。

变数$width,它的值为100%;变数$buttonNumber,它的值为6。

接下来就可以利用变数直接在scss中做计算,css所显示的会是计算结果。

scss

width: $width / $buttonNumber;

css

width: 16.66667%;

继承(Extend)

对于写后端程式的开发者而言,继承(extend)是必备的基本观念,但前端人员,尤其是设计师,这个就非常陌生了。

先实作,再解释,会比较容易理解。

将a做成按钮区块。

li {      display: inline-block;      width: $width / $buttonNumber;      font-size: 16px;      > a {        display: block;        width: 100%;        height: 20px;        line-height: 20px;        text-decoration: none;      }    }

a就会变成按钮区块。

那之后要是需要再次将其他的a变成按钮区块呢?

按照css的做法,肯定是要将所有的样式再写一次,有程式观念的人一定知道,这是非常没有效率的做法,尤其专案愈来愈複杂的情况,会很难维护。

css做不到的,scss可以做到,将重複使用的程式码包起来,之后若有需要,再叫出来即可。

修改上面的程式码。

我们将

display: block;text-decoration: none;

抽出来,这是之后将a做成按钮区块必备的属性设定。

设定一个class(aButton),将属性包起来。

scss

$width: 100%;$buttonNumber: 6;.aButton {  display: block;  text-decoration: none;}.tabList {  > header {    > ul {      list-style: none;      font-size: 0;    }    li {      display: inline-block;      width: $width / $buttonNumber;      font-size: 16px;      > a {        width: 100%;        height: 20px;        line-height: 20px;      }    }  }  div {    color: red;  }}

好了,接下来,使用继承,使a吃到.aButton的设定。

> a {        @extend .aButton;        width: 100%;        height: 20px;        line-height: 20px;      }

使用@extend,继承的关键字,后面接上要继承的class,如此一来,a就会继承.aButton,并吃到.aButton所有样式设定。

css

.aButton, .tabList > header li > a {  display: block;  text-decoration: none; }.tabList > header > ul {  list-style: none;  font-size: 0; }.tabList > header li {  display: inline-block;  width: 16.66667%;  font-size: 16px; }.tabList > header li > a {  width: 100%;  height: 20px;  line-height: 20px; }.tabList div {  color: red; }

请看第一段,不只.aButton有吃到设定,a确实也吃到设定。

往后,遇到相同的需求,只需将继承.aButton即可。

但这种命名方式有个缺陷,.aButton的功能是用来被继承的,它并不是html里面的任何元素,却被转译成css,是有点奇怪。

因此,我们可以将.aButton改成%aButton。

%aButton {  display: block;  text-decoration: none;}
> a {        @extend %aButton;        width: 100%;        height: 20px;        line-height: 20px;      }

%aButton就不会是class了,只是一个集合样式设定的区块,它的存在就是为了继承。

a一样可以继承%aButton,%aButton也不会被转译成css。

转译后,会发现css已经没有%aButton的蹤影了。

.tabList > header li > a {  display: block;  text-decoration: none; }

所以,只要有共用的样式设定,就可以使用继承来解决。

函式(Function)

有时,遇到属性的数值设定,像是font-size、padding、margin、line-height。

有经验的设计师都会使用级数,或有规则的运算逻辑去设定数值大小,而不会随便设一个数值。

专案小,每个数值可以手调,那万一专案很大呢?动辄数十页,不就改到疯掉?

既然数值是可以用规则算出来,那我们可以设定一个函式(Function),计算出结果。

假设,我们希望某些特定的元素padding,是使用10px、20px、30px这种级距去设定的。

宣告Function

scss

$basePadding: 10px;@function paddingLevel($count: 1) {  @return $basePadding * $count;}

首先在最上层,先设定基準padding:10px。

使用@function关键字,宣告一个名为paddingLevel的function。

名称后面的小括号($count: 1),会放入级距等级,变数$count预设是1。

意思是,假使我们都没放任何数值,$count就会以1计算,若放入2,就会以2去计算。

大括号里面,@return关键字,表示会将运算结果回传,讲白话,会将结果给丢出来。

$basePadding * $count,是运算部分,我们放入2,结果就会是10*2,@return就会将20px,回传。

使用function

scss

.a {  padding: paddingLevel();}.b {  padding: paddingLevel(2);}.c {  padding: paddingLevel(3);}

假设我们有不同的class,要套用不同级数的padding,可以输入Function名称(等级)。

css就会像这样。

.a {  padding: 10px; }.b {  padding: 20px; }.c {  padding: 30px; }

传入2个以上数值

刚刚的Function,只能传入一个数值,那如果想要把所有要算的值全部包含在Function里,也是可以的。

@function paddingLevel($count: 1, $basePadding: 10px) {  @return $basePadding * $count;}

小括号( ),多了一个参数$basePadding,预设值为10px,并用逗号( , )跟$count做区隔。

scss

.a {  padding: paddingLevel();}.b {  padding: paddingLevel(2,20px);}.c {  padding: paddingLevel(3,30px);}

css

.a {  padding: 10px; }.b {  padding: 40px; }.c {  padding: 90px; }

结果应该很容易理解吧。

以上讲到的,巢状(Nesting)、变数(Variable)、继承(Extend)、函式(Function),算是最基础的功能了。

接下来要讲的mixin,算是整合这些的应用,也比较进阶。

mixin

先看mixin跟extend的差异。

scss

%aButton {  display: block;  text-decoration: none;}@mixin aButton2 {  display: block;  text-decoration: none;}.a {  @extend %aButton;}.b {  @extend %aButton;}.c {  @extend %aButton;}.d {  @include aButton2();}.e {  @include aButton2();}.f {  @include aButton2();}

使用@mixin关键字,将共用样式给包起来。

看起来似乎跟extend有点像。

如若要套用mixin的话,要使用@include关键字。

css

.a, .b, .c {  display: block;  text-decoration: none; }.d {  display: block;  text-decoration: none; }.e {  display: block;  text-decoration: none; }.f {  display: block;  text-decoration: none; }

很明显的区别,虽然达到的目的都一样。

extend是共用一份样式。

但mixin会产生好几份同样的样式。

由此可知,这显然不是mixin该做的事。

那mixin的功能究竟是什么?

可以把mixin想像成,由变数(Variable)、继承(Extend)、函式(Function),所集合而成的大补帖。

恩,听起来笼统,直接实作。

我们想要设定字体大小从12px开始,每个级距是4px。

意思就是字体从12px、16px、20px这样加大的。

scss

$baseSize: 12px;$sizeLevel: 4px;@function font($level: 0) {  @if $level < 0 {    $level: 0;  }  @return $baseSize + $sizeLevel * round($level);}

@if是判断式关键字,意思是当$level小于0的时候,就把$level设为0,也就是预防输入负数的情况发生。

回传的是,基本字体大小(12px)+字体级距(4px)*四捨五入(输入的等级)。

round()是四捨五入的函式,回传整数。

scss

.a {  font-size: font(5);//12+5*4}.b {  font-size: font(6);//12+6*4}.c {  font-size: font(7);//12+7*4}

css

.a {  font-size: 32px; }.b {  font-size: 36px; }.c {  font-size: 40px; }

字体大小的级距规则订好了,那行高呢?

不同的字体大小也有相对应的行高,再次设定行高的计算规则。

scss

$baseLineSize: 10px;$paddingLevel: 1.2;@function rhythm($size) {  @return ceil($size * $paddingLevel / $baseLineSize) * $baseLineSize;}

$size是字体大小,ceil()会回传大于或等于所给定数值的最小整数。

处理逻辑是这样的:

ceil(字体大小 *1.2 / 10px)* 10px。

scss

.a {  font-size: font(5);//12+5*4  line-height: rhythm(font(5));//ceil(32*1.2/10)*10}.b {  font-size: font(6);//12+6*4  line-height: rhythm(font(6));//ceil(36*1.2/10)*10}.c {  font-size: font(7);//12+7*4  line-height: rhythm(font(7));//ceil(40*1.2/10)*10}

css

.a {  font-size: 32px;  line-height: 40px; }.b {  font-size: 36px;  line-height: 50px; }.c {  font-size: 40px;  line-height: 50px; }

只要使用function,输入数值,就可以得到相对应的结果。

不过,要得到字体大小与行高,得需要2个function,那有没有更简便的方式,只要输入级距,就可以自动产字体大小与行高呢?

有,就是mixin。

@mixin font($level: 1, $line-height: auto) {  $size: font($level);  $line: rhythm($size);  font-size: $size;  @if $line-height == auto or $line-height < $line {    line-height: $line;  } @else {    line-height: $line-height;  }}

一样使用@mixin关键字,宣告mixin,取名font,有两个参数。

$level预设为1,$line-height预设为auto。

$size: font($level),表示呼叫font() function,把计算结果设定给$size变数。

$line: rhythm($size),同理。

font-size: $size,设定字体大小的属性值为$size变数的值。

@if这段表示,如果$line-height等于auto或者我们自行输入的$line-height小于$line的值的话,就把$line的值设定给line-height属性,不然line-height属性值就使用我们自己输入的值。

@if判断式,对于没有学过程式逻辑的人来说,确实是个门槛,不过scss的强大与效率,是值得投资的。

完整的scss程式码

$baseSize: 12px;$baseLineSize: 10px;$sizeLevel: 4px;$paddingLevel: 1.2;@mixin aButton {  display: block;  text-decoration: none;}@function font($level: 0) {  @if $level < 0 {    $level: 0;  }  @return $baseSize + $sizeLevel * round($level);}@function rhythm($size) {  @return ceil($size * $paddingLevel / $baseLineSize) * $baseLineSize;}@mixin font($level: 1, $line-height: auto) {  $size: font($level);  $line: rhythm($size);  font-size: $size;  @if $line-height == auto or $line-height < $line {    line-height: $line;  } @else {    line-height: $line-height;  }}.a {  @include aButton();  @include font(5);}.b {  @include aButton();  @include font(6);}.c {  @include aButton();  @include font(7);}

所产生的css

.a {  display: block;  text-decoration: none;  font-size: 32px;  line-height: 40px; }.b {  display: block;  text-decoration: none;  font-size: 36px;  line-height: 50px; }.c {  display: block;  text-decoration: none;  font-size: 40px;  line-height: 50px; }

看到了吗?只要一行mixin,就可以产生font-size与line-height。

这就是mixin真正的价值所在。

接下来,我们要将这些function与mixin独立出来,让专案的其他scss或其他专案也可以使用。

首先,在scss资料夹新增_function.scss。

加底线的原因是,这个档案就不会被转译成css,_function.scss的功能只是做运算,不需要转成css。

_function.scss

$baseSize: 12px;$baseLineSize: 10px;$sizeLevel: 4px;$paddingLevel: 1.2;@mixin aButton {  display: block;  text-decoration: none;}@function font($level: 0) {  @if $level < 0 {    $level: 0;  }  @return $baseSize + $sizeLevel * round($level);}@function rhythm($size) {  @return ceil($size * $paddingLevel / $baseLineSize) * $baseLineSize;}@mixin font($level: 1, $line-height: auto) {  $size: font($level);  $line: rhythm($size);  font-size: $size;  @if $line-height == auto or $line-height < $line {    line-height: $line;  } @else {    line-height: $line-height;  }}

里面只有处理逻辑与设定属性值,没有指定任何元素。

只需要在需要计算出字体大小与行高的scss引入_function.scss即可。

test.scss

@import "function";.a {  @include aButton();  @include font(5);}.b {  @include aButton();  @include font(6);}.c {  @include aButton();  @include font(7);}

给初学者的建议,若觉得mixin太複杂,可以先使用变数(Variable)、继承(Extend)、函式(Function)就好。

等到熟悉了,再将这些功能整合进mixin即可。

SCSS还有很多地方可以讲,之后有机会再慢慢补充。

参考来源
[ Alex 宅干嘛 ] ?‍?从 CSS 到 SASS (SCSS) 超入门观念引导

Demo
MyGitHub


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章