Stylus 插值 #

插值基础 #

插值允许你将变量或表达式的值插入到选择器、属性名或属性值中。

基本语法 #

使用 {} 包裹变量或表达式:

stylus
// 选择器插值
prefix = 'btn'

.{prefix}
  padding 10px 20px

.{prefix}-primary
  background-color #3498db

编译结果:

css
.btn {
  padding: 10px 20px;
}
.btn-primary {
  background-color: #3498db;
}

选择器插值 #

动态选择器 #

stylus
// 动态生成选择器
for i in 1..5
  .col-{i}
    width (i * 20)%

// 使用变量
element = 'header'
.{element}
  position fixed

// 组合选择器
block = 'card'
.{block}
  border 1px solid #ddd
  
  &__header
    padding 15px
    
  &__body
    padding 20px
    
  &--featured
    border-color #3498db

BEM 命名 #

stylus
// BEM 命名模式
block = 'menu'

.{block}
  list-style none
  
  &__item
    display inline-block
    
    &--active
      font-weight bold
      
  &__link
    text-decoration none

状态选择器 #

stylus
// 动态状态选择器
states = hover focus active

for state in states
  .button:{state}
    opacity 0.9

属性插值 #

动态属性名 #

stylus
// 动态属性名
property = 'margin'

.element
  {property} 10px
  {property}-top 20px
  {property}-bottom 20px

// 方向属性
directions = top right bottom left

for dir in directions
  .element
    margin-{dir} 10px
    padding-{dir} 15px

响应式属性 #

stylus
// 响应式属性
breakpoints = {
  sm: 576px,
  md: 768px,
  lg: 992px
}

for name, value in breakpoints
  @media (min-width: value)
    for i in 1..12
      .col-{name}-{i}
        width (i / 12) * 100%

值插值 #

动态属性值 #

stylus
// 动态值
base-url = '/assets/images'

.hero
  background-image url('{base-url}/hero.jpg')

.icon
  background-image url('{base-url}/icon.png')

// 计算值
base = 10px

.element
  padding 'calc(%s + 5px)' % base
  width 'calc(100% - %s)' % (base * 2)

内容插值 #

stylus
// content 属性
icon-check = '\2713'
icon-cross = '\2717'

.success::before
  content icon-check
  color green

.error::before
  content icon-cross
  color red

高级插值 #

选择器函数 #

stylus
// 动态选择器函数
bem(block, element = null, modifier = null)
  selector = '.' + block
  if element
    selector += '__' + element
  if modifier
    selector += '--' + modifier
  return selector

// 使用
{bem('card')}
  border 1px solid #ddd

{bem('card', 'header')}
  padding 15px

{bem('card', null, 'featured')}
  border-color #3498db

属性前缀 #

stylus
// 自动添加前缀
prefixes = webkit moz ms o

prefix(property, value)
  for prefix in prefixes
    -{prefix}-{property} value
  {property} value

// 使用
.element
  prefix('transition', 'all 0.3s ease')
  prefix('transform', 'rotate(45deg)')

编译结果:

css
.element {
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -ms-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;
  transition: all 0.3s ease;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

动态媒体查询 #

stylus
// 动态媒体查询
screens = {
  mobile: 480px,
  tablet: 768px,
  desktop: 1024px
}

for name, width in screens
  $screen-{name}
    = '@media (min-width: %s)' % width

// 使用
.container
  width 100%
  
  @media (min-width: screens.mobile)
    width 90%
    
  @media (min-width: screens.tablet)
    width 80%

复杂选择器生成 #

stylus
// 生成复杂选择器
generate-states(base-class, states)
  for state in states
    {base-class}:{state}
      @extend {base-class}

// 使用
states = hover focus active disabled
generate-states('.button', states)

实用示例 #

1. 主题类生成 #

stylus
// 主题类
themes = {
  light: {
    bg: #fff,
    text: #333,
    primary: #3498db
  },
  dark: {
    bg: #1a1a1a,
    text: #e0e0e0,
    primary: #5dade2
  }
}

for theme-name, colors in themes
  .theme-{theme-name}
    background-color colors.bg
    color colors.text
    
    .button
      background-color colors.primary

2. 工具类生成 #

stylus
// 间距工具类
spacing-properties = {
  m: margin,
  p: padding
}

directions = {
  '': '',
  t: '-top',
  r: '-right',
  b: '-bottom',
  l: '-left',
  x: '-left' '-right',
  y: '-top' '-bottom'
}

sizes = {
  0: 0,
  1: 4px,
  2: 8px,
  3: 12px,
  4: 16px,
  5: 20px,
  6: 24px,
  8: 32px
}

for prefix, property in spacing-properties
  for dir-suffix, dir-values in directions
    for size-suffix, size-value in sizes
      if dir-suffix == ''
        .{prefix}-{size-suffix}
          {property} size-value
      else if dir-suffix == 'x'
        .{prefix}x-{size-suffix}
          {property}-left size-value
          {property}-right size-value
      else if dir-suffix == 'y'
        .{prefix}y-{size-suffix}
          {property}-top size-value
          {property}-bottom size-value
      else
        .{prefix}{dir-suffix}-{size-suffix}
          {property}{dir-values} size-value

3. 组件变体 #

stylus
// 组件变体
component = 'alert'
variants = {
  success: #27ae60,
  warning: #f39c12,
  danger: #e74c3c,
  info: #3498db
}

.{component}
  padding 15px
  border-radius 4px
  
  for name, color in variants
    &--{name}
      background-color color
      color #fff
      
      a
        color lighten(color, 30%)

4. 网格系统 #

stylus
// 响应式网格
breakpoints = {
  '': 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
}

columns = 12

for bp-name, bp-value in breakpoints
  if bp-name == ''
    for i in 1..columns
      .col-{i}
        width (i / columns) * 100%
  else
    @media (min-width: bp-value)
      for i in 1..columns
        .col-{bp-name}-{i}
          width (i / columns) * 100%

5. 图标类 #

stylus
// 图标类
icons = {
  check: '\2713',
  cross: '\2717',
  arrow-right: '\2192',
  arrow-left: '\2190',
  star: '\2605',
  heart: '\2665'
}

for name, code in icons
  .icon-{name}::before
    content code
    font-family inherit

6. 动画关键帧 #

stylus
// 动态关键帧
animations = {
  fadeIn: opacity 0 1,
  fadeOut: opacity 1 0,
  slideIn: transform translateY(-100%) translateY(0),
  zoomIn: transform scale(0.5) scale(1)
}

for name, props in animations
  @keyframes {name}
    from
      {props[0]} props[1]
    to
      {props[0]} props[2]

插值最佳实践 #

1. 保持可读性 #

stylus
// 推荐:清晰的插值
prefix = 'btn'
.{prefix}-primary
  // ...

// 不推荐:过度复杂的插值
.{'btn' + '-' + 'primary'}
  // ...

2. 使用变量存储 #

stylus
// 推荐:使用变量
block-name = 'card'
.{block-name}
  // ...

// 不推荐:硬编码
.card
  // ...

3. 避免过度使用 #

stylus
// 推荐:简单场景直接写
.button
  padding 10px

// 不推荐:简单场景也用插值
name = 'button'
.{name}
  padding 10px

下一步 #

掌握插值后,继续学习 模块化与导入 了解如何组织和管理 Stylus 文件!

最后更新:2026-03-28