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