阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      Stylus 运算符 Operators

      运算符优先级

      下表运算符优先级,从最高到最低:

      []
      ! ~ + -
      is defined
      ** * / %
      + -
      ... ..
      <= >= < >
      in
      == is != is not isnt
      is a
      && and || or
      ?:
      = := ?= += -= *= /= %=
      not
      if unless
      

      一元运算符

      以下一元运算符可用,!, not, -, +, 以及~.

      !0
      // => true
      
      !!0
      // => false
      
      !1
      // => false
      
      !!5px
      // => true
      
      -5px
      // => -5px
      
      --5px
      // => 5px
      
      not true
      // => false
      
      not not true
      // => true
      

      逻辑运算符not的优先级较低,因此,下面这个例子可以替换:

      a = 0
      b = 1
      
      !a and !b
      // => false
      // 解析为: (!a) and (!b)
      

      用:

      not a or b
      // => false
      // 解析为: not (a or b)
      

      二元运算符

      下标运算符[]允许我们通过索引获取表达式内部值。括号表达式可以充当元组(如(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])
      

      范围.. …

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

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

      加减:+ -

      二元加乘运算其单位会转化,或使用默认字面量值。例如,5s - 2px结果是3s.

      15px - 5px
      // => 10px
      
      5 - 2
      // => 3
      
      5in - 50mm
      // => 3.031in
      
      5s - 1000ms
      // => 4s
      
      20mm + 4in
      // => 121.6mm
      
      "foo " + "bar"
      // => "foo bar"
      
      "num " + 15
      // => "num 15"
      

      乘除:/ * %

      2000ms + (1s * 2)
      // => 4000ms
      
      5s / 2
      // => 2.5s
      
      4 % 2
      // => 0
      

      当在属性值内使用/时候,你必须用括号包住。否则/会根据其字面意思处理(支持CSS的line-height)。

      font: 14px/1.5;
      

      但是,下面这个却等同于14px ÷ 1.5:

      font: (14px/1.5);
      

      只有/操作符的时候需要这样。

      指数:**

      指数操作符:

      2 ** 8
      // => 256
      

      相等与关系运算:== != >= <= > <

      相等运算符可以被用来等同单位、颜色、字符串甚至标识符。这是个强大的概念,甚至任意的标识符(例如wahoo)可以作为原子般使用。函数可以返回yesno代替truefalse(虽然不建议)。

      5 == 5
      // => true
      
      10 > 5
      // => true
      
      #fff == #fff
      // => true
      
      true == false
      // => false
      
      wahoo == yay
      // => false
      
      wahoo == wahoo
      // => true
      
      "test" == "test"
      // => true
      
      true is true
      // => true
      
      'hey' is not 'bye'
      // => true
      
      'hey' isnt 'bye'
      // => true
      
      (foo bar) == (foo bar)
      // => true
      
      (1 2 3) == (1 2 3)
      // => true
      
      (1 2 3) == (1 1 3)
      // => false
      

      只有精确值才匹配,例如,0 == falsenull == false均返回false.

      别名:

      ==    is
      !=    is not
      !=    isnt
      

      真与假

      Stylus近乎一切都是true, 包括有后缀的单位,甚至0%, 0px等都被认作true.

      不过,0在算术上本身是false.

      表达式(或“列表”)长度大于1被认为是真。

      true例子:

      0% 
      0px
      1px 
      -1
      -1px
      hey
      'hey'
      (0 0 0)
      ('' '')
      

      false例子:

      0 
      null
      false
      ''
      

      逻辑操作符:&& || 和 or

      逻辑操作符&&||别名是and / or。它们优先级相同。

      5 && 3
      // => 3
      
      0 || 5
      // => 5
      
      0 && 5
      // => 0
      
      #fff is a 'rgba' and 15 is a 'unit'
      // => true
      

      存在操作符:in

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

      简单的例子:

      nums = 1 2 3
      1 in nums
      // => true
      
      5 in nums
      // => false
      

      一些未定义标识符:

      words = foo bar baz
      bar in words
      // => true
      
      HEY in words
      // => false
      

      元组同样适用:

      vals = (error 'one') (error 'two')
      error in vals
      // => false
      
      (error 'one') in vals
      // => true
      
      (error 'two') in vals
      // => true
      
      (error 'something') in vals
      // => false
      

      混合书写适用例子:

      pad(types = padding, n = 5px)
        if padding in types
          padding n
        if margin in types
          margin n
      
      body
        pad()
      
      body
        pad(margin)
      
      body
        pad(padding margin, 10px)
      
      对应于:
      
      body {
        padding: 5px;
      }
      body {
        margin: 5px;
      }
      body {
        padding: 10px;
        margin: 10px;
      }
      

      条件赋值:?= :=

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

      例如,下面这些都是平起平坐的:

      color := white
      color ?= white
      color = color is defined ? color : white
      

      如果我们使用等号=, 就只是简单地赋值。

      color = white
      color = black
      
      color
      // => black
      

      但当使用?=,第二个相当就嗝屁了(因为变量已经定义了):

      color = white
      color ?= black
      
      color
      // => white
      

      实例检查:is a

      Stylus提供一个二元运算符叫做is a, 用做类型检查。

      15 is a 'unit'
      // => true
      
      #fff is a 'rgba'
      // => true
      
      15 is a 'rgba'
      // => false
      

      另外,我们可以使用type()这个内置函数。

      type(#fff) == 'rgba'
      // => true
      

      注意:color是唯一的特殊情况,当左边是RGBA或者HSLA节点时,都为true.

      变量定义:is defined

      此伪二元运算符右边空荡荡,左边无计算。用来检查变量是否已经分配了值。

      foo is defined
      // => false
      
      foo = 15px
      foo is defined
      // => true
      
      #fff is defined
      // => 'invalid "is defined" check on non-variable #fff'
      

      另外,我们可以使用内置lookup(name)方法做这个活动态查找。

      name = 'blue'
      lookup('light-' + name)
      // => null
      
      light-blue = #80e2e9
      lookup('light-' + name)
      // => #80e2e9
      

      该操作符必不可少,因为一个未定义的标识符仍是真值。如:

      body
        if ohnoes
          padding 5px
      

      当未定义的时候,产生的是下面的CSS:

      body {
        padding: 5px;
      }
      

      显然,这不是我们想要的,如下书写就安全了:

      body
        if ohnoes is defined
          padding 5px
      

      三元

      三元运算符的运作正如大部分语言里面的那样。三个操作对象的操作符(条件表达式、真表达式以及假表达式)。

      num = 15
      num ? unit(num, 'px') : 20px
      // => 15px
      

      铸造

      作为替代简洁的内置unit()函数,语法(expr) unit可用来强制后缀。

      body
        n = 5
        foo: (n)em
        foo: (n)%
        foo: (n + 5)%
        foo: (n \* 5)px
        foo: unit(n + 5, '%')
        foo: unit(5 + 180 / 2, deg)
      

      颜色操作

      颜色操作提供了一个简洁,富有表现力的方式来改变其组成。例如,我们可以对每个RGB:

      #0e0 + #0e0
      // => #0f0
      

      另外一个例子是通过增加或减少百分值调整颜色亮度。颜色亮,加;暗,则减。

      #888 + 50%
      // => #c3c3c3
      
      #888 - 50%
      // => #444
      

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

      #f00 + 50deg
      // => #ffd500
      

      值适当固定。例如,我们可以"旋转"180度的色调,如果目前的值是320deg, 将变成140deg.

      我们也可能一次调整几个值(包括alpha),通过使用rgb(), rgba(), hsl(), 或 hsla():

      #f00 - rgba(100,0,0,0.5)
      // => rgba(155,0,0,0.5)
      

      格式化字符串

      格式化字符串模样的字符串%可以用来生成字面量值,通过传参给内置s()方法。

      'X::Microsoft::Crap(%s)' % #fc0
      // => X::Microsoft::Crap(#fc0)
      
      多个值需要括起来:
      
      '-webkit-gradient(%s, %s, %s)' % (linear (0 0) (0 100%))
      // => -webkit-gradient(linear, 0 0, 0 100%)
      
      目录
      目录