具有默认值的Sass配置映射

具有默认值的Sass配置映射,sass,compass-sass,Sass,Compass Sass,我正在使用SASS创建css,并希望其他开发人员能够通过更改SASS变量来创建自定义css。当我在我的基本文件中使用如下单个变量时,这可以正常工作: $text-color: #000 !default; 为了测试覆盖,我创建了一个新项目,首先声明变量的覆盖,然后导入“base”sass文件 $text-color: #0074b; @import "base-file"; 但是我也希望使用映射进行配置,但是我无法让覆盖工作。我应该如何使用可以覆盖的配置映射 $colors: (te

我正在使用SASS创建css,并希望其他开发人员能够通过更改SASS变量来创建自定义css。当我在我的基本文件中使用如下单个变量时,这可以正常工作:

$text-color: #000 !default;
为了测试覆盖,我创建了一个新项目,首先声明变量的覆盖,然后导入“base”sass文件

$text-color: #0074b;    
@import "base-file";
但是我也希望使用映射进行配置,但是我无法让覆盖工作。我应该如何使用可以覆盖的配置映射

$colors: (text-color: #000, icon-color: #ccc );
添加!#000之后的默认值给了我一个编译错误:
expected”)”,是“!default”
添加!之后的默认值)不会给出错误,但变量也不会被覆盖


你知道我做错了什么吗?

我认为标准Sass中不存在你想要的功能。我构建了这个函数,但它满足了您的要求:

//A function for filling in a map variable with default values
@function defaultTo($mapVariable: (), $defaultMap){

    //if it's a map, treat each setting in the map seperately
    @if (type-of($defaultMap) == 'map' ){

        $finalParams: $mapVariable;

        // We iterate over each property of the defaultMap
        @each $key, $value in $defaultMap {

            // If the variable map does not have the associative key
            @if (not map-has-key($mapVariable, $key)) {

                // add it to finalParams
                $finalParams: map-merge($finalParams, ($key : $value));

            }
        }

        @return $finalParams;

    //Throw an error message if not a map
    } @else {
        @error 'The defaultTo function only works for Sass maps';
    }
}
用法:

$map: defaultTo($map, (
    key1 : value1,
    key2 : value2
));
然后,如果你有一个混音的东西,你可以这样做:

@mixin someMixin($settings: ()){
    $settings: defaultTo($settings, (
        background: white,
        text: black
    );
    background: map-get($settings, background);
    color: map-get($settings, text);
}

.element {
    @include someMixin((text: blue));
}
输出的CSS:

.element { background: white; color: blue; }
根据你在问题中所说的,你会这样使用它:

$colors: defaultTo($colors, (
    text-color: #000,
    icon-color: #ccc,
));

Bootstrap已通过以下方式解决了此问题:

$grays: () !default;
// stylelint-disable-next-line scss/dollar-variable-default
$grays: map-merge(
  (
    "100": $gray-100,
    "200": $gray-200,
    "300": $gray-300,
    "400": $gray-400,
    "500": $gray-500,
    "600": $gray-600,
    "700": $gray-700,
    "800": $gray-800,
    "900": $gray-900
  ),
  $grays
);

这里不清楚实际发生了什么和您预期会发生什么。变量
$colors
的值为
(文本颜色:#000,图标颜色:#ccc)
。使用
无法覆盖其中的一部分!默认情况下
,您必须覆盖整个内容。谢谢您的清理。那么,如果我创建一个新变量$colors并覆盖它应该工作的所有内容?如果创建一个新变量$colors:(文本颜色:#fff),会发生什么情况;原始地图中的图标颜色会发生什么变化?它会变为null吗?没有指定为映射一部分的任何内容都将不存在。本质上,它将表现为null。太好了,谢谢。然后我理解了这个行为,我应该能够让它正常工作;是的,我知道。如果您没有注意到,我给$settings变量一个默认值,即空列表。这只是显示通常用于更复杂事物的最简单方式。这仍然是获得地图默认功能的最佳方式吗?我走上了添加的路线!默认设置为我的地图的末尾,我认为这会起作用。。在经历了大量的挠头之后,我意识到我所遵循的是错误的,并且浪费了很多时间。使用此技术,您需要添加
$colors:()!违约据我所知,如果您还想处理没有发生覆盖的情况,这仍然是在Sass映射中执行默认值的最佳方法。