CSS 预处理器 Stylus分享

CSS 预处理器 Stylus分享

ps:为了分享,内容东拼西凑,并非原创,很多参考了 张鑫旭大大翻译的中文文档。这里放上两个不错的stylus链接:

https://github.com/leeseean/stylus-style-guide github stylus语法规范

http://blog.hooperui.com/561-2/  预处理器的作用ect  写的很好。。

一、简介

由于原生css有一些缺陷,

 

一些CSS预处理器应运而生

使用最多的是

变量(variables),代码混合( mixins),嵌套(nested rules)以及 代码模块化(Modules)。

复用,逻辑能力和抽象能力。

Stylus相较于SASS更加简洁,甚至冒号也都可以省略,初学Stylus时感到它太神奇了,仅仅以空格分隔属性名和多个属性值就可以生成想要的CSS,而且还可以拼接字符串等等。与此同时,类似Ruby或Python完善的缩进语法,Stylus在简约自由中有效的防止了语法歧义。

 

 

 

安装

  npm install stylus --save

例子

Stylus由Javascript编译,其结构语句也和Javascript相差不多。Stylus较之LESS则要优越不少,不仅仅是可定义变量,如Javascript般的条件语句和循环语句也为Stylus带来各种可能,加上丰富的内置函数,可以轻松判断和操作各种变量。而利用这样的动态性,就可以写出非常强壮的CSS以满足不同环境和条件下的需要。

 

二、从语法和mixin 混合开始

1、& 指向的是父选择器。

字符&指向父选择器。下面这个例子,我们两个选择器(textareainput):hover伪类选择器上都改变了color

textarea

input

  color #A7A7A7

  &:hover

    color #000

等同于:

textarea,

input {

  color: #a7a7a7;

}

textarea:hover,

input:hover {

  color: #000;

}

2、mixin  混合书写。混入

先来一段官方描述:如果你发现自己在不停地重复一段样式,那就应该把这段样式构造成优良的混合器,尤其是这段样式本身就是一个逻辑单元。再为其添加一个展示性的描述,能够清晰明了的看出它是用来干嘛的。

显然,你首先会想到的是需要各种浏览器厂商前缀的CSS3代码。一个好的事情是,mixin本身不会被编译到css代码中。

混入和函数定义方法一致,但是应用却大相径庭。

例如,下面有定义的border-radius(n)方法,其却作为一个mixin(如,作为状态调用,而非表达式)调用。

当border-radius()选择器中调用时候,属性会被扩展并复制在选择器中。

border-radius(n)
  -webkit-border-radius n
  -moz-border-radius n
  border-radius n
form input[type=button]
  border-radius
(5px)

标红括号可以省略。。

也可以把n替换为 arguments  这样就可以传递多个值

border-radius 1px 2px / 3px 4px

编译成

form input[type=button] {

  -webkit-border-radius: 5px;

  -moz-border-radius: 5px;

  border-radius: 5px;

}

3、而且在调用时,也不一定要使用括号的形式,可以使用CSS的形式,直接Mixin名加空格然后写参数。所以有时候可以直接写一个Mixin来修改CSS属性的功能,比如看看下面这个兼容所有标准浏览器阴影的写法,可以很方便的为标准调用加上各标准浏览器的前缀:

下面这个例子,IE浏览器利用了父级引用以及混合书写来实现2px的边框。

  box-shadow()
    -webkit-box-shadow arguments
    -moz-box-shadow arguments
    box-shadow arguments
    html.ie8 &,
    html.ie7 &,
    html.ie6 &
      border 2px solid arguments[length(arguments) - 1]
  body
    #login
      box-shadow 1px 1px 3px #eee

其变身后面目:

  body #login {
    -webkit-box-shadow: 1px 1px 3px #eee;
    -moz-box-shadow: 1px 1px 3px #eee;
    box-shadow: 1px 1px 3px #eee;
  }
  html.ie8 body #login,
  html.ie7 body #login,
  html.ie6 body #login {
    border: 2px solid #eee;
  }

可以看到调用时的写法与一般的写法一样,但是因为Mixin的存在,box-shadow不再是一个属性,可以变成几行带有各浏览器前缀的CSS。

4、插值

Stylus支持通过使用{}字符包围表达式来插入值,其会变成标识符的一部分。例如,-webkit-{'border' + '-radius'}等同于-webkit-border-radius.

比较好的例子就是私有前缀属性扩展:

vendor(prop, args)

  -webkit-{prop} args

  -moz-{prop} args

  {prop} args

 

border-radius()

  vendor('border-radius', arguments)

 

box-shadow()

  vendor('box-shadow', arguments)

 

button

  border-radius 1px 2px / 3px 4px

变身:

button {

  -webkit-border-radius: 1px 2px / 3px 4px;

  -moz-border-radius: 1px 2px / 3px 4px;

  border-radius: 1px 2px / 3px 4px;

}

不仅仅是box-shadow,CSS3的许多属性都需要添加前缀~

三、响应式支持

1、变量  可以直接指定表达式的值为变量,可以给变量赋多个值可以组成一个表达式列表

你可以使用"$"符号开始。结尾的分号(;)可有可无,但变量名和变量值之间的等号(=)是需要的。不要用@ (不会赋值)

有了变量,我们不需要为了修改一个颜色而输入许多次,也不需要为了修改一个宽度去到找寻找他.(我们只需要修改定义好的变量,修改一次就足够).

font-size = 14px
font = font-size "Lucida Grande", Arial
body
  font font sans-serif

编译为:

body {
  font: 14px "Lucida Grande", Arial sans-serif;
}

2、Stylus有另外一个很酷的独特功能,不需要分配值给变量就可以定义引用属性。下面是个很好的例子,元素水平垂直居中对齐(典型的方法是使用百分比和margin负值),如下:

简单地前置@字符在属性名前来访问该属性名对应的值:

#logo
  position: absolute
  top: 50%
  left: 50%
  width: 150px
  height: 80px
  margin-left: -(@width / 2)
  margin-top: -(@height / 2)

另外使用案例是基于其他属性有条件地定义属性。在下面这个例子中,我们默认指定z-index值为1,但是,只有在z-

index之前未指定的时候才这样:

position()
  position: arguments
  z-index: 1 unless @z-index
#logo
  z-index: 20
  position: absolute

属性会“向上冒泡”查找堆栈直到被发现,或者返回null(如果属性搞不定)。下面这个例子,@color被弄成了blue.(父元素之前定义过的blue。)

3、响应式的例子。关于数组的定义,对于响应式来说有非常好的帮助,因为响应式往往是一系列的尺寸或设备,无论如何,使用数组可以轻松的定义多组对应与索引的配套值。

$screen = 1920px 1280px 1024px 768px 640px 320px

$width = 1600px 1080px 840px 600px 480px 300px

$margin = 180px 100px 80px 40px 20px 0

media()

  join(' and ', arguments)

responsive(p_index)

  body

    width $width[p_index]

    margin-left $margin[p_index]

responsive(0)

for $i in 0 1 2 3 4 5

  $media = media('screen', '(max-width: ' + $screen[$i] + ')')

  @media $media

      responsive($i)

// =>

body {

  width: 1600px;

  margin-left: 180px;

}

@media screen and (max-width: 1920px) {

  body {

    width: 1600px;

    margin-left: 180px;

  }

}

// ...

@media screen and (max-width: 320px) {

  body {

    width: 300px;

    margin-left: 0;

  }

}

当然响应式不是简单的改变尺寸,如果你需要控制某些内容的显示则可以使用一个Boolean的数组来判断是否显示,控制结构或样式则可以字符串的数组来放置一些预先写好的Mixin名称。 

四、模块化管理、易维护

当我们在做中、大型项目的时候,往往一个功能或者模块,会在很多页面都用到,如果我们把它们单独的放到所有页面对应的代码中,那么每次修改,我们都要去改所有的代码段,这显然是低效的,如果将它们放到一个大的公共文件中,有很可能造成冗余,或许,你会说,可以放在一个单独的文件中,然后引入到页面中,就行了,这样是可以,但是会多出来一个文件的请求,如果有多个,那么从维护性和性能两方面考虑的话,就得不偿失了。所以,我们可以使用处理器中的@import规则,把复用代码段提取,然后在需要的页面引入,这样,同样能达到“一处变、处处变”的效果,而且,不会有多余的请求发出,一个页面可以只有一个css文件即可。

在CSS中,并不喜欢用@import来导入样式,因为这样的做法会增加HTTP的请求。但是在CSS预处理器中的导入(@import)规则和CSS的有所不同,它只是在语义上导入不同的文件,但最终结果是生成一个CSS文件。如果你是通过“@import 'file.css'”导入“file.css”样式文件,那效果跟普通CSS导入样式文件一样。注意:导入文件中定义了变量、混合等信息也将会被引入到主样式文件中,因此需要避免他们的相互冲突。

--------------------------------------------------

/* file.{type} */

body {

  background: #EEE;

}

------------------------------------------------

@import "reset.css";

@import "file.{type}";

p {

  background: #0982C1;

}

转译后---------------------------------------------

@import "reset.css";

body {

  background: #EEE;

}

p {

  background: #0982C1;

} 

 

嵌套、继承

如果我们在CSS中多个元素有一个相同的父元素,那么写样式会变得很乏味,我们需要一遍一遍的在每个元素前写这个父元素.

section {

  margin: 10px;

}

section nav {

  height: 25px;

}

section nav a {

  color: #0982C1;

}

section nav a:hover {

  text-decoration: underline;

}

相反,使用CSS预处理器,我们可以在父元素的花括号({})写这些元素。同时可以使用“&”符号来引用父选择器。

section {

  margin: 10px;

  nav {

    height: 25px;

    a {

      color: #0982C1;

      &:hover {

        text-decoration: underline;

      }

    }

  }

}

 

Extend 扩展继承

这可以说是处理器的一个亮点,你定义了一个类,后面如果有另一个类需要用到和已经定义了的类同样的属性和值,那么你可以通过@extend来直接引用已经定义的类,来再次使用它定义过的规则。

这样不会多出来很多重复代码段吗?可能你跟我有过同样的困惑,其实它生成的,是一个群组选择器,也就是多个类共用一段css样式规则,这样做的好处是,在你想定义有共性又有差异的一组元素时,不需要写多个类,只需要写它单独定义的类即可。

在多个元素应用相同的样式时,我们在CSS通常都是这样写:

p,

ul,

ol {

  /* 样式写在这 */

}

这样做非常的好,但往往我们需要给单独元素添加另外的样式,这个时候我们就需要把其中选择器单独出来写样式,这样一回来我们维护样式就相当的麻烦。为了应对这个问题,CSS预处理器可以从一个选择继承另一个选择器下的所有样式。

.block {

  margin: 10px 5px;

  padding: 2px;

}

p {

  @extend .block; /* 继承.block所有样式 */

  border: 1px solid #EEE;

}

ul, ol {

  @extend .block; /* 继承.block所有样式 */

  color: #333;

  text-transform: uppercase;

} 

转译后:

.block, p, ul, ol {

  margin: 10px 5px;

  padding: 2px;

}

p {

  border: 1px solid #EEE;

}

ul, ol {

  color: #333;

  text-transform: uppercase;

} 

 

  

五、图片与色彩的处理

1、切图

对于CSS Sprite相信是所有切图者的主要工作产出,以前我也推荐过一些在线的制作Sprite的工具,不过现在有了Stylus。

 

其中for不同于Javascript,rowList为数组遍历出的一个元素,而$row为索引,可以这样理解 `for [value], [index] in [array]` 。所以可以在两个嵌套的for中获取纵横的位置以及国家代码,来生成CSS。

作为预处理工具,Stylus自然也需要预处理器,不过它不像Sass需要Ruby环境,Stylus由Javascript实现,所以有Javascript就可以处理Stylus。

 

2、颜色操作

如同其他CSS预处理工具一样,Stylus在颜色方面也拥有许多内置函数,无论是判断,提取还是修改都十分强大。函数 `red` , `blue` , `green` , `alpha` 将分别返回颜色对应的rgba值,`dark` 和 `light` 用于判断颜色属于亮色还是暗色,`hue` , `saturation` , `lightness` 则分别返回颜色的色相、饱和度以及亮度,其中色相是在色环上的角度,单位是deg。我经常用的是`lighten` 和 `darken` 这两个函数,其作用是增加或减少一个颜色的亮度,另外还有饱和度的操作函数 `desaturate` 和 `satucate`。

通过增加或减少百分值调整颜色亮度。颜色亮,加;暗,则减

我们也可以通过增加或减去色度调整色调。例如,红色增加65deg就变成了黄色。

六、运算符

1、优先级qwq

下标运算符[]允许我们通过索引获取表达式内部值。括号表达式可以充当元组(如(15px 5px)(1, 2, 3)

下面这个例子使用错误处理的元组(并展示了该结构的多功能性):

add(a, b)
  if a is a 'unit' and b is a 'unit'
    a + b
  else
    (error 'a  b 必须是 units!')

body
  padding add(1,'5')
  // => padding: error "a  b 必须是 units";
 
  padding add(1,'5')[0]
  // => padding: error;
 
  padding add(1,'5')[0] == error
  // => padding: true;
 
  padding add(1,'5')[1]
  // => padding: "a  b 必须是 units";

这儿有个更复杂的例子。现在,我们调用内置的error()函数,当标识符(第一个值)等于error的时候返回错误信息。

if (val = add(1,'5'))[0] == error
  error(val[1])

2、范围.. ...

同时提供包含界线操作符(..)和范围操作符(...),见下表达式:

1..5
// => 1 2 3 4 5
 
1...5
// => 1 2 3 4

3、存在操作符:in

检查左边内容是否在右边的表达式中

nums = 1 2 3

1 in nums

// => true

4、条件赋值:?= :=

条件赋值操作符?=(别名?:)让我们无需破坏旧值(如果存在)定义变量。该操作符可以扩展成三元内is defined的二元操作。

color := white

color ?= white

color = color is defined ? color : white

(Is defined  是 是否分配过了值  qwq)

5、方法

函数  函数内方法 标识符 (内置 unit 都换成了px单位 就可以无视单位了)

add(a, b = a)
  a = unit(a, px)
  b = unit(b, px)
  a + b
 
add(15%, 10deg)
// => 25

 

可能和 属性赋值 混淆 那么加个括号 或者加个return

 swap(a, b)
  return (b a)

 

条件、别名、参数、哈希等等

下面,我们定义get(hash, key)方法,用来返回key值或null. 我们遍历每个键值对,如果键值匹配,返回对应的值。

get(hash, key)

  return pair[1] if pair[0] == key for pair in hash

下面例子可以证明,语言函数模样的Stylus表达式具有更大的灵活性。

hash = (one 1) (two 2) (three 3)

get(hash, two)

// => 2

get(hash, three)

// => 3

get(hash, something)

// => null

七、区别(三者对比

1、变量

 

 2、作用域

  

 3、继承

  • Sass和Stylus的继承非常像,能把一个选择器的所有样式继承到另一个选择器上。使用『@extend』开始,后面接被继承的选择器。

.test{

  margin: 10px5px;

  padding: 2px;

}

p{

  @extend.test;/*继承.block*/

  border: 1pxsolid#aaa;

}

ul,li{

  @extend.test; /*继承.block*/

  color: #aaa;

}

将被编译成标准 css:

.test,p,ul,ol {

  margin: 10px5px;

  padding:2px;

}

p {

  border: 1px solid #aaa

}

ul,li {

  color:#aaa;

}

  • Less 继承:与前两者继承方式有所区别,它不是在选择器上继承,而是将Mixins中的样式嵌套到每个选择器里面。然而这样会带来一个明显的缺点:每个选择器中会出现重复的样式

不管什么原因,如果遇到Stylus搞不定的特殊需求,你可以使用@css使其作为CSS字面量解决之。

Less 的发展有 Bootstrap,Sass 的发展有 Compass 

虽然各种预处理器功能强大,但使用最多的,还是以下特性:

变量(variables),代码混合( mixins),嵌套(nested rules)以及 代码模块化(Modules)。

原生的css  也有变量的  后来出的   常常给用来  切换背景色(主题模式)

它不需要经过任何转译步骤,因为它是浏览器原生支持的 是动态的

它是DOM 的一部分

是  - - 来命名的用两个“-”开头表示声明变量,

如:--white-color: #FFF

用var(...)引用变量值,

如:background: var(--white-color)

 

猜你喜欢

转载自www.cnblogs.com/lx2331/p/11888284.html