Skip to content
On this page

Sass 函数与运算

Sass提供了丰富的内置函数和强大的数学运算能力,使您能够动态计算样式值,创建响应式设计,并进行复杂的样式计算。

数学运算

Sass支持基本的数学运算,包括加、减、乘、除和取模。

基本运算

scss
// 数字运算
$base-font-size: 16px;
$multiplier: 1.5;
$calculated-size: $base-font-size * $multiplier; // 24px

.element {
  font-size: $calculated-size;
  margin: 10px + 5px; // 15px
  padding: 20px - 8px; // 12px
  width: 100px / 2; // 50px
  height: 30px % 7px; // 2px
}

// 运算优先级
$calculation: 10px + 5px * 2; // 20px (先乘后加)
$grouped-calculation: (10px + 5px) * 2; // 30px (先加后乘)

单位运算

scss
// 相同单位的运算
$width: 100px + 50px; // 150px
$height: 2em - 0.5em; // 1.5em

// 不同单位的运算(需要兼容的单位)
$converted: 1in + 25.4mm; // 2in (因为1in = 25.4mm)

// 除法运算的特殊性
$half-width: 100px / 2; // 50px
$not-calculation: 100px / 2px; // 50 (无单位)
$division-in-function: calc(100% / 3); // 使用calc()函数

.container {
  width: $half-width;
  // 当除法可能产生歧义时,使用括号
  margin: (100px / 2); // 50px
}

复杂运算

scss
// 复杂的计算示例
$container-width: 1200px;
$gutter: 20px;
$columns: 4;

$column-width: ($container-width - ($gutter * ($columns - 1))) / $columns;

.grid-item {
  width: $column-width;
  margin-right: $gutter;
  
  &:last-child {
    margin-right: 0;
  }
}

// 使用运算创建响应式值
$min-width: 320px;
$max-width: 1200px;
$min-font: 14px;
$max-font: 18px;

.responsive-text {
  font-size: calc(#{$min-font} + (#{$max-font} - #{$min-font}) * ((100vw - #{$min-width}) / (#{$max-width} - #{$min-width})));
}

内置函数

字符串函数

scss
// 字符串连接
$prefix: 'btn';
$modifier: 'primary';
$full-class: #{$prefix}-#{$modifier}; // 'btn-primary'

// to-upper-case 和 to-lower-case
$original: 'Hello World';
$uppercase: to-upper-case($original); // 'HELLO WORLD'
$lowercase: to-lower-case($original); // 'hello world'

// 字符串操作
$font-family: 'Helvetica Neue';
$has-space: str-index($font-family, ' '); // 10 (空格位置)
$substring: str-slice($font-family, 1, 9); // 'Helvetica'

// 选择器生成
$namespace: 'myapp';

.#{$namespace}-button {
  padding: 10px 20px;
  
  @each $size in small, medium, large {
    &--#{$size} {
      padding: if($size == small, 5px 10px, if($size == large, 15px 30px, 10px 20px));
    }
  }
}

数字函数

scss
// 取整函数
$rounded: round(10.7); // 11
$floored: floor(10.7); // 10
$ceiled: ceil(10.1); // 11

// 绝对值
$absolute: abs(-10); // 10

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

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

// 随机数
$random-number: random(); // 0到1之间的随机数
$random-range: random(100); // 1到100之间的随机整数

// 使用数字函数创建动态样式
.grid {
  @for $i from 1 through 12 {
    &.col-#{$i} {
      width: percentage($i / 12);
    }
  }
}

列表函数

scss
// 定义列表
$colors: red, green, blue;
$dimensions: 10px 20px 30px 40px;

// 获取列表长度
$list-length: length($colors); // 3

// 获取特定位置的值
$first-color: nth($colors, 1); // red
$second-dimension: nth($dimensions, 2); // 20px

// 检查列表中是否包含某值
$has-red: list-separator($colors); // 'comma'
$has-green: if(index($colors, green), true, false); // true

// 添加到列表
$new-colors: append($colors, yellow); // red, green, blue, yellow
$joined-list: join($colors, (purple, orange)); // red, green, blue, purple, orange

// 生成网格类
$sizes: (small: 25%, medium: 50%, large: 75%, full: 100%);

@each $name, $size in $sizes {
  .box--#{$name} {
    width: $size;
  }
}

映射函数

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
  )
);

// 获取嵌套映射值
$primary-color: map-get(map-get($theme, colors), primary);
$large-spacing: map-get(map-get($theme, spacing), lg);

// 安全的映射访问函数
@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);

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

颜色函数

颜色操作函数

scss
// 颜色定义
$base-color: #3498db;
$light-color: lighten($base-color, 20%); // 更浅的颜色
$dark-color: darken($base-color, 20%); // 更深的颜色
$saturated: saturate($base-color, 20%); // 更饱和的颜色
$desaturated: desaturate($base-color, 20%); // 不饱和的颜色
$grayscale: grayscale($base-color); // 灰度颜色
$complement: complement($base-color); // 互补色
$invert-color: invert($base-color); // 反转颜色

// 透明度操作
$transparent-color: rgba($base-color, 0.5);
$adjusted-alpha: fade-in(rgba($base-color, 0.3), 0.2); // 0.5
$reduced-alpha: fade-out(rgba($base-color, 0.8), 0.3); // 0.5

// 颜色混合
$mixed-color: mix(#ff0000, #0000ff, 50%); // 紫色 (50% 红 + 50% 蓝)
$weighted-mix: mix(#ff0000, #0000ff, 70%); // 更偏向红色

// 颜色验证函数
$is-light: lightness($base-color) > 50%; // true 或 false
$red-value: red($base-color); // 红色分量值
$green-value: green($base-color); // 绿色分量值
$blue-value: blue($base-color); // 蓝色分量值

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

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

颜色生成函数

scss
// 使用HSL创建颜色
$hue-based: hsl(240, 100%, 50%); // 纯蓝色
$hsl-adjusted: adjust-hue($base-color, 30); // 调整色调

// 生成颜色调色板
@function generate-palette($base-color, $steps: 10) {
  $palette: ();
  
  @for $i from 1 through $steps {
    $lightness: percentage($i / $steps);
    $color: adjust-color($base-color, $lightness: $lightness);
    $palette: map-merge($palette, (#{$i * 10}: $color));
  }
  
  @return $palette;
}

$blue-palette: generate-palette(#007bff);

@each $name, $color in $blue-palette {
  .blue-#{$name} {
    background-color: $color;
  }
}

自定义函数

基本自定义函数

scss
// 创建像素到em的转换函数
@function px-to-em($px, $context: 16px) {
  @return ($px / $context) * 1em;
}

// 创建响应式字体大小函数
@function responsive-size($min-size, $max-size, $min-width: 320px, $max-width: 1200px) {
  @return calc(#{$min-size} + ((#{$max-size} - #{$min-size}) * ((100vw - #{$min-width}) / (#{$max-width} - #{$min-width}))));
}

// 使用自定义函数
.element {
  font-size: px-to-em(18px); // 1.125em
  margin: px-to-em(16px) px-to-em(24px); // 1em 1.5em
  line-height: px-to-em(24px, px-to-em(18px)); // 1.33333em
}

.responsive-text {
  font-size: responsive-size(14px, 18px);
}

高级自定义函数

scss
// 创建黄金比例函数
@function golden-ratio($value, $increment) {
  $phi: 1.618033988749895;
  @return $value * pow($phi, $increment);
}

// 计算函数(需要使用内部函数)
@function pow($number, $exponent) {
  @if $exponent == 0 {
    @return 1;
  }
  
  $value: $number;
  @for $i from 1 to abs($exponent) {
    $value: $value * $number;
  }
  
  @if $exponent < 0 {
    $value: 1 / $value;
  }
  
  @return $value;
}

// 使用黄金比例创建字体层次
$base-font-size: 16px;

h1 { font-size: golden-ratio($base-font-size, 3); } // ~68px
h2 { font-size: golden-ratio($base-font-size, 2); } // ~42px
h3 { font-size: golden-ratio($base-font-size, 1); } // ~26px
h4 { font-size: golden-ratio($base-font-size, 0); } // 16px

// 颜色亮度函数
@function lightness-level($color) {
  $lightness: lightness($color);
  @if $lightness > 70% {
    @return 'light';
  } @else if $lightness > 30% {
    @return 'medium';
  } @else {
    @return 'dark';
  }
}

// 根据颜色亮度返回对比色
@function contrast-color($color) {
  @return if(lightness($color) > 50, #000, #fff);
}

.card {
  background-color: #333;
  color: contrast-color(#333); // #fff
}

.light-card {
  background-color: #f8f9fa;
  color: contrast-color(#f8f9fa); // #000
}

条件函数

if函数

scss
// 简单条件判断
$theme: 'dark';
$text-color: if($theme == 'dark', white, black);

.element {
  color: $text-color;
  background-color: if($theme == 'dark', #333, #fff);
}

// 复杂条件判断
$size: large;
$padding: if($size == 'small', 5px, if($size == 'large', 15px, 10px));

.button {
  padding: $padding;
}

// 使用函数进行样式计算
@function get-border-radius($type) {
  @return if($type == 'pill', 50px, if($type == 'circle', 50%, 4px));
}

.pill-button {
  border-radius: get-border-radius(pill);
}

.circle-button {
  border-radius: get-border-radius(circle);
}

.regular-button {
  border-radius: get-border-radius(default);
}

布尔函数

scss
// 检查值类型
@function is-even($number) {
  @return $number % 2 == 0;
}

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

// 使用布尔函数
.grid {
  @for $i from 1 through 12 {
    &__item:nth-child(#{$i}) {
      @if is-even($i) {
        background-color: #f8f9fa;
      } @else {
        background-color: white;
      }
    }
  }
}

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

实际应用示例

响应式网格系统

scss
// 创建响应式网格函数
@function calculate-column-width($columns, $total-columns: 12) {
  @return percentage($columns / $total-columns);
}

// 媒体查询映射
$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
);

// 生成网格类
@each $name, $value in $breakpoints {
  @if $name == xs {
    @for $i from 1 through 12 {
      .col-#{$name}-#{$i} {
        width: calculate-column-width($i);
      }
    }
  } @else {
    @media (min-width: $value) {
      @for $i from 1 through 12 {
        .col-#{$name}-#{$i} {
          width: calculate-column-width($i);
        }
      }
    }
  }
}

主题系统

scss
// 定义主题函数
@function get-theme-value($theme, $property) {
  $themes: (
    light: (
      bg-color: white,
      text-color: #333,
      border-color: #ddd
    ),
    dark: (
      bg-color: #333,
      text-color: white,
      border-color: #555
    )
  );
  
  @return map-get(map-get($themes, $theme), $property);
}

// 使用主题函数
.light-theme {
  background-color: get-theme-value(light, bg-color);
  color: get-theme-value(light, text-color);
  border: 1px solid get-theme-value(light, border-color);
}

.dark-theme {
  background-color: get-theme-value(dark, bg-color);
  color: get-theme-value(dark, text-color);
  border: 1px solid get-theme-value(dark, border-color);
}

// 主题混合宏
@mixin theme($theme-name) {
  background-color: get-theme-value($theme-name, bg-color);
  color: get-theme-value($theme-name, text-color);
  border: 1px solid get-theme-value($theme-name, border-color);
}

.card {
  &--light {
    @include theme(light);
  }
  
  &--dark {
    @include theme(dark);
  }
}

Sass的函数和运算功能为样式开发提供了强大的动态计算能力,使您可以创建更灵活、可维护和响应式的样式系统。