SASS: как сгенерировать карту с помощью цикла

#css #loops #sass #sass-maps

#css #циклы #sass #sass-maps

Вопрос:

Моя цель — сгенерировать SASS map для хранения вариантов цветов, которые хранятся на следующей карте:

   $colors : (

    jet                 : #333333,
    wintergreen-dream   : #588C73,
    eton-blue           : #8FC0A9,
    sunglow             : #FFC33C,
    light-kaki          : #F2E394,
    bege                : #FAF3DD

  );
  

Пока что я использую @function для извлечения этих вариантов:

   @function light       ($color, $val) { @return lighten($color, $val);     }
  @function dark        ($color, $val) { @return darken($color, $val);      }
  @function transparent ($color, $val) { @return transparent($color, $val); }
  

Карта, которую я ожидаю, что смогу сгенерировать, будет выглядеть следующим образом:

   $colors-map : (

    eton-blue : (

        base  : $eton-blue,
        light : lighten($eton-blue, 15%),
        dark  : darken($eton-blue, 15%),
        trans : transparent($eton-blue, .5)


    ),

    jet : (

      base  : $jet,
      light : lighten($jet, 15%),
      dark  : darken($jet, 15%),
      trans : transparent($jet, .5)

    )

    // ...

  );
  

Тем не менее, цикл, который я уже пытался применить, выглядит следующим образом:

 @for $key, $value in $colors {}
  

Однако я был наивен, полагая, что это может работать внутри самой карты.

Вопросы, ответы на которые могли бы легче ответить на это сомнение :

  • Как добавить значения к карте SASS (функция), (ключ: значение)?
  • Базовое использование map-merge / map-set ? ( @return map-merge($map, $new) )

Строго то, что я ищу ниже :

 $alternative-colors : (

    @each $color, $hex in $colors {

        #{$color} : (

            light : lighten($color, 25%),
            dark  : darken($color, 25%)

        );

    }

);
  

Но, тем не менее, он возвращает следующую ошибку:

 Error: Invalid CSS after "...tive-colors : (": expected ")", was "@each (...)
  

Заключение

Прошло много времени, и было бы неплохо, если бы я мог поделиться своим решением со всеми остальными.

Я создал репозиторий для хранения результатов решения этой проблемы, https://github.com/vladimirlisovets/SASS-Color-Palettes.

Надеюсь, это будет кому-то полезно либо вдохновит на что-то лучшее.

Приветствия.

Ответ №1:

 $colors : (
  jet                 : #333333,
  wintergreen-dream   : #588C73,
  eton-blue           : #8FC0A9,
  sunglow             : #FFC33C,
  light-kaki          : #F2E394,
  bege                : #FAF3DD
);

$colors-map: ();

@function create_colour_map($color, $percentage, $opacity) {
  $map: (
    base: $color,
    light: lighten($color, $percentage),
    dark: darken($color, $percentage),
    trans: transparentize($color, $opacity)
  );
  @return $map;
}

@each $key, $value in $colors {
  $map: ();
  $map: map-merge($map, ($key: create_colour_map($value, 15%, 0.5)) );
  $colors-map: map-merge($colors-map, $map);
}

@debug $colors-map; //prints out the map below 
  (jet:               (base: #333333, 
                       light: #595959,
                       dark: #0d0d0d,
                       trans: rgba(51, 51, 51, 0.5)), 
   wintergreen-dream: (base: #588C73, 
                       light: #81b099,
                       dark: #3a5d4c,
                       trans: rgba(88, 140, 115, 0.5)),
   eton-blue:          (base: #8FC0A9,
                        light: #c0dccf,
                        dark: #5ea483,
                        trans: rgba(143, 192, 169, 0.5)), 
   sunglow:            (base: #FFC33C,
                        light: #ffdb89,
                        dark: #efa500,
                        trans: rgba(255, 195, 60, 0.5)),
   light-kaki:         (base: #F2E394,
                        light: #faf5d8,
                        dark: #ead150,
                        trans: rgba(242, 227, 148, 0.5)),
   bege:               (base: #FAF3DD,
                        light: white,
                        dark: #f0db9a,
                        trans: rgba(250, 243, 221, 0.5)))
  

Я объединил ваши три функции в одну, create_colour_map функцию. Для colour , percentage и opacity требуется три аргумента. Функция возвращает map

Вызов create_colour_map(#333333, 15%, 0.5) с этими аргументами возвращает map

 (base: #333333, 
 light: #595959,
 dark: #0d0d0d,
 trans: rgba(51, 51, 51, 0.5)
);
  

Я просто перебираю $colors карту и каждый раз вызываю функцию, которая генерирует карту, которая становится значением ключа каждый раз для итерации.

Как добавить значения к карте и базовое использование map-merge?

Я использую map-merge для добавления значений в map . Как следует из названия, он объединяет две карты вместе, и поскольку это функция, ее можно использовать там, где Sass ожидает значение. Итак, возьмем, к примеру, приведенный ниже код

 $map: ( colour: red);
$new_map: (class: blue);
  

Если бы мы хотели $map иметь те же ключи и значения, что и обе карты, мы могли бы написать

 $map: map-merge( $map, $new_map); // $map: (colour: red, class: blue)
  

По сути, это означает, что return значение функции (которая будет представлять собой две карты, соединенные вместе) равно значению $map

Проще говоря, просто подумайте об этой строке кода как о переназначении переменной в языках программирования. Вот как вы можете использовать map-merge для установки значений в картах. 2-й аргумент для map-merge метода не обязательно должен быть предопределенной переменной map. Это можно было бы написать таким образом

 $map: map-merge( $map, (class: blue) );
  

Итак, здесь это просто выглядит так, как будто вы добавляете новое key и value к $map переменной

Комментарии:

1. Замечательно! Это работает так хорошо! Спасибо, я буду работать над этим решением дальше, чтобы я мог создавать цветовые палитры и управлять ими наряду со страницами.

2. Надеюсь, что больше людей с такой же проблемой найдут это решение ^^

3. Всегда пожалуйста. И спасибо за редактирование, я просто случайно пропустил этот момент, когда проводил рефакторинг, чтобы убедиться, что мое соглашение об именовании было разумным 🙂

4. Странно, я использовал похожую логику, и она не работает с map-set , но сработала, когда я изменил ее на map-merge . В документации говорится, что они оба возвращают новую карту, но, похоже, у меня это не сработало. Это может быть просто моя версия node-sass.

Ответ №2:

Просто сделайте это следующим образом.

название цвета и шестнадцатеричная пара:

 $colors: (
  "primary": #404145,
  "secondary": #F5F0F6,
  "yellow": #ecaf2d,
  "green": #5ad864,
  "danger": #B0413E,
  "grey": #808A9F,
  "black": #000F08,
  "white": #ffffff,
);
  

создать mixin (повторно используемый), $attribute — это переменная, по умолчанию значение color. мы можем передать ее значение при вызове этого микширования.

 @mixin bg-mixin($attribute: 'color') { 

  @each $name,
  $hex in $colors {
    amp;-#{$name} {
      #{$attribute}: $hex;
    }
  }
}
  

Используя его для генерации цвета текста и фона.

 .text {
  @include bg-mixin();
}
  

сгенерированные классы будут текстовыми-первичными, текстовыми-вторичными и так далее.

 .bg {
  @include bg-mixin($attribute: 'background-color');
}
  

сгенерированные классы будут bg-primary, bg-secondary и так далее.