美文网首页
css预处理--stylus,以及遇到的问题

css预处理--stylus,以及遇到的问题

作者: 是一只猫诶 | 来源:发表于2019-08-09 13:51 被阅读0次

    介绍

    stylus跟sass和less一样都是css预处理框架,2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,官网的介绍为:富于表现力、动态的、健壮的 CSS
    因为stylus出现的比较晚,因此它的语法比较新。
    Stylus默认使用 .styl 的作为文件扩展名,支持多样性的CSS语法。

    安装

    $ npm install stylus --save-dev
    $ npm install stylus-loader --save-dev
    

    使用

    <style lang="stylus" scoped>
    </style>
    

    Stylus 特性

    注释

    stylus支持三种注释:

    单行注释 //
    多行注释 /**/ 
    以及多行缓冲注释/*!*/
    

    单行注释在编译之后会被删除,多行注释会被保留,多行缓冲注释相当于告诉Stylus压缩的时候这段无视直接输出。

    选择器

    html
    body
        margin 0
        padding 0
    

    编译之后的css

    html,
    body {
        margin: 0;
        padding: 0;
    }
    

    在stylus中,认为对于元素样式的设置 , {} : ; 是无意义的,因此在stylus中可以不用书写它们。同样因为没有来这些符号,所有空白符,换行,空格以及tab都很重要,写的时候要慎重。

    变量

    stylus是用js写的,因此很多语法跟js很像,比如js定义变量:

     var color = 'red';
    

    stylus中定义变量:

    color = red
    //或者添加标识符 $
    $color =  red
    
    属性查找

    Stylus有另外一个很酷的独特功能,不需要分配值给变量就可以定义引用属性。如下:

     #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(arg)
        position arg
        z-index 1 unless @z-index
    #logo
        z-index 20
        position absolute
    #logo2
        position absolute
    

    属性会“向上冒泡”查找堆栈直到被发现,或者返回null(如果属性搞不定)。下面这个例子,@color最后是blue.

    body
        color red
        ul
            li
                color blue
               a
                   background-color @color
    

    插值

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

    vendor(prop, args)
        -webkit-{prop} args
        -moz-{prop} args
        {prop} args
    border-radius(arg)
        vendor('border-radius', arg)
    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;
    }
    
    选择器插值
    table
        for row in 1 2 3 4 5
            tr:nth-child({row})
                height: 10px * row
    

    编译过后:

    table tr:nth-child(1) {
      height: 10px;
    }
    table tr:nth-child(2) {
      height: 20px;
    }
    table tr:nth-child(3) {
      height: 30px;
    }
    table tr:nth-child(4) {
      height: 40px;
    }
    table tr:nth-child(5) {
      height: 50px;
    }
    

    混合

    stylus中支持混合,语法跟js中定义函数很像,它的作用是用来复制样式或者兼容浏览器
    js中定义函数:

    function 函数名称 ( ) { }
    

    在stylus中定义混合语法:

    混合名称()
        //定义内容
    
    使用混合的三种方式:

    1.混合名称() ,参数集合中可以传递参数,多个参数使用逗号隔开
    2.混合名称 参数 ,多个参数使用逗号隔开
    3.混合名称 参数 ,多个参数使用空格隔开

    混合分类

    1.属性混合
    封装一个属性,用来兼容各个浏览器
    特点:通常以属性名称定义混合,来覆盖原有的属性,兼容浏览器
    2.样式混合
    封装的是多个属性,用来复用样式

    //属性混合
    border-radius(n)
        -webkit-border-radius n
        -moz-border-radius n
        -o-border-radius n
        -ms-border-radius n
        border-radius n
    
    box-shadow(bs1, bs2)
        -webkit-box-shadow bs1, bs2
        -moz-box-shadow bs1, bs2
        -o-box-shadow bs1, bs2
        -ms-box-shadow bs1, bs2
        box-shadow bs1, bs2
    
    form input[type=button]
        border-radius 5px
        box-shadow 2px 4px red, 10px 20px green
    
    //样式混合
    size(w = 300px, h = 200px, color = red)
        width w
        height h
        background color
    div 
        /*第一种*/
        size(500px, 200px , blue)
        /*第二种*/
        size 500px, 200px, blue
        /*第三种*/
        size 500px 200px blue
    

    编译之后

    form input[type=button] {
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        -o-border-radius: 5px;
        -ms-border-radius: 5px;
        border-radius: 5px;
        -webkit-box-shadow: 2px 4px red 10px 20px green;
        -moz-box-shadow: 2px 4px red 10px 20px green;
        -o-box-shadow: 2px 4px red 10px 20px green;
        -ms-box-shadow: 2px 4px red 10px 20px green;
        box-shadow: 2px 4px red 10px 20px green;
    }
    div {
        width: 500px;
        height: 200px;
        background: blue;
    }
    

    注意:
    1.混合的参数集合绝对不能省略
    2.混合名称与参数集合之间绝对不能有空格
    3.如果参数中出现了空格,我们要使用第二种方式

    方法

    函数

    Stylus强大之处就在于其内置的语言函数定义。其定义与混入(mixins)一致;却可以返回值。

    返回值

    很简单的例子,两数值相加的方法:

    add(a, b)
        a + b
    body 
        padding add(10px, 5)
    

    编译之后

    body {
        padding: 15px;
    }
    
    默认参数
    add(a, b = a)
        a + b
    
    add(10, 5)
    // => 15
    
    add(10)
    // => 20
    

    导入 @import

    sylus还可以引入外部的stylus文件


    https://user-gold-cdn.xitu.io/2018/10/22/166979d6d16565e2?imageslim

    动画

    stylus会根据@keyframes自动创建兼容浏览器的样式,但是内容样式如果出现了css3则不会处理,需要使用混合书写的方式进行处理
    举个栗子:

    div
        width 100px
        height 100px
        background red
        animation move 5s
    
    //定义transform混合
    transform(arg...)
        -webkit-transform arg
        -moz--transform arg
        -o--transform arg
        -ms--transform arg
        transform arg
    
    //定义move动画
    @keyframes move
        from 
            margin-left 0
            transform rotate(0)
        to
            margin-left 100%
            transform rotate(360deg)
    

    编译之后:

    div {
        width: 100px;
        height: 100px;
        background: red;
        animation: move 5s;
    }
    @-webkit-keyframes move {
        from {
             margin-left: 0;
             -webkit-transform: rotate(0);
             -moz--transform: rotate(0);
             -o--transform: rotate(0);
             -ms--transform: rotate(0);
             transform: rotate(0);
        }
        to {
            margin-left: 0;
            -webkit-transform: rotate(360deg);
            -moz--transform: rotate(360deg);
            -o--transform: rotate(360deg);
            -ms--transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    @-moz-keyframes move {
        from {
             margin-left: 0;
             -webkit-transform: rotate(0);
             -moz--transform: rotate(0);
             -o--transform: rotate(0);
             -ms--transform: rotate(0);
             transform: rotate(0);
        }
        to {
            margin-left: 0;
            -webkit-transform: rotate(360deg);
            -moz--transform: rotate(360deg);
            -o--transform: rotate(360deg);
            -ms--transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    @-o-keyframes move {
        from {
             margin-left: 0;
             -webkit-transform: rotate(0);
             -moz--transform: rotate(0);
             -o--transform: rotate(0);
             -ms--transform: rotate(0);
             transform: rotate(0);
        }
        to {
            margin-left: 0;
            -webkit-transform: rotate(360deg);
            -moz--transform: rotate(360deg);
            -o--transform: rotate(360deg);
            -ms--transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    @-ms-keyframes move {
        from {
             margin-left: 0;
             -webkit-transform: rotate(0);
             -moz--transform: rotate(0);
             -o--transform: rotate(0);
             -ms--transform: rotate(0);
             transform: rotate(0);
        }
        to {
            margin-left: 0;
            -webkit-transform: rotate(360deg);
            -moz--transform: rotate(360deg);
            -o--transform: rotate(360deg);
            -ms--transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    @keyframes move {
        from {
             margin-left: 0;
             -webkit-transform: rotate(0);
             -moz--transform: rotate(0);
             -o--transform: rotate(0);
             -ms--transform: rotate(0);
             transform: rotate(0);
        }
        to {
            margin-left: 0;
            -webkit-transform: rotate(360deg);
            -moz--transform: rotate(360deg);
            -o--transform: rotate(360deg);
            -ms--transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    

    继承 @extend

    .message 
        padding 10px
        border 1px solid #eee
    .warning 
        @extend .message
        color #E2E21E
    

    编译之后:

    .message,
    .warning {
        padding: 10px;
        border: 1px solid #eee;
    }
    .warning {
        color: #E2E21E;
    }
    
    @extend嵌套选择器
    form
        input[type=text]
            padding 5px
            border 1px solid #eee
            color #ddd
    textarea
        @extends form input[type=text]
        padding 10px
    

    编译之后:

    form input[type=text],
    form textarea {
        padding: 5px;
        border: 1px solid #eee;
        color: #ddd;
    }
    textarea {
        padding: 10px;
    }
    

    CSS字面量

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

    @css {
        .ie-opacity {
            filter: progid:DXImageTransform.Microsoft.Alpha(opacity=25);
            -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=25)";
        }
    }
    

    编译为:

    .ie-opacity {        
        filter: progid:DXImageTransform.Microsoft.Alpha(opacity=25);
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=25)";
    }
    

    字符转义

    Stylus可以字符转码。这可以让字符变成标识符,或是渲染成字面量。注意Stylus中/当作为属性使用的时候需要用括号括起来:

    body
      font 14px/1.4
      font (14px/1.4)
    

    编译为:

    body {
      font: 14px/1.4;
      font: 10px;
    }
    

    问题:在vue cli 3.X如何使用全局的stylus,不需要每个组件里面再引入一次?

    需要在vue.config.js中配置

    // vue.config.js
    const path = require('path')
    
    module.exports = {
      chainWebpack: config => {
        const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
        types.forEach(type => addStyleResource(config.module.rule('stylus').oneOf(type)))
      },
    }
    
    function addStyleResource (rule) {
      rule.use('style-resource')
        .loader('style-resources-loader')
        .options({
          patterns: [
            path.resolve(__dirname, './src/styles/imports.styl'),
          ],
        })
    }
    

    然后在main.js中引入公共样式文件,这样就不需要在组件里面再引入一次公共样式啦
    官网:http://stylus-lang.com/
    参考中文文档:https://www.zhangxinxu.com/jq/stylus/

    相关文章

      网友评论

          本文标题:css预处理--stylus,以及遇到的问题

          本文链接:https://www.haomeiwen.com/subject/gnjsrctx.html