语法
unit()
在 sass 中是一个内置函数,用于获取数值的单位。它返回一个字符串,表示数值的单位部分(如 px
、rem
、%
等)。如果数值没有单位,则返回空字符串。
其语法如下:
unit($number)
参数
:$number
是一个数值(带单位或不带单位)。返回值
:数值的单位部分。
作用
获取单位
这是 unit()
最基本的用途,直接返回单位部分字符串。
$width: 100px;
unit($width) // 'px'
用于判断
配合 @if
可以来严格规定单位,使结果符合我们的预期。
例如:我们需要单位为 px
,当传入 rem
单位时,报错。
@mixin set-margin($value) {
@if unit($value) != "px" {
@error "margin 的单位必须为 px, 但是传入了 `#{$value}`。";
} @else {
margin: $value;
}
}
.box {
@include set-margin(20px) // 正确
}
.error-box {
@include set-margin(20rem) // 错误
}
然而在一些页面中,某些内容样式的单位需要使用 px
写死,而其他的一些内容需要使用相对单位,例如 rem
、%
等,我们就利用上述判断的方法,进一步扩展。
@mixin responsive-size($size) {
$unit: unit($size);
@if $unit == "px" {
font-size: $size;
} @else if $unit == "rem" {
font-size: $size;
} @else {
@error "不支持的单位: `#{$unit}`。";
}
}
.text {
@include responsive-size(16px); // 正确
}
.head {
@include responsive-size(2rem); // 正确
}
.error-text {
@include responsive-size(10%); // 错误:不支持的单位: '%'。
}
编译结果
.text {
font-size: 16px;
}
.head {
font-size: 2rem;
}
单位转换
单位转换在实际开发中还是挺常用的,例如将 px
转为 rem
,我们就可以使用 unit()
配合一些运算来完成。
@function px-to-rem($px) {
@if unit($px) != "px" {
@error "字号单位必须为 px, 但是传入了 `#{$value}`。";
}
@return $px / 16 * 1rem;
}
.text {
font-size: px-to-rem(32px);
}
编译后得到
.text {
font-size: 2rem;
}
案例
需求
我们需要开发一个响应式布局系统,要求:
- 支持多种设备类型(如
desktop
、tablet
、mobile
)。 - 每种设备类型使用不同的单位(
px
、rem
、%
)。 - 动态生成不同设备的样式。
- 如果传入的单位不符合要求,抛出错误提示。
实现
根据需求,先定义设备类型。我们使用 sass
中的 map
:
$devices: (
desktop: px,
tablet: rem,
mobile: %
);
接下来,我们再定义一下转换函数并限制单位,将 px
转为 rem
:
@function px-to-rem($px) {
@if unit($px) != "px" {
@error "单位必须为 px,但是传入了 `#{$px}`。";
}
@return $px / 16 * 1rem;
}
然后,定义下 mixin
:
@mixin responsive-layout($property, $value, $device: "desktop") {
// 获取设备对应的单位
$expected-unit: map-get($devices, $device);
// 检查设备类型是否有效
@if not $expected-unit {
@error "非法设备类型: `#{$device}`。";
}
// 获取传入值的单位
$input-unit: unit($value);
// 验证单位是否符合要求
@if $input-unit != $expected-unit {
@error "对于设备 #{$device}, #{$property} 值的单位必须是 #{$expected-unit}, 但是传入了 `#{$value}`。";
}
// 动态生成样式
#{$property}: $value;
}
将定义好的 mixin
使用并验证下:
.container {
@include responsive-layout(padding, 20px, "desktop"); // 正确
@include responsive-layout(margin, 2rem, "tablet"); // 正确
@include responsive-layout(width, 100%, "mobile"); // 正确
}
.error-container {
@include responsive-layout(padding, 10%, "desktop"); // 错误
}
报错如下:
最后,借助 @each
遍历我们定义的设备类型,生成动态样式:
@each $device, $unit in $devices {
.#{$device}-box {
@include responsive-layout(
padding,
if($unit == "px", 20px, if($unit == "rem", 1.5rem, 100%)),
$device
);
}
}
其编译结果如下:
.container {
padding: 20px;
margin: 2rem;
width: 100%;
}
.desktop-box {
padding: 20px;
}
.tablet-box {
padding: 1.5rem;
}
.mobile-box {
padding: 100%;
}
关于 unit()
今天就简单讲这么多,下课!
已收录于 没啥用的CSS小知识!【更新中】