无法在SASS中创建动态着色调色板

时间:2018-06-14 12:21:51

标签: css function sass sass-maps

我尝试使用SASS从一组基色动态创建调色板。我之前通过首先定义一组颜色变量,然后创建具有各种阴影的每种基色的地图来手动创建每种基色。然后将每个颜色贴图放入调色板中。

然后返回颜色/阴影我会使用一个函数从调色板图中的颜色图中检索值。

它是如此长时间的啰嗦,更不用说每当我想添加另一种颜色时都会烦恼,所以我想尝试动态地执行此操作但是我似乎在使用变量名创建地图时遇到了一些麻烦,如据我所知。

这是我之前的代码,只是为了让您了解我在做什么:

$color-percent-change: 3%;

$color-blue: hsla(196, 85%, 57%, 1);
$color-brown: hsla(15, 40%, 33%, 1);
$color-charcoal: hsla(0, 0%, 23%, 1);

$blue: (
    'lighten-3': lighten($color-blue, ($color-percent-change * 3)),
    'lighten-2': lighten($color-blue, ($color-percent-change * 2)),
    'lighten-1': lighten($color-blue, ($color-percent-change * 1)),
    'base': $color-blue,
    'darken-1': darken($color-blue, ($color-percent-change * 1)),
    'darken-2': darken($color-blue, ($color-percent-change * 2)),
    'darken-3': darken($color-blue, ($color-percent-change * 3))
);

$brown: (
    'lighten-3': lighten($color-brown, ($color-percent-change * 3)),
    'lighten-2': lighten($color-brown, ($color-percent-change * 2)),
    'lighten-1': lighten($color-brown, ($color-percent-change * 1)),
    'base': $color-brown,
    'darken-1': darken($color-brown, ($color-percent-change * 1)),
    'darken-2': darken($color-brown, ($color-percent-change * 2)),
    'darken-3': darken($color-brown, ($color-percent-change * 3))
);

$charcoal: (
    'lighten-3': lighten($color-charcoal, ($color-percent-change * 3)),
    'lighten-2': lighten($color-charcoal, ($color-percent-change * 2)),
    'lighten-1': lighten($color-charcoal, ($color-percent-change * 1)),
    'base': $color-charcoal,
    'darken-1': darken($color-charcoal, ($color-percent-change * 1)),
    'darken-2': darken($color-charcoal, ($color-percent-change * 2)),
    'darken-3': darken($color-charcoal, ($color-percent-change * 3))
);

$palette: (
    'blue': $blue,
    'brown': $brown,
    'charcoal': $charcoal,
);

@function color($color, $type: 'base') {

    @if map-has-key($palette, $color) {

        $current: map-get($palette, $color);

        @if map-has-key($current, $type) {

            @return map-get($current, $type);

        }
    }

    @warn 'Unknown #{$color} - #{$type} in #{$palette}.';
    @return null;

}

.blue {
    color: color('blue', 'lighten-2');
}

jsfiddle

所以现在我用每个颜色名称/值创建一个颜色贴图,然后循环遍历地图中的每个键并动态创建基色调色板调色板并使用类似的函数返回颜色值,但是我和#39;我收到错误:

argument `$map` of `map-has-key($map, $key)` must be a map

这是新代码:

$color-percent-change: 3%;

$colors: (
    'brand': hsla(265, 35%, 50%, 1),
    'black': hsla(0, 0%, 0%, 1),
    'blue': hsla(196, 85%, 57%, 1),
    'brown': hsla(15, 40%, 33%, 1),
    'charcoal': hsla(0, 0%, 23%, 1),
    'emerald': hsla(140, 52%, 55%, 1),
    'green': hsla(101, 55%, 60%, 1),
    'grey': hsla(0, 0%, 47%, 1),
    'indigo': hsla(225, 57%, 47%, 1),
    'orange': hsla(34, 100%, 53%, 1),
    'pink': hsla(309, 80%, 70%, 1),
    'purple': hsla(285, 67%, 60%, 1),
    'red': hsla(11, 85%, 57%, 1),
    'silver': hsla(0, 0%, 80%, 1),
    'slate': hsla(210, 20%, 33%, 1),
    'teal': hsla(180, 100%, 24%, 1),
    'white': hsla(0, 100%, 100%, 1),
    'yellow': hsla(55, 100%, 57%, 1),
);

@each $name, $color in $colors {
  $name: (
    'lighten-10': lighten($color, ($color-percent-change * 10)),
    'lighten-9': lighten($color, ($color-percent-change * 9)),
    'lighten-8': lighten($color, ($color-percent-change * 8)),
    'lighten-7': lighten($color, ($color-percent-change * 7)),
    'lighten-6': lighten($color, ($color-percent-change * 6)),
    'lighten-5': lighten($color, ($color-percent-change * 5)),
    'lighten-4': lighten($color, ($color-percent-change * 4)),
    'lighten-3': lighten($color, ($color-percent-change * 3)),
    'lighten-2': lighten($color, ($color-percent-change * 2)),
    'lighten-1': lighten($color, ($color-percent-change * 1)),
    'base': $color,
    'darken-1': darken($color, ($color-percent-change * 1)),
    'darken-2': darken($color, ($color-percent-change * 2)),
    'darken-3': darken($color, ($color-percent-change * 3)),
    'darken-4': darken($color, ($color-percent-change * 4)),
    'darken-5': darken($color, ($color-percent-change * 5)),
    'darken-6': darken($color, ($color-percent-change * 6)),
    'darken-7': darken($color, ($color-percent-change * 7)),
    'darken-8': darken($color, ($color-percent-change * 8)),
    'darken-9': darken($color, ($color-percent-change * 9)),
    'darken-10': darken($color, ($color-percent-change * 10))
  );
}

@function color($color, $type: 'base') {
    @if map-has-key($color, $type) {
        @return map-get($color, $type);
    }
    @warn 'Unknown #{$color} - #{$type} in #{$color}.';
    @return null;
}

.red {
    color: color('red', 'lighten-2');
}

jsfiddle

我认为定义@each作为变量名称的$name循环导致问题,因为它没有将其识别为SASS地图?但我不完全确定,通常我的SASS文件非常简单,这是我第一次真正走得更远,而不仅仅是使用简单的变量和函数,所以我可能会遗漏一些东西比较直接的?

1 个答案:

答案 0 :(得分:2)

您需要使用颜色名称作为键映射将生成的颜色列表合并到主列表,而不是通过插值生成变量:

// modification
$color-percent-change: 3%;

// color list definition
$colors: (
    'brand': hsla(265, 35%, 50%, 1),
    'black': hsla(0, 0%, 0%, 1),
    'blue': hsla(196, 85%, 57%, 1),
    'brown': hsla(15, 40%, 33%, 1),
    'charcoal': hsla(0, 0%, 23%, 1),
    'emerald': hsla(140, 52%, 55%, 1),
    'green': hsla(101, 55%, 60%, 1),
    'grey': hsla(0, 0%, 47%, 1),
    'indigo': hsla(225, 57%, 47%, 1),
    'orange': hsla(34, 100%, 53%, 1),
    'pink': hsla(309, 80%, 70%, 1),
    'purple': hsla(285, 67%, 60%, 1),
    'red': hsla(11, 85%, 57%, 1),
    'silver': hsla(0, 0%, 80%, 1),
    'slate': hsla(210, 20%, 33%, 1),
    'teal': hsla(180, 100%, 24%, 1),
    'white': hsla(0, 100%, 100%, 1),
    'yellow': hsla(55, 100%, 57%, 1),
);

// creates a list to store lists of color modifications, with key defined as color name
$colormap: ();

@each $name, $color in $colors {

  // generate the list of colors modifications
  $generated: (
    'lighten-10': lighten($color, ($color-percent-change * 10)),
    'lighten-9': lighten($color, ($color-percent-change * 9)),
    'lighten-8': lighten($color, ($color-percent-change * 8)),
    'lighten-7': lighten($color, ($color-percent-change * 7)),
    'lighten-6': lighten($color, ($color-percent-change * 6)),
    'lighten-5': lighten($color, ($color-percent-change * 5)),
    'lighten-4': lighten($color, ($color-percent-change * 4)),
    'lighten-3': lighten($color, ($color-percent-change * 3)),
    'lighten-2': lighten($color, ($color-percent-change * 2)),
    'lighten-1': lighten($color, ($color-percent-change * 1)),
    'base': $color,
    'darken-1': darken($color, ($color-percent-change * 1)),
    'darken-2': darken($color, ($color-percent-change * 2)),
    'darken-3': darken($color, ($color-percent-change * 3)),
    'darken-4': darken($color, ($color-percent-change * 4)),
    'darken-5': darken($color, ($color-percent-change * 5)),
    'darken-6': darken($color, ($color-percent-change * 6)),
    'darken-7': darken($color, ($color-percent-change * 7)),
    'darken-8': darken($color, ($color-percent-change * 8)),
    'darken-9': darken($color, ($color-percent-change * 9)),
    'darken-10': darken($color, ($color-percent-change * 10))
  );

  // merge the generated color list to the main color list
  $colormap: map-merge($colormap, ($name: $generated));

}

@function color($color, $type: 'base') {

    // Check is the main color exists in the generated list, and if the color modification exist in the specific color list
    @if map-has-key($colormap, $color) && map-has-key(map-get($colormap, $color), $type) {

        // return the specific color
        @return map-get(map-get($colormap, $color), $type);

    }

    // warning
    @warn 'Unknown #{$color} - #{$type} in #{$color}.';

    // return default color
    @return null;

}

// test
.red {
    color: color('red', 'lighten-2');
}

您可以看到工作示例here

希望它有所帮助。