Skip to content
On this page

Sass 内置函数库

Sass提供了丰富的内置函数库,涵盖了颜色操作、数值计算、字符串处理、列表操作等多个方面。本章将详细介绍Sass的各种内置函数及其用法。

颜色函数

颜色调节函数

scss
// 颜色定义
$base-color: #3498db;

// 明度调整
$lighter: lighten($base-color, 20%);  // #80c5e6 - 变亮20%
$darker: darken($base-color, 20%);    // #1d689e - 变暗20%

// 饱和度调整
$more-saturated: saturate($base-color, 20%);    // 增加饱和度
$less-saturated: desaturate($base-color, 20%); // 降低饱和度
$grayscale: grayscale($base-color);             // 灰度化

// 透明度调整
$semi-transparent: fade-in(rgba($base-color, 0.3), 0.2); // 增加透明度 -> rgba(#3498db, 0.5)
$more-transparent: fade-out(rgba($base-color, 0.8), 0.3); // 降低透明度 -> rgba(#3498db, 0.5)
$set-alpha: fade(rgba($base-color, 0.7), 0.5); // 设置透明度 -> rgba(#3498db, 0.5)

// 色调调整
$shifted-hue: adjust-hue($base-color, 30deg); // 调整色调30度
$opposite: complement($base-color);           // 互补色

// 颜色反转
$inverted: invert($base-color);               // 颜色反转

// 示例:创建颜色变体
$primary: #007bff;

.color-palette {
  @for $i from 1 through 10 {
    $amount: ($i - 1) * 10;
    &--light-#{$amount} {
      background-color: if($i <= 5, 
        lighten($primary, (6 - $i) * 10%), 
        darken($primary, ($i - 5) * 10%)
      );
    }
  }
}

颜色创建和分解函数

scss
// 颜色创建
$hsl-color: hsl(240, 100%, 50%);           // HSL创建
$hsla-color: hsla(240, 100%, 50%, 0.8);   // HSLA创建
$rgb-color: rgb(52, 152, 219);             // RGB创建
$rgba-color: rgba(52, 152, 219, 0.8);     // RGBA创建

// 颜色分量提取
$red: red(#ff6b6b);           // 255 (红色分量)
$green: green(#ff6b6b);       // 107 (绿色分量)
$blue: blue(#ff6b6b);         // 107 (蓝色分量)
$hue: hue(hsl(240, 100%, 50%));        // 240deg (色调)
$saturation: saturation(hsl(240, 100%, 50%)); // 100% (饱和度)
$lightness: lightness(hsl(240, 100%, 50%));   // 50% (明度)
$alpha: alpha(rgba(255, 0, 0, 0.5));    // 0.5 (透明度)

// 颜色操作
$mixed: mix(#ff0000, #0000ff, 30%);      // 混合颜色,30%红色,70%蓝色
$adjust-red: adjust-color(#ff6b6b, $red: -50); // 调整红色分量
$scale-color: scale-color(#ff6b6b, $lightness: 20%); // 按比例调整明度
$change-color: change-color(#ff6b6b, $hue: 180); // 改变色调

// 颜色验证
$is-light: lightness(#f0f0f0) > 50%;     // true
$is-dark: lightness(#333) < 50%;         // true

// 创建配色方案
@function analogous-colors($color, $angle: 30deg) {
  @return (
    'analogous1': adjust-hue($color, -$angle),
    'analogous2': adjust-hue($color, $angle),
    'triadic1': adjust-hue($color, 120deg),
    'triadic2': adjust-hue($color, 240deg)
  );
}

$base-color: #3498db;
$color-scheme: analogous-colors($base-color);

.analogous-colors {
  .color1 { background-color: map-get($color-scheme, 'analogous1'); }
  .color2 { background-color: map-get($color-scheme, 'analogous2'); }
  .triadic1 { background-color: map-get($color-scheme, 'triadic1'); }
  .triadic2 { background-color: map-get($color-scheme, 'triadic2'); }
}

数值函数

基本数值函数

scss
// 四舍五入函数
$rounded: round(10.7);      // 11
$floored: floor(10.7);      // 10
$ceiled: ceil(10.1);        // 11

// 绝对值
$abs-val: abs(-15);         // 15

// 最大值和最小值
$max-val: max(10, 20, 15); // 20
$min-val: min(10, 20, 15); // 10

// 百分比转换
$ratio: 50px / 100px;       // 0.5
$percent: percentage($ratio); // 50%

// 随机数
$rand-float: random();       // 0到1之间的随机数
$rand-int: random(100);      // 1到100之间的随机整数

// 数值运算示例
$base-font: 16px;
$multiplier: 1.25;
$calculated: $base-font * $multiplier; // 20px

.element {
  font-size: $calculated;
  margin: ($base-font / 2) 0; // 8px 0
}

// 创建动态计算函数
@function fibonacci($n) {
  @if $n <= 1 {
    @return $n;
  }
  @return fibonacci($n - 1) + fibonacci($n - 2);
}

// 黄金比例计算
@function golden-ratio($value, $increment: 1) {
  $phi: 1.618033988749895;
  @return $value * pow($phi, $increment);
}

@function pow($number, $exponent) {
  @if $exponent == 0 { @return 1; }
  $result: $number;
  @for $i from 1 to abs($exponent) {
    $result: $result * $number;
  }
  @if $exponent < 0 { $result: 1 / $result; }
  @return $result;
}

.golden-typography {
  h1 { font-size: golden-ratio(1rem, 3); } // ~4.236rem
  h2 { font-size: golden-ratio(1rem, 2); } // ~2.618rem
  h3 { font-size: golden-ratio(1rem, 1); } // ~1.618rem
  h4 { font-size: golden-ratio(1rem, 0); } // 1rem
}

单位处理函数

scss
// 获取单位
$unit: unit(10px);           // 'px'
$unitless: unitless(10);     // true
$not-unitless: unitless(10px); // false

// 单位转换示例
@function convert-to-rem($px, $base: 16px) {
  @if unitless($px) {
    @warn '#{$px} has no units, assuming pixels.';
    $px: $px * 1px;
  }
  @if unit($px) != 'px' {
    @warn 'Expected pixels, got #{unit($px)}.';
  }
  @return ($px / $base) * 1rem;
}

// 使用单位转换函数
.typography {
  font-size: convert-to-rem(18px);    // 1.125rem
  line-height: convert-to-rem(24px);  // 1.5rem
  margin: convert-to-rem(16px) 0;     // 1rem 0
}

// 单位验证
$dimension: 2em;
$has-unit: not(unitless($dimension)); // true

字符串函数

基本字符串操作

scss
// 字符串拼接和插值
$prefix: 'btn';
$suffix: 'primary';
$full-class: '#{$prefix}-#{$suffix}'; // 'btn-primary'

// 大小写转换
$original: 'Hello World';
$upper: to-upper-case($original); // 'HELLO WORLD'
$lower: to-lower-case($original); // 'hello world'

// 字符串搜索
$search: str-index('Hello World', 'Wor'); // 7 (位置)
$not-found: str-index('Hello World', 'xyz'); // null

// 字符串截取
$slice: str-slice('Hello World', 1, 5); // 'Hello'
$rest: str-slice('Hello World', 7);     // 'World'

// 字符串长度
$length: str-length('Hello'); // 5

// 实际应用示例
@function add-prefix($name, $prefix: 'my') {
  @return '#{$prefix}-#{$name}';
}

$components: ('button', 'input', 'card');

@each $comp in $components {
  .#{add-prefix($comp, 'ui')} {
    padding: 1rem;
    border: 1px solid #ddd;
  }
}

// 生成带前缀的类名
.string-operations {
  $base-class: 'component';
  $modifier: 'active';
  
  &__#{$base-class} {
    background-color: #f8f9fa;
    
    &--#{$modifier} {
      background-color: #007bff;
      color: white;
    }
  }
}

CSS标识符处理

scss
// 引号处理
$quoted: quote('Hello');     // 'Hello' (加上引号)
$unquoted: unquote('.class'); // .class (去掉引号)

// 用于CSS属性或选择器
$property: 'transform';
$value: 'rotate(45deg)';

.element {
  #{$property}: #{$value}; // transform: rotate(45deg);
}

// 动态属性名
@mixin dynamic-property($prop, $value) {
  #{$prop}: $value;
}

.animated {
  @include dynamic-property('animation', 'spin 2s linear infinite');
  @include dynamic-property('transform', 'rotate(45deg)');
}

列表函数

列表创建和访问

scss
// 列表定义
$colors: red, green, blue;                    // 逗号分隔
$dimensions: 10px 20px 30px 40px;           // 空格分隔
$single-item: (single-item,);                // 单元素列表

// 列表长度
$length: length($colors);                     // 3

// 获取特定元素
$first: nth($colors, 1);                     // red
$last: nth($colors, -1);                     // blue

// 检查列表分隔符
$separator: list-separator($colors);         // comma
$space-sep: list-separator($dimensions);     // space

// 列表操作
$extended: append($colors, yellow);          // red, green, blue, yellow
$joined: join($colors, (purple, orange));   // red, green, blue, purple, orange

// 生成网格类
$grid-columns: 1 2 3 4 5 6 7 8 9 10 11 12;

@each $col in $grid-columns {
  .col-#{$col} {
    width: percentage($col / 12);
  }
}

// 响应式网格
$breakpoints: (sm, md, lg, xl);

@each $bp in $breakpoints {
  @each $col in $grid-columns {
    .col-#{$bp}-#{$col} {
      @media (min-width: map-get((sm: 576px, md: 768px, lg: 992px, xl: 1200px), $bp)) {
        width: percentage($col / 12);
      }
    }
  }
}

高级列表操作

scss
// 索引查找
$colors: red, green, blue, green;
$index: index($colors, blue);               // 3
$first-green: index($colors, green);        // 2 (第一个匹配项)

// 列表替换
@function replace-in-list($list, $old, $new) {
  $result: ();
  @for $i from 1 through length($list) {
    $current: nth($list, $i);
    $result: append($result, if($current == $old, $new, $current));
  }
  @return $result;
}

$original: red, blue, green, blue;
$modified: replace-in-list($original, blue, yellow); // red, yellow, green, yellow

// 列表筛选函数
@function filter-list($list, $callback) {
  $result: ();
  @for $i from 1 through length($list) {
    $item: nth($list, $i);
    @if call($callback, $item) {
      $result: append($result, $item);
    }
  }
  @return $result;
}

// 生成按钮变体
$button-types: (primary, secondary, success, danger, warning, info);

@each $type in $button-types {
  .btn-#{$type} {
    @if $type == 'primary' {
      background-color: #007bff;
      border-color: #007bff;
    } @else if $type == 'secondary' {
      background-color: #6c757d;
      border-color: #6c757d;
    } @else if $type == 'success' {
      background-color: #28a745;
      border-color: #28a745;
    } @else if $type == 'danger' {
      background-color: #dc3545;
      border-color: #dc3545;
    } @else if $type == 'warning' {
      background-color: #ffc107;
      border-color: #ffc107;
      color: #212529;
    } @else {
      background-color: #17a2b8;
      border-color: #17a2b8;
    }
    
    color: if(index('warning info', $type), #212529, white);
    
    &:hover {
      @if $type == 'primary' {
        background-color: darken(#007bff, 10%);
        border-color: darken(#007bff, 10%);
      } @else if $type == 'secondary' {
        background-color: darken(#6c757d, 10%);
        border-color: darken(#6c757d, 10%);
      } @else if $type == 'success' {
        background-color: darken(#28a745, 10%);
        border-color: darken(#28a745, 10%);
      } @else if $type == 'danger' {
        background-color: darken(#dc3545, 10%);
        border-color: darken(#dc3545, 10%);
      } @else if $type == 'warning' {
        background-color: darken(#ffc107, 10%);
        border-color: darken(#ffc107, 10%);
      } @else {
        background-color: darken(#17a2b8, 10%);
        border-color: darken(#17a2b8, 10%);
      }
    }
  }
}

映射函数

映射操作

scss
// 映射定义
$theme: (
  colors: (
    primary: #007bff,
    secondary: #6c757d,
    success: #28a745,
    danger: #dc3545
  ),
  spacing: (
    xs: 0.25rem,
    sm: 0.5rem,
    md: 1rem,
    lg: 1.5rem,
    xl: 2rem
  ),
  breakpoints: (
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px
  )
);

// 映射访问
$primary-color: map-get(map-get($theme, colors), primary); // #007bff
$large-spacing: map-get(map-get($theme, spacing), lg);     // 1.5rem

// 安全访问函数
@function safe-get($map, $keys...) {
  @each $key in $keys {
    $map: map-get($map, $key);
    @if $map == null {
      @return null;
    }
  }
  @return $map;
}

$safe-color: safe-get($theme, colors, primary); // #007bff
$missing-color: safe-get($theme, colors, missing); // null

// 映射键和值
$color-keys: map-keys(map-get($theme, colors));   // primary, secondary, success, danger
$color-values: map-values(map-get($theme, colors)); // #007bff, #6c757d, #28a745, #dc3545

// 映射合并
$additional-colors: (
  warning: #ffc107,
  info: #17a2b8
);

$merged-colors: map-merge(map-get($theme, colors), $additional-colors);

// 键存在检查
$has-primary: map-has-key(map-get($theme, colors), primary); // true
$has-missing: map-has-key(map-get($theme, colors), missing); // false

// 遍历映射
@each $name, $color in map-get($theme, colors) {
  .text-#{$name} {
    color: $color;
  }
  
  .bg-#{$name} {
    background-color: $color;
  }
  
  .border-#{$name} {
    border-color: $color;
  }
}

映射实用工具

scss
// 映射转换函数
@function map-reverse($map) {
  $result: ();
  @each $key, $value in $map {
    $result: map-merge($result, ($value: $key));
  }
  @return $result;
}

$color-map: (
  'primary': #007bff,
  'secondary': #6c757d,
  'success': #28a745
);

$reversed: map-reverse($color-map); // (#007bff: 'primary', #6c757d: 'secondary', #28a745: 'success')

// 映射过滤函数
@function map-filter($map, $predicate) {
  $result: ();
  @each $key, $value in $map {
    @if call($predicate, $key, $value) {
      $result: map-merge($result, ($key: $value));
    }
  }
  @return $result;
}

$all-colors: (
  'primary': #007bff,
  'secondary': #6c757d,
  'light': #f8f9fa,
  'dark': #343a40
);

// 只保留暗色
@function is-dark-color($key, $color) {
  @return lightness($color) < 50%;
}

$dark-colors: map-filter($all-colors, is-dark-color); // ('secondary': #6c757d, 'dark': #343a40)

// 生成响应式类
@each $name, $breakpoint in map-get($theme, breakpoints) {
  .hidden-#{$name}-up {
    @media (min-width: $breakpoint) {
      display: none !important;
    }
  }
  
  .visible-#{$name}-up {
    @media (min-width: $breakpoint) {
      display: block !important;
    }
  }
}

类型检查函数

类型检测

scss
// 检查值的类型
@function get-type($value) {
  @return type-of($value);
}

$test-values: (
  'number': 123,
  'string': 'hello',
  'color': #ff0000,
  'bool': true,
  'list': (1, 2, 3),
  'map': (key: value),
  'null': null
);

// 类型检查示例
@each $name, $value in $test-values {
  $type: type-of($value);
  
  .type-#{$name} {
    content: 'Type: #{$type}';
  }
}

// 实用类型检查函数
@function is-number($value) {
  @return type-of($value) == 'number';
}

@function is-string($value) {
  @return type-of($value) == 'string';
}

@function is-color($value) {
  @return type-of($value) == 'color';
}

@function is-list($value) {
  @return type-of($value) == 'list';
}

@function is-map($value) {
  @return type-of($value) == 'map';
}

@function is-boolean($value) {
  @return type-of($value) == 'bool';
}

@function is-null($value) {
  @return type-of($value) == 'null';
}

// 类型安全的计算函数
@function safe-add($a, $b) {
  @if is-number($a) and is-number($b) {
    @return $a + $b;
  } @else {
    @error 'Both arguments must be numbers';
  }
}

// 使用类型检查
$dimension1: 10px;
$dimension2: 20px;

.calculation {
  result: safe-add($dimension1, $dimension2); // 30px
}

综合应用示例

主题系统

scss
// 创建完整的主题系统
$themes: (
  light: (
    colors: (
      primary: #007bff,
      secondary: #6c757d,
      success: #28a745,
      danger: #dc3545,
      background: #ffffff,
      text: #212529,
      border: #dee2e6
    ),
    spacing: (
      xs: 0.25rem,
      sm: 0.5rem,
      md: 1rem,
      lg: 1.5rem,
      xl: 2rem
    )
  ),
  dark: (
    colors: (
      primary: #0d6efd,
      secondary: #6c757d,
      success: #198754,
      danger: #dc3545,
      background: #212529,
      text: #f8f9fa,
      border: #495057
    ),
    spacing: (
      xs: 0.25rem,
      sm: 0.5rem,
      md: 1rem,
      lg: 1.5rem,
      xl: 2rem
    )
  )
);

// 获取主题值的函数
@function theme-get($theme, $category, $key) {
  $theme-map: map-get($themes, $theme);
  $category-map: map-get($theme-map, $category);
  @return map-get($category-map, $key);
}

// 应用主题
@each $theme-name, $theme-config in $themes {
  .theme-#{$theme-name} {
    background-color: theme-get($theme-name, colors, background);
    color: theme-get($theme-name, colors, text);
    border-color: theme-get($theme-name, colors, border);
    
    .card {
      background-color: theme-get($theme-name, colors, background);
      border: 1px solid theme-get($theme-name, colors, border);
      
      .card-header {
        border-bottom: 1px solid theme-get($theme-name, colors, border);
      }
    }
    
    .btn-primary {
      background-color: theme-get($theme-name, colors, primary);
      border-color: theme-get($theme-name, colors, primary);
      color: if(lightness(theme-get($theme-name, colors, primary)) > 50, #212529, #fff);
      
      &:hover {
        background-color: darken(theme-get($theme-name, colors, primary), 10%);
        border-color: darken(theme-get($theme-name, colors, primary), 10%);
      }
    }
  }
}

Sass的内置函数库提供了强大的功能,可以帮助您创建动态、灵活和可维护的样式系统。