Andy-set-studio / gorko

A tiny Sass token class generator.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Best way to use css custom properties with gorko?

robdodson opened this issue · comments

I was trying to think of a way to use $gorko-colors to define custom properties. In addition, if someone calls get-color(), I'd like it to return the custom property, instead of the literal color value. This would avoid duplication in the CSS.

For example, if I have --color-light: #fff and some of my code is using that, but elsewhere I use a .bg-light class (that gorko generates) then I'd end up with this in my CSS:

.foo {
  color: var(--color-light) // #fff
}

.bg-light {
  background-color: #fff
}

Very up for this, Rob.

One approach could be to set a flag on $gorko-config for a colour mode. Maybe 'color-mode': 'vars' or something. We could also, like the way colours are defined, set a variable in the config. So $gorko-color-mode: 'vars' maybe.

With either set, the util generator could tweak how it works when a colours map is passed to it and also generate a block of :root custom properties that can be used wherever and whenever the user wants.

With either set, the util generator could tweak how it works when a colours map is passed to it and also generate a block of :root custom properties that can be used wherever and whenever the user wants.

That sounds good. I was wondering if you may also want to do something similar for generating scale variables?

Yeh good shout. var(--size-500) etc would be handy

I recently used Gorko on a project (which was super useful, thanks @hankchizljaw) where I was wanting the colour values to be defined with CSS custom properties. I had an explore into a possible solution for this yesterday. It is very much a work in progress but essentially in the $gorko-config you define a --variables map of the values you wish to be defined as CSS variables. Then you can define a utility in the config to use the CSS variables by defining use-css-variable with the key in the --variables map.

Example config and output
/* config.scss */
$gorko-size-scale: (
  '300': $gorko-base-size * 0.8,
  '400': $gorko-base-size,
  '500': $gorko-base-size * 1.25,
  '600': $gorko-base-size * 1.6,
  '700': $gorko-base-size * 2,
  '900': $gorko-base-size * 3
);

$gorko-colors: (
  'dark': #1a1a1a,
  'light': #f3f3f3
);

$gorko-config: (
  '--variables': (
    'color': $gorko-colors,
    'size': $gorko-size-scale
  ),
  'bg': (
    'items': $gorko-colors,
    'output': 'standard',
    'property': 'background',
    'use-css-variable': 'color'
  ),
  'text': (
    'items': $gorko-size-scale,
    'output': 'responsive',
    'property': 'font-size',
    'use-css-variable': 'size'
  ),
  'breakpoints': (
    'lg': '(min-width: 62em)'
  )
);
/* compiled.css */
:root {
  --color-dark: #1a1a1a;
  --color-light: #f3f3f3;
  --size-300: 0.8rem;
  --size-400: 1rem;
  --size-500: 1.25rem;
  --size-600: 1.6rem;
  --size-700: 2rem;
  --size-900: 3rem;
}

.bg-dark {
  background: var(--color-dark);
}

.bg-light {
  background: var(--color-light);
}

.text-300 {
  font-size: var(--size-300);
}

.text-400 {
  font-size: var(--size-400);
}

.text-500 {
  font-size: var(--size-500);
}

.text-600 {
  font-size: var(--size-600);
}

.text-700 {
  font-size: var(--size-700);
}

.text-900 {
  font-size: var(--size-900);
}

@media screen and (min-width: 62em) {
  .lg\:text-300 {
    font-size: var(--size-300);
  }

  .lg\:text-400 {
    font-size: var(--size-400);
  }

  .lg\:text-500 {
    font-size: var(--size-500);
  }

  .lg\:text-600 {
    font-size: var(--size-600);
  }

  .lg\:text-700 {
    font-size: var(--size-700);
  }

  .lg\:text-900 {
    font-size: var(--size-900);
  }
}

Do you think this is a viable solution?

If using CSS variables, would we want to update the get-color and get-size functions to return the custom property? I like the idea of being able to get the literal value with the functions and get the custom property by defining the CSS variable.

Ah yes I often generate properties like this and for sure, it's a good solution. I think what @robdodson is after though, is a way to reduce repetition, so stuff that uses colour and scale tokens, uses custom properties instead.

I think I am a little lost. In the commit of the possible solution it generates the custom properties from the $gorko-size-scale and $gorko-colors maps. Then you can set a utility that uses colour or scale tokens to use the generated custom properties instead.

Ah sorry, Joel, you're right! I didn't look in enough detail.

I think we've got something as a good base point for a WIP pr maybe? I'm hesitant to update the get-size or get-color functions tbh, unless we make it configurable.

I can neaten it up and open a WIP PR 👍

You could also define your custom properties before the config and use the properties in the $gorko-size-scale and $gorko-colors maps like so:

/* config.scss */
$gorko-base-size: 1rem;

:root {
  --color-dark: #1a1a1a;
  --color-light: #f3f3f3;
  --size-300: #{$gorko-base-size * 0.8};
  --size-400: #{$gorko-base-size};
  --size-500: #{$gorko-base-size * 1.25};
  --size-600: #{$gorko-base-size * 1.6};
  --size-700: #{$gorko-base-size * 2};
  --size-900: #{$gorko-base-size * 3};
}

$gorko-size-scale: (
  '300': var(--size-300),
  '400': var(--size-400),
  '500': var(--size-500),
  '600': var(--size-600),
  '700': var(--size-700),
  '900': var(--size-900)
);

$gorko-colors: (
  'dark': var(--color-dark),
  'light': var(--color-light)
);

This already works with Gorko as is. It is a bit of duplication but has the most flexibility. We could document this example in the readme.md.

Yeh for sure. Having something like your above fork where Gorko generates everything would be ace too. I'm working on something rn where I am generating the Gorko config via external tokens, so the more Gorko can do in that sort of context, the better.

Thanks, Joel! :)

Yeh for sure. Having something like your above fork where Gorko generates everything would be ace too. I'm working on something rn where I am generating the Gorko config via external tokens, so the more Gorko can do in that sort of context, the better.

Thanks, Joel! :)

Is this so we can create design tokens with style dictionary and then create the Gorko config from them?

Essentially, if your design token tool of choice can generate a gorko config, you're good to go!