zoukankan      html  css  js  c++  java
  • 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%
       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- ' + $screen[$i] + ')')
    
      @media $media
    
          responsive($i)
    
    // =>
    
    body {
    
       1600px;
    
      margin-left: 180px;
    
    }
    
    @media screen and (max- 1920px) {
    
      body {
    
         1600px;
    
        margin-left: 180px;
    
      }
    
    }
    
    // ...
    
    @media screen and (max- 320px) {
    
      body {
    
         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)

     

  • 相关阅读:
    企业命令linux下处理实时日志生成另一个实时日志
    排序算法Java(android)安卓中的list对象排序
    项目设置一个类似HTML map标签功能的Android组件
    最大算法【Manacher模板】HDU 3068——求最长回文子串
    类实现java面向对象上:接口
    线程方法Android:异步调用详解
    输入数字实现分页功能(三层)
    对象主题设计模式读书笔记观察者模式
    网站算法石榴算法严厉打击下 网站盈利方向何在
    闭包执行JavaScript中的闭包
  • 原文地址:https://www.cnblogs.com/lx2331/p/11888284.html
Copyright © 2011-2022 走看看