Skip to content
On this page

混入

¥Mixins

mixin 和函数都以相同的方式定义,但它们的应用方式不同。

¥Both mixins and functions are defined in the same manner, but they are applied in different ways.

例如,我们在下面定义了一个 border-radius(n) 函数,它作为 mixin 被调用(即作为语句调用,而不是表达式的一部分)。

¥For example, we have a border-radius(n) function defined below, which is invoked as a mixin (i.e., invoked as a statement, rather than part of an expression).

当在选择器内调用 border-radius() 时,属性将展开并复制到选择器中。

¥When border-radius() is invoked within a selector, the properties are expanded and copied into the selector.

border-radius(n)
  -webkit-border-radius n
  -moz-border-radius n
  border-radius n

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

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

编译为:

¥Compiles to:

form input[type=button] {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}
form input[type=button] {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

使用 mixins 时,你可以完全省略括号,从而提供出色的透明浏览器属性支持!

¥When using mixins you can omit the parentheses altogether, providing fantastic transparent vendor property support!

border-radius(n)
  -webkit-border-radius n
  -moz-border-radius n
  border-radius n

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

form input[type=button]
  border-radius 5px

请注意,我们 mixin 中的 border-radius 被视为属性,而不是递归函数调用。

¥Note that the border-radius within our mixin is treated as a property, and not a recursive function invocation.

为了更进一步,我们可以利用自动 arguments 局部变量,包含传递的表达式,允许传递多个值:

¥To take this further, we can utilize the automatic arguments local variable, containing the expression passed, allowing multiple values to be passed:

border-radius()
  -webkit-border-radius arguments
  -moz-border-radius arguments
  border-radius arguments
border-radius()
  -webkit-border-radius arguments
  -moz-border-radius arguments
  border-radius arguments

现在我们可以传递像 border-radius 1px 2px / 3px 4px 这样的值!

¥Now we can pass values like border-radius 1px 2px / 3px 4px!

我们还可以利用 interpolation {param}

¥Also we can make use of the interpolation {param}:

border(side, args...)
  if side
    border-{side}  args
  else
    border args

.border-thick
  border('left' , 10px, 'darkred')

.border
  border('' , 1px, 'darkred')
border(side, args...)
  if side
    border-{side}  args
  else
    border args

.border-thick
  border('left' , 10px, 'darkred')

.border
  border('' , 1px, 'darkred')

渲染:

¥Rendering:

.border-thick {
  border-left: 10px 'darkred';
}
.border {
  border: 1px 'darkred';
}
.border-thick {
  border-left: 10px 'darkred';
}
.border {
  border: 1px 'darkred';
}

这样做的另一个重要用途是增加对特定于浏览器的透明支持,例如对 IE 的 opacity 支持:

¥Another great use of this is the addition of transparent support for vendor-specifics—such as opacity support for IE:

support-for-ie ?= true

opacity(n)
  opacity n
  if support-for-ie
    filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')')

#logo
  &:hover
    opacity 0.5
support-for-ie ?= true

opacity(n)
  opacity n
  if support-for-ie
    filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')')

#logo
  &:hover
    opacity 0.5

渲染:

¥Rendering:

#logo:hover {
  opacity: 0.5;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
}
#logo:hover {
  opacity: 0.5;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
}

父引用

¥Parent References

Mixin 可以利用父引用字符 &,作用于父引用而不是进一步嵌套。

¥Mixins may utilize the parent reference character &, acting on the parent instead of further nesting.

例如,假设我们要创建一个 stripe(even, odd) mixin 用于条带化表行。我们为 evenodd 提供默认颜色值,并在该行上分配 background-color 属性。嵌套在 tr 中,我们使用 & 来引用 tr,提供 even 颜色。

¥For example, let's say we want to create a stripe(even, odd) mixin for striping table rows. We provide both even and odd with default color values, and assign the background-color property on the row. Nested within the tr we use & to reference the tr, providing the even color.

stripe(even = #fff, odd = #eee)
  tr
    background-color odd
    &.even
    &:nth-child(even)
      background-color even
stripe(even = #fff, odd = #eee)
  tr
    background-color odd
    &.even
    &:nth-child(even)
      background-color even

然后我们可以使用 mixin,如下所示:

¥We may then utilize the mixin as shown below:

table
  stripe()
  td
    padding 4px 10px

table#users
  stripe(#303030, #494848)
  td
    color white
table
  stripe()
  td
    padding 4px 10px

table#users
  stripe(#303030, #494848)
  td
    color white

或者,可以在没有父引用的情况下定义 stripe()

¥Alternatively, stripe() could be defined without parent references:

stripe(even = #fff, odd = #eee)
  tr
    background-color odd
  tr.even
  tr:nth-child(even)
    background-color even
stripe(even = #fff, odd = #eee)
  tr
    background-color odd
  tr.even
  tr:nth-child(even)
    background-color even

如果我们愿意,我们可以像调用属性一样调用 stripe()

¥If we wished, we could invoke stripe() as if it were a property:

stripe #fff #000
stripe #fff #000

块混入

¥Block mixins

你可以通过使用 + 前缀调用 mixin 来将块传递给 mixin:

¥You can pass blocks to mixins by calling mixin with + prefix:

+foo()
  width: 10px
+foo()
  width: 10px

传递的块将在 mixin 中作为 block 变量提供,然后可以与插值一起使用:

¥The passed block would be available inside the mixin as block variable, that then could be used with interpolation:

foo()
  .bar
    {block}

+foo()
  width: 10px

=> .bar {
      width: 10px;
    }
foo()
  .bar
    {block}

+foo()
  width: 10px

=> .bar {
      width: 10px;
    }

此功能在 ATM 上处于粗糙状态,但将来会得到增强。

¥This feature is in its rough state ATM, but would be enhanced in the future.

在混入中混合混入

¥Mixing Mixins in Mixins

Mixin 可以(当然!)利用其他 mixin,建立在它们自己的选择器和属性的基础上。

¥Mixins can (of course!) utilize other mixins, building upon their own selectors and properties.

例如,下面我们创建 comma-list() 来内联(通过 inline-list())并用逗号分隔无序列表。

¥For example, below we create comma-list() to inline (via inline-list()) and comma-separate an unordered list.

inline-list()
  li
    display inline

comma-list()
  inline-list()
  li
    &:after
      content ', '
    &:last-child:after
      content ''

ul
  comma-list()
inline-list()
  li
    display inline

comma-list()
  inline-list()
  li
    &:after
      content ', '
    &:last-child:after
      content ''

ul
  comma-list()

渲染:

¥Rendering:

ul li:after {
  content: ", ";
}
ul li:last-child:after {
  content: "";
}
ul li {
  display: inline;
}
ul li:after {
  content: ", ";
}
ul li:last-child:after {
  content: "";
}
ul li {
  display: inline;
}