Appearance
运算符
¥Operators
运算符优先级
¥Operator Precedence
下面是运算符优先级表,从高到低:
¥Below is the operator precedence table, highest to lowest:
.
[]
! ~ + -
is defined
** * / %
+ -
... ..
<= >= < >
in
== is != is not isnt
is a
&& and || or
?:
= := ?= += -= *= /= %=
not
if unless
.
[]
! ~ + -
is defined
** * / %
+ -
... ..
<= >= < >
in
== is != is not isnt
is a
&& and || or
?:
= := ?= += -= *= /= %=
not
if unless
一元运算符
¥Unary Operators
可以使用以下一元运算符:!、not、-、+ 和 ~。
¥The following unary operators are available, !, not, -, +, and ~.
!0
// => true
!!0
// => false
!1
// => false
!!5px
// => true
-5px
// => -5px
--5px
// => 5px
not true
// => false
not not true
// => true
!0
// => true
!!0
// => false
!1
// => false
!!5px
// => true
-5px
// => -5px
--5px
// => 5px
not true
// => false
not not true
// => true
逻辑 not 运算符的优先级较低,因此以下示例可以替换为
¥The logical not operator has low precedence, therefore the following example could be replaced with
a = 0
b = 1
!a and !b
// => false
// parsed as: (!a) and (!b)
a = 0
b = 1
!a and !b
// => false
// parsed as: (!a) and (!b)
和:
¥With:
not a or b
// => false
// parsed as: not (a or b)
not a or b
// => false
// parsed as: not (a or b)
二元运算符
¥Binary Operators
下标[]
¥Subscript []
下标运算符允许我们通过索引(从零开始)获取表达式内的值。负索引值从表达式中的最后一个元素开始。
¥The subscript operator allows us to grab a value inside an expression via index (zero-based). Negative index values starts with the last element in the expression.
list = 1 2 3
list[0]
// => 1
list[-1]
// => 3
list = 1 2 3
list[0]
// => 1
list[-1]
// => 3
带括号的表达式可以充当元组(例如 (15px 5px)、(1 2 3))。
¥Parenthesized expressions may act as tuples (e.g. (15px 5px), (1 2 3)).
下面是一个使用元组进行错误处理的示例(并展示了此构造的多功能性):
¥Below is an example that uses tuples for error handling (and showcasing the versatility of this construct):
add(a, b)
  if a is a 'unit' and b is a 'unit'
    a + b
  else
    (error 'a and b must be units!')
body
  padding add(1,'5')
  // => padding: error "a and b must be units";
  
  padding add(1,'5')[0]
  // => padding: error;
  
  padding add(1,'5')[0] == error
  // => padding: true;
  padding add(1,'5')[1]
  // => padding: "a and b must be units";
add(a, b)
  if a is a 'unit' and b is a 'unit'
    a + b
  else
    (error 'a and b must be units!')
body
  padding add(1,'5')
  // => padding: error "a and b must be units";
  
  padding add(1,'5')[0]
  // => padding: error;
  
  padding add(1,'5')[0] == error
  // => padding: true;
  padding add(1,'5')[1]
  // => padding: "a and b must be units";
这是一个更复杂的示例。现在,只要 ident(第一个值)等于 error,我们就会调用内置 error() 函数并返回错误消息。
¥Here's a more complex example. Now we're invoking the built-in error() function with the return error message, whenever the ident (the first value) equals error.
if (val = add(1,'5'))[0] == error
  error(val[1])
if (val = add(1,'5'))[0] == error
  error(val[1])
范围 .....
¥Range .. ...
提供了包含 (..) 和排除 (...) 范围运算符,可扩展为表达式:
¥Both the inclusive (..) and exclusive (...) range operators are provided, expanding to expressions:
1..5
// => 1 2 3 4 5
1...5
// => 1 2 3 4
5..1
// => 5 4 3 2 1
1..5
// => 1 2 3 4 5
1...5
// => 1 2 3 4
5..1
// => 5 4 3 2 1
添加物:* -
¥Additive: + -
乘法和加法二元运算符按预期工作。类型转换应用于单位类型类内,或默认为字面量值。例如,5s - 2px 结果为 3s。
¥Multiplicative and additive binary operators work as expected. Type conversion is applied within unit type classes, or default to the literal value. For example 5s - 2px results in 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"
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"
乘法:/ * %
¥Multiplicative: / * %
2000ms + (1s * 2)
// => 4000ms
5s / 2
// => 2.5s
4 % 2
// => 0
2000ms + (1s * 2)
// => 4000ms
5s / 2
// => 2.5s
4 % 2
// => 0
在属性值中使用 / 时,必须用括号括起来。否则 / 按字面意思理解(以支持 CSS line-height):
¥When using / within a property value, you must wrap with parens. Otherwise the / is taken literally (to support CSS line-height):
font: 14px/1.5;
font: 14px/1.5;
但以下计算为 14px ÷ 1.5:
¥But the following is evaluated as 14px ÷ 1.5:
font: (14px/1.5);
font: (14px/1.5);
仅 / 运算符需要此操作。
¥This is only required for the / operator.
简写运算符:+= -= *= /= %=
¥Shorthand operators: += -= *= /= %=
速记运算符的工作方式与其他通用语言类似。对于列表变量,第一个值将用于执行运算符并覆盖列表以将其转换为单值变量。对于字符串,节点值仅 += 用作附加函数。对于数字类型值,所有运算符的工作方式与普通数学完全相同。颜色值类似。
¥Shorthand operators works like other common language. With list variable, the first value will be use to execute the operators and overwrite the list to turn it to a single-value variable. With string, node values only += works as an appending function. With number type value, all operators work exactly like a normal math. Similar for color value.
n = 12
n += 8
// => n = 20
int-list = 12 23 0 32
int-list %= 2
// => 12 % 2 = 0 (mod operator)
// => int-list = 0
mixed-list = node 23 'str'
mixed-list %= 2
// => error
mixed-list = node 23 'str' #2e7
mixed-list += 2
// => mixed-list = node2
s = 'str'
s += 2
// => s = 'str2'
c = #0e0
c -= #0e0
// => c = #000    
n = 12
n += 8
// => n = 20
int-list = 12 23 0 32
int-list %= 2
// => 12 % 2 = 0 (mod operator)
// => int-list = 0
mixed-list = node 23 'str'
mixed-list %= 2
// => error
mixed-list = node 23 'str' #2e7
mixed-list += 2
// => mixed-list = node2
s = 'str'
s += 2
// => s = 'str2'
c = #0e0
c -= #0e0
// => c = #000    
指数:**
¥Exponent: **
指数运算符:
¥The Exponent operator:
2 ** 8
// => 256
2 ** 8
// => 256
相等与关系:== != >= <= > <
¥Equality & Relational: == != >= <= > <
相等运算符可用于使单位、颜色、字符串甚至标识符相等。这是一个强大的概念,因为甚至任意标识符(例如 wahoo)都可以用作原子。函数可以返回 yes 或 no,而不是 true 或 false(尽管不建议)。
¥Equality operators can be used to equate units, colors, strings, and even identifiers. This is a powerful concept, as even arbitrary identifiers (such as as wahoo) can be utilized as atoms. A function could return yes or no instead of true or false (although not advised).
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
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 == false 和 null == false 都是 false。
¥Only exact values match. For example, 0 == false and null == false are both false.
别名:
¥Aliases:
==    is
!=    is not
!=    isnt
==    is
!=    is not
!=    isnt
真值
¥Truthfulness
Stylus 中的几乎所有内容都解析为 true,包括带有后缀的单元。即使 0%、0px 等也会解析为 true(因为在 Stylus 中,mixin 或函数接受有效单位很常见)。
¥Nearly everything within Stylus resolves to true, including units with a suffix. Even 0%, 0px, etc. will resolve to true (because it's common in Stylus for mixins or functions to accept units as valid).
然而,从算术上来说,0 本身就是 false。
¥However, 0 itself is false in terms of arithmetic.
长度大于 1 的表达式(或 "lists")被认为是真实的。
¥Expressions (or "lists") with a length greater than 1 are considered truthy.
true 示例:
¥true examples:
      0% 
      0px
      1px 
      -1
      -1px
      hey
      'hey'
      (0 0 0)
      ('' '')
      0% 
      0px
      1px 
      -1
      -1px
      hey
      'hey'
      (0 0 0)
      ('' '')
false 示例:
¥false examples:
0 
null
false
''
0 
null
false
''
逻辑运算符:&& || 和或
¥Logical Operators: && || and or
逻辑运算符 && 和 || 被别名为 and / or,它们应用相同的优先级。
¥Logical operators && and || are aliased and / or which apply the same precedence.
5 && 3
// => 3
0 || 5
// => 5
0 && 5
// => 0
#fff is a 'rgba' and 15 is a 'unit'
// => true
5 && 3
// => 3
0 || 5
// => 5
0 && 5
// => 0
#fff is a 'rgba' and 15 is a 'unit'
// => true
存在运算符:in
¥Existence Operator: in
检查右侧表达式中是否存在左侧操作数。
¥Checks for the existence of the left-hand operand within the right-hand expression.
简单的例子:
¥Simple examples:
nums = 1 2 3
1 in nums
// => true
5 in nums
// => false
nums = 1 2 3
1 in nums
// => true
5 in nums
// => false
一些未定义的标识符:
¥Some undefined identifiers:
words = foo bar baz
bar in words
// => true
HEY in words
// => false
words = foo bar baz
bar in words
// => true
HEY in words
// => false
也适用于元组:
¥Works with tuples too:
vals = (error 'one') (error 'two')
error in vals
// => false
(error 'one') in vals
// => true
(error 'two') in vals
// => true
(error 'something') in vals
// => 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
mixin 中的用法示例:
¥Example usage in mixin:
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)
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)
产量:
¥Yielding:
body {
  padding: 5px;
}
body {
  margin: 5px;
}
body {
  padding: 10px;
  margin: 10px;
}
body {
  padding: 5px;
}
body {
  margin: 5px;
}
body {
  padding: 10px;
  margin: 10px;
}
条件赋值:?= :=
¥Conditional Assignment: ?= :=
条件赋值运算符 ?=(别名为 :=)让我们可以在不破坏旧值(如果存在)的情况下定义变量。该运算符扩展为三元内的 is defined 二元运算。
¥The conditional assignment operator ?= (aliased as :=) lets us define variables without clobbering old values (if present). This operator expands to an is defined binary operation within a ternary.
例如,以下内容是等效的:
¥For example, the following are equivalent:
color := white
color ?= white
color = color is defined ? color : white
color := white
color ?= white
color = color is defined ? color : white
当使用普通 = 时,我们只需重新分配:
¥When using plain =, we simply reassign:
color = white
color = black
color
// => black
color = white
color = black
color
// => black
但是当使用 ?= 时,我们的第二次尝试失败了(因为变量已经定义了):
¥But when using ?=, our second attempt fails (since the variable is already defined):
color = white
color ?= black
color
// => white
color = white
color ?= black
color
// => white
实例检查:是一个
¥Instance Check: is a
Stylus 提供了一个名为 is a 的二元运算符用于类型检查。
¥Stylus provides a binary operator named is a used to type check.
15 is a 'unit'
// => true
#fff is a 'rgba'
// => true
15 is a 'rgba'
// => false
15 is a 'unit'
// => true
#fff is a 'rgba'
// => true
15 is a 'rgba'
// => false
或者,我们可以使用 type() BIF:
¥Alternatively, we could use the type() BIF:
type(#fff) == 'rgba'
// => true                                                                            
type(#fff) == 'rgba'
// => true                                                                            
注意:color 是唯一的特殊情况,当左侧操作数是 RGBA 或 HSLA 节点时,计算结果为 true。
¥Note: color is the only special-case, evaluating to true when the left-hand operand is an RGBA or HSLA node.
变量定义:被定义为
¥Variable Definition: is defined
此伪二元运算符不接受右侧运算符,也不计算左侧运算符。这允许我们检查变量是否已分配值。
¥This pseudo binary operator does not accept a right-hand operator, and does not evaluate the left. This allows us to check if a variable has a value assigned to it.
foo is defined
// => false
foo = 15px
foo is defined
// => true
#fff is defined
// => 'invalid "is defined" check on non-variable #fff'
foo is defined
// => false
foo = 15px
foo is defined
// => true
#fff is defined
// => 'invalid "is defined" check on non-variable #fff'
或者,可以使用 lookup(name) 内置函数来执行此操作,或执行动态查找:
¥Alternatively, one can use the lookup(name) built-in function to do this—or to perform dynamic lookups:
name = 'blue'
lookup('light-' + name)
// => null
light-blue = #80e2e9
lookup('light-' + name)
// => #80e2e9
name = 'blue'
lookup('light-' + name)
// => null
light-blue = #80e2e9
lookup('light-' + name)
// => #80e2e9
该运算符至关重要,因为未定义的标识符仍然是真值。例如:
¥This operator is essential, as an undefined identifier is still a truthy value. For example:
body
  if ohnoes
    padding 5px
body
  if ohnoes
    padding 5px
未定义时将产生以下 CSS:
¥Will yield the following CSS when undefined:
body {
  padding: 5px;
}
body {
  padding: 5px;
}
然而,这将是安全的:
¥However this will be safe:
body
  if ohnoes is defined
    padding 5px
body
  if ohnoes is defined
    padding 5px
三元
¥Ternary
三元运算符的工作原理与我们在大多数语言中所期望的一样。它是唯一具有三个操作数(条件表达式、真值表达式和假表达式)的运算符。
¥The ternary operator works as we would expect in most languages. It's the only operator with three operands (the condition expression, the truth expression, and the false expression).
num = 15
num ? unit(num, 'px') : 20px
// => 15px
num = 15
num ? unit(num, 'px') : 20px
// => 15px
抛光
¥Casting
作为 unit() 内置函数的简洁替代方案,语法 (expr) unit 可用于强制后缀。
¥As a terse alternative to the unit() built-in function, the syntax (expr) unit may be used to force the suffix.
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)
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)
颜色操作
¥Color Operations
对颜色的操作提供了一种简洁、富有表现力的方式来改变组件。例如,我们可以对每个 RGB 进行操作:
¥Operations on colors provide a terse, expressive way to alter components. For example, we can operate on each RGB:
#0e0 + #0e0
// => #0f0
#0e0 + #0e0
// => #0f0
另一个例子是通过增加或减少百分比来调整亮度值。要使颜色变浅,请添加;变暗,减去。
¥Another example is adjust the lightness value by adding or subtracting a percentage. To lighten a color, add; to darken, subtract.
#888 + 50%
// => #c3c3c3
#888 - 50%
// => #444
#888 + 50%
// => #c3c3c3
#888 - 50%
// => #444
也可以通过增加或减少度数来调整色调。例如,将 50deg 添加到该红色值会产生黄色:
¥Adjust the hue is also possible by adding or subtracting with degrees. For example, adding 50deg to this red value results in a yellow:
#f00 + 50deg
// => #ffd500
#f00 + 50deg
// => #ffd500
值适当钳位。例如,我们可以将色调 "spin" 180 度,如果当前值为 320deg,则它将解析为 140deg。
¥Values clamp appropriately. For example, we can "spin" the hue 180 degrees, and if the current value is 320deg, it will resolve to 140deg.
我们还可以使用 rgb()、rgba()、hsl() 或 hsla() 一次调整多个值(包括 alpha):
¥We may also tweak several values at once (including the alpha) by using rgb(), rgba(), hsl(), or hsla():
#f00 - rgba(100,0,0,0.5)
// => rgba(155,0,0,0.5)
#f00 - rgba(100,0,0,0.5)
// => rgba(155,0,0,0.5)
Sprintf
类似 sprintf 的字符串运算符 % 可用于生成字面量值,通过 s() 内置函数在内部传递参数:
¥The string sprintf-like operator % can be used to generate a literal value, internally passing arguments through the s() built-in:
'X::Microsoft::Crap(%s)' % #fc0
// => X::Microsoft::Crap(#fc0)
'X::Microsoft::Crap(%s)' % #fc0
// => X::Microsoft::Crap(#fc0)
多个值应加括号:
¥Multiple values should be parenthesized:
'-webkit-gradient(%s, %s, %s)' % (linear (0 0) (0 100%))
// => -webkit-gradient(linear, 0 0, 0 100%)
'-webkit-gradient(%s, %s, %s)' % (linear (0 0) (0 100%))
// => -webkit-gradient(linear, 0 0, 0 100%)