less预处理器*
一,css预处理器的定义
CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。
CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题
通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题”。
例如你可以在 CSS 中使用变量、简单的逻辑程序、函数(如右侧代码编辑器中就使用了变量$color)等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
其它 CSS 预处理器语言:
CSS 预处理器技术已经非常的成熟,而且也涌现出了很多种不同的 CSS 预处理器语言,比如说:
Sass(SCSS)
LESS
Stylus
Turbine
Swithch CSS
CSS Cacheer
DT CSS
到目前为止,在众多优秀的 CSS 预处理器语言中就属 Sass、LESS 和 Stylus 最优秀,讨论的也多,对比的也多。本教程将着重向大家介绍 CSS 预处理器中的 Sass。相信前端开发工程师会喜欢的。
二 ,css预处理器的作用
浅谈 CSS 预处理器: 为什么要使用预处理器?
背景
CSS 自诞生以来,基本语法和核心机制一直没有本质上的变化,它的发展几乎全是表现力层面上的提升。最开始 CSS 在网页中的作用只是辅助性的装饰,轻便易学是最大的需求;然而如今网站的复杂度已经不可同日而语,原生 CSS 已经让开发者力不从心。
当一门语言的能力不足而用户的运行环境又不支持其它选择的时候,这门语言就会沦为 “编译目标” 语言。开发者将选择另一门更高级的语言来进行开发,然后编译到底层语言以便实际运行。
于是,在前端领域,天降大任于斯人也,CSS 预处理器应运而生。而 CSS 这门古老的语言以另一种方式 “重新适应” 了网页开发的需求。
预处理器赋予我们的 “超能力”
简单梳理一下,CSS 预处理器为我们带来了几项重要的能力,由浅入深排列如下。(不用在意你用到了多少,无论深浅,都是获益。)
1.文件切分
页面越来越复杂,需要加载的 CSS 文件也越来越大,我们有必要把大文件切分开来,否则难以维护。传统的 CSS 文件切分方案基本上就是 CSS 原生的 @import 指令,或在 HTML 中加载多个 CSS 文件,这些方案通常不能满足性能要求。
CSS 预处理器扩展了 @import 指令的能力,通过编译环节将切分后的文件重新合并为一个大文件。这一方面解决了大文件不便维护的问题,另一方面也解决了一堆小文件在加载时的性能问题。
2.模块化
把文件切分的思路再向前推进一步,就是 “模块化”。一个大的 CSS 文件在合理切分之后,所产生的这些小文件的相互关系应该是一个树形结构。
树形的根结节一般称作 “入口文件”,树形的其它节点一般称作 “模块文件”。入口文件通常会依赖多个模块文件,各个模块文件也可能会依赖其它更末端的模块,从而构成整个树形。
以下是一个简单的示例:
entry.styl
├─ base.styl
│ ├─ normalize.styl
│ └─ reset.styl
├─ layout.styl
│ ├─ header.styl
│ │ └─ nav.styl
│ └─ footer.styl
├─ section-foo.styl
├─ section-bar.styl
└─ …
(入口文件 entry.styl 在编译时会引入所需的模块,生成 entry.css,然后被页面引用。)
如果你用过其它拥有模块机制的编程语言,应该已经深有体会,模块化是一种非常好的代码组织方式,是开发者设计代码结构的重要手段。模块可以很清晰地实现代码的分层、复用和依赖管理,让 CSS 的开发过程也能享受到现代程序开发的便利。
3.选择符嵌套
选择符嵌套是文件内部的代码组织方式,它可以让一系列相关的规则呈现出层级关系。在以前,如果要达到这个目的,我们只能这样写:
.nav {margin: auto /* 水平居中 /; width: 1000px; color: #333;}
.nav li {float: left / 水平排列 */; width: 100px;}
.nav li a {display: block; text-decoration: none;}
这种写法需要我们手工维护缩进关系,当上级选择符发生变化时,所有相关的下级选择符都要修改;此外,把每条规则写成一行也不易阅读,为单条声明写注释也很尴尬(只能插在声明之间了)。
在 CSS 预处理语言中,嵌套语法可以很容易地表达出规则之间的层级关系,为单条声明写注释也很清晰易读:
.nav
margin: auto // 水平居中
width: 1000px
color: #333
li
float: left // 水平排列
width: 100px
a
display: block
text-decoration: none
4.变量
在变更出现之前,CSS 中的所有属性值都是 “幻数”。你不知道这个值是怎么来的、它的什么样的意义。有了变量之后,我们就可以给这些 “幻数” 起个名字了,便于记忆、阅读和理解。
接下来我们会发现,当某个特定的值在多处用到时,变量就是一种简单而有效的抽象方式,可以把这种重复消灭掉,让你的代码更加 DRY。
我们来比较一下以下两段代码:
/* 原生 CSS 代码 */
strong {
color: #ff4466;
font-weight: bold;
}
/* … */
.notice {
color: #ff4466;
}
// 用 Stylus 来写
$color-primary = #ff4466
strong
color: $color-primary
font-weight: bold
/* … */
.notice
color: $color-primary
你可能已经意识到了,变量让开发者更容易实现网站视觉风格的统一,也让 “换肤” 这样的需求变得更加轻松易行。
5.运算
光有变量还是不够的,我们还需要有运算。如果说变量让值有了意义,那么运算则可以让值和值建立关联。有些属性的值其实跟其它属性的值是紧密相关的,CSS 语法无法表达这层关系;而在预处理语言中,我们可以用变量和表达式来呈现这种关系。
举个例子,我们需要让一个容器最多只显示三行文字,在以前我们通常是这样写的:
.wrapper {
overflow-y: hidden;
line-height: 1.5;
max-height: 4.5em; /* = 1.5 x 3 */
}
大家可以发现,我们只能用注释来表达 max-height 的值是怎么来的,而且注释中 3这样的值也是幻数,还需要进一步解释。未来当行高或行数发生变化的时候,max-height 的值和注释中的算式也需要同步更新,维护起来很不方便。
接下来我们用预处理语言来改良一下:
.wrapper
$max-lines = 3
$line-height = 1.5
overflow-y: hidden
line-height:
l
i
n
e
−
h
e
i
g
h
t
m
a
x
−
h
e
i
g
h
t
:
u
n
i
t
(
line-height max-height: unit(
line−heightmax−height:unit(line-height * $max-lines, ‘em’)
乍一看,代码行数似乎变多了,但代码的意图却更加清楚了——不需要任何注释就把整件事情说清楚了。在后期维护时,只要修改那两个变量就可以了。
值得一提的是,这种写法还带来另一个好处。$line-height 这个变量可以是 .wrapper 自己定义的局部变量(比如上面那段代码),也可以从更上层的作用域获取:
$line-height = 1.5 // 全局统一行高
body
line-height: $line-height
.wrapper
$max-lines = 3
max-height: unit($line-height * $max-lines, ‘em’)
overflow-y: hidden
这意味着 .wrapper 可以向祖先继承行高,而不需要为这个 “只显示三行” 的需求把自己的行高写死。有了运算,我们就有能力表达属性与属性之间的关联,它令我们的代码更加灵活、更加 DRY。
6.函数
把常用的运算操作抽象出来,我们就得到了函数。
开发者可以自定义函数,预处理器自己也内置了大量的函数。最常用的内置函数应该就是颜色的运算函数了吧!有了它们,我们甚至都不需要打开 Photoshop 来调色,就可以得到某个颜色的同色系变种了。
举个例子,我们要给一个按钮添加鼠标悬停效果,而最简单的悬停效果就是让按钮的颜色加深一些。我们写出的 CSS 代码可能是这样的:
.button {
background-color: #ff4466;
}
.button:hover {
background-color: #f57900;
}
我相信即使是最资深的视觉设计师,也很难分清 #ff4466 和 #f57900 这两种颜色到底有什么关联。而如果我们的代码是用预处理语言来写的,那事情就直观多了:
.button
$color = #ff9833
background-color: KaTeX parse error: Expected 'EOF', got '&' at position 10: color &̲:hover b…color, 20%)
此外,预处理器的函数往往还支持默认参数、具名实参、arguments 对象等高级功能,内部还可以设置条件分支,可以满足复杂的逻辑需求。
7.Mixin
Mixin 是 CSS 预处理器提供的又一项实用功能。Mixin 的形态和用法跟函数十分类似——先定义,然后在需要的地方调用,在调用时可以接受参数。它与函数的不同之处在于,函数用于产生一个值,而 Mixin 的作用是产生一段 CSS 代码。
Mixin 可以产生多条 CSS 规则,也可以只产生一些 CSS 声明。
一般来说,Mixin 可以把 CSS 文件中类似的代码块抽象出来,并给它一个直观的名字。比如 CSS 框架可以把一些常用的代码片断包装为 mixin 备用,在内部按需调用,或暴露给使用者在业务层调用。
举个例子,我们经常会用到 clearfix 来闭合浮动。在原生 CSS 中,如果要避免 clearfix 代码的重复,往往只能先定义好一个 .clearfix 类,然后在 HTML 中挂载到需要的元素身上:
/* 为 clearfix 定义一个类 */
.clearfix {…}
.clearfix::after {…}
// 为 clearfix 定义一个 mixin
clearfix()
…
&::after
…
// 在需要的元素身上调用
.info
clearfix()
footer
clearfix()
8.工程化
CSS 预处理语言无法直接运行于浏览器环境,这意味着我们编写的源码需要编译为 CSS 代码之后才能用于网页。这似乎是一个门槛,需要我们付出 “额外” 的成本。
但在目前的大环境下,大多数项目的前端开发流程已经包含了构建环节,比如选择任何一个脚本模块化方案都是需要在部署时走一道打包程序的。所以对大多数团队来说,这个门槛其实已经跨过去一大半了。
而一旦接受了这种设定,我们还可以享受到 “额外” 的福利。在给 CSS 的开发加入编译环节的同时,还可以顺道加入其它构建环节,比如代码校验、代码压缩、代码后处理等等。
“代码后处理” 是指 PostCSS 平台上各类插件所提供的功能,光是 Autoprefixer 这一项就已经值回票价了。我们再也不需要在 CSS 代码中手工添加浏览器前缀了,直接使用标准写法,剩下的事情让工具搞定吧!
三,less简介及用法
(1)less
less是一种动态样式语言,属于css预处理器的范畴,它扩展了 CSS 语言,
增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展,
LESS 既可以在 客户端 上运行 ,也可以借助Node.js在服务端运行。
less的中文官网:http://lesscss.cn/
bootstrap中less教程:http://www.bootcss.com/p/lesscss/
less在客户端的引入写法:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/03.css"/>
</head>
<body>
<div id="wrap">
<div class="inner">
</div>
</div>
</body>
</html>
如上:①在head元素中引入经过编译后的css文件,href为css文件地址。
(2)Less编译工具
koala 官网:www.koala-app.com
(3)less中的注释
以//开头的注释,不会被编译到css文件中
以/**/包裹的注释会被编译到css文件中
例如:在.less文件中编写
/*这是想暴露出去的注释*/
//这是见不得人的注释
*{
margin: 0;
padding: 0;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height: 100px;
width: 100px;
}
}
通过考拉工具编译成css文件如下:
/*这是想暴露出去的注释*/
* {
margin: 0;
padding: 0;
}
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height: 100px;
width: 100px;
}
(4)less中的变量
使用@来申明一个变量:@pink:pink;
1.作为普通属性值只来使用:直接使用@pink
2.作为选择器和属性名:#@{selector的值}的形式
3.作为URL:@{url}
4.变量的延迟加载
例如:在.less文件中编写
/*这是想暴露出去的注释*/
//这是见不得人的注释
@color:deeppink;
@m:margin;
@selector:#wrap;
*{
@{m}: 0;
padding: 0;
}
@{selector}{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: @color;
height: 100px;
width: 100px;
}
}
编译后的css文件为
/*这是想暴露出去的注释*/
* {
margin: 0;
padding: 0;
}
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ff1493;
height: 100px;
width: 100px;
}
关于变量的延迟加载:在块作用域中延迟加载计算,且块与块间不相干
@var: 0;
.class {
@var: 1;
.brass {
@var: 2;
three: @var;//3
@var: 3;
}
one: @var;
}
编译出来后
.class {
one: 1;
}
.class .brass {
three: 3;
}
在.class 作用域中,变量会延迟加载计算,就是等@var:3读完,才会去加载three:@var;
(5) less中的嵌套规则
1.基本嵌套规则
2.&的使用
&在嵌套中表示两个选择器是平级选择器不是父子的选择器
/*这是想暴露出去的注释*/
//这是见不得人的注释
@color:deeppink;
*{
margin: 0;
padding: 0;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: @color;
height: 100px;
width: 100px;
&:hover{
background: pink;
}
}
}
编译后为
/*这是想暴露出去的注释*/
* {
margin: 0;
padding: 0;
}
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ff1493;
height: 100px;
width: 100px;
}
#wrap .inner:hover {
background: pink;
}
注意如果不加&,在#wrap .inner于:hover会有一个空格存在。
(6) less中的混合
将一系列的规则集引入另一个规则集中(ctrl c+ctrl v)
混合的定义在less规则有明确的指定,使用 . 的形式来定义
1.普通混合
混合类似变量加函数的作用;
.juzhong{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height:100px;
width:100px;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
.juzhong;
}
.inner2{
.juzhong;
}
}
编译后为:
.juzhong{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height:100px;
width:100px;
}
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ffc0cb;
height: 100px;
width: 100px;
}
#wrap .inner2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ffc0cb;
height: 100px;
width: 100px;
}
定义一个混合规则集为 .juzhong(表示#wrap .inner和#wrap .inner2相同的属性和属性值的一个合集),然后在.inner和.inner2中引用这个规则集,编译后得到上面这段css代码。
2.不带输出的混合
.juzhong(){
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height:100px;
width:100px;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
.juzhong();
}
.inner2{
.juzhong();
}
}
编译后的css代码为
在这里插入代码片#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height: 100px;
width: 100px;
}
#wrap .inner2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: pink;
height: 100px;
width: 100px;
}
不带输出的混合比普通混合多了一对括号,括号里的参数是空的,且编译出来的代码比普通混合更将简洁。
3.带参数的混合
.juzhong(@w,@h,@c){
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: @c;
height:@h;
width:@w;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
.juzhong(100px,100px,pink);
}
.inner2{
.juzhong(200px,200px,deeppink);
}
}
编译后的css文件
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ffc0cb;
height: 100px;
width: 100px;
}
#wrap .inner2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ff1493;
height: 200px;
width: 200px;
}
在less文件中编写时,将规则集里的属性设置为变量,再将其作为形参,最后子元素引用。
4.带参数并且有默认值的混合
.juzhong(@w:100px,@h:100px,@c:black){
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: @c;
height:@h;
width:@w;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
.juzhong();
}
.inner2{
.juzhong(200px,200px,deeppink);
}
}
编译后的css文件`
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #000000;
height: 100px;
width: 100px;
}
#wrap .inner2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ff1493;
height: 200px;
width: 200px;
}
在形参中写入默认值,实参中不引用值表示引用默认值
5.带多个参数的混合
带多个参数的混合,同上
6.命名参数
.juzhong(@w:200px,@h:200px,@c:pink){
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: @c;
height: @h;
width: @w;
}
#wrap{
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
.inner{
.juzhong(100px ,100px,pink);
}
.inner2{
.juzhong(@c:black);
}
}
编译后的css文件为
#wrap {
position: relative;
width: 300px;
height: 400px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #ffc0cb;
height: 100px;
width: 100px;
}
#wrap .inner2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: #000000;
height: 10px;
width: 10px;
}
当形参和实参个数不一致时,如上,我们只需要bg这一个参数时,需要在实参中指定这个参数是引用哪个形参的。其余没有使用的形参会引用器默认值
7.匹配模式
想要实现一个可以改变任意朝向的三角形
在html中
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/03.css"/>
</head>
<body>
<div id="wrap">
<div class="sjx"></div>
</div>
</body>
</html>
(1)首先定义一个混合库,其中L,R,T,B表示三角形的朝向即匹配符,而第一个块作用域表示四个朝向三角形的公共属性,通过 @_ 和匹配符相关联。
.triangle(@_,@w,@c){
width: 0px;
height: 0px;
overflow: hidden;
}
.triangle(L,@w,@c){
border-width: @w;
border-style:dashed solid dashed dashed;
border-color:transparent @c transparent transparent ;
}
.triangle(R,@w,@c){
border-width: @w;
border-style:dashed dashed dashed solid;
border-color:transparent transparent transparent @c;
}
.triangle(T,@w,@c){
border-width: @w;
border-style:dashed dashed solid dashed;
border-color:transparent transparent @c transparent ;
}
.triangle(B,@w,@c){
border-width: @w;
border-style:solid dashed dashed dashed;
border-color:@c transparent transparent transparent ;
}
(2)定义一个业务逻辑库,并通过@import引用混合库,引号内为相对路径
@import "./triangle.less";
#wrap .sjx{
.triangle(R,40px,yellow)
}
当我们输入R匹配符时,先调用通过@_关联的公共属性,再去调用下面对应的块作用域。
注意:使用overflow: hidden; 可以解决很多浏览器不兼容的问题
8.arguments变量
arguments是一个实参列表
.border(@w,@style,@c){
border: @arguments;
}
#wrap .sjx{
.border(1px,solid,black)
}
编译后
#wrap .sjx {
border: 1px solid #000000;
}
形参可以命名
(7) less运算
在less中可以进行加减乘除的运算
@rem:100rem;
#wrap .sjx{
width:(100 + @rem)
}
编译后
#wrap .sjx {
width: 200rem;
}
计算中只需要一方带单位即可
(8) less避免编译
不去编译less中的代码,例如算术运算去交给浏览器进行运算
*{
margin: 100 * 10px;
padding: ~"cacl(100px + 100)";
}
css为
* {
margin: 1000px;
padding: cacl(100px + 100);
}
(9) less继承
性能比混合高
灵活度比混合低
在html中
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/extend.css"/>
</head>
<body>
<div id="wrap">
<div class="inner">
inner1
</div>
<div class="inner">
inner2
</div>
</div>
</body>
</html>
定义一个继承库
.juzhong{
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
}
.juzhong:hover{
background: red !important;
}
再定义一个业务逻辑库,引用继承库
*{
margin: 0;
padding: 0;
}
@import "mixin/juzhong-extend.less";
#wrap{
position: relative;
width: 300px;
height: 300px;
border: 1px solid;
margin: 0 auto;
.inner{
&:extend(.juzhong all);
&:nth-child(1){
width: 100px;
height: 100px;
background: pink;
}
&:nth-child(2){
width: 50px;
height: 50px;
background: yellow;
}
}
}
编译后的css文件为
* {
margin: 0;
padding: 0;
}
.juzhong,
#wrap .inner {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
}
.juzhong:hover,
#wrap .inner:hover {
background: red!important;
}
#wrap {
position: relative;
width: 300px;
height: 300px;
border: 1px solid;
margin: 0 auto;
}
#wrap .inner:nth-child(1) {
width: 100px;
height: 100px;
background: pink;
}
#wrap .inner:nth-child(2) {
width: 50px;
height: 50px;
background: yellow;
}
(1)继承跟混合的普通混合类似,没有形参,使用方法可一看到这行 &:extend(.juzhong all);继承的一个extend。如果要使用继承库中定义的所有继承,在extend里加入关键字 all 就可以。
(2)引用继承时一定要注意css选择器的权重。