Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Take this one step further and build the color palette into your stylesheets. If you're using Sass you can setup something like:

    $palettes: (
      blue: (
        lightest: hsl(201, 75%, 66%),
        lighter:  hsl(201, 75%, 61%),
        light:    hsl(201, 75%, 56%),
        base:     hsl(201, 75%, 51%),
        dark:     hsl(201, 75%, 46%),
        darker:   hsl(201, 75%, 41%),
        darkest:  hsl(201, 75%, 36%)
      ),
      red: (...),
      gray: (...)
    )

    @function palette($palette, $tone: 'base') {
      @return map-get(map-get($palettes, $palette), $tone);
    }
This ends up looking like: `background-color: palette(blue, "light")` in your codebase.

I typically use hsl instead of hex codes because it is easier to understand and modify. You can quickly build up a palette by just modifying the lightness scale on each color by a constant percentage. (This is where I disagree with the author, all of design is just math)

It is often useful to combine colors for your designs and Sass has you covered with the `mix` function. Using this setup you can call `mix(palette(blue), palette(gray))` to combine colors in your palette. You typically want to do this with text on a colored background to make it look more visually appealing.

This is the only way I've found to stay sane managing your colors in a big project. In my experience, everything else goes off the rails when you introduce multiple people into the picture. Please steal this idea, your projects will be better because of it.



> I typically use hsl instead of hex codes because it is easier to understand and modify. You can quickly build up a palette by just modifying the lightness scale on each color by a constant percentage. (This is where I disagree with the author, all of design is just math)

Unfortunately, the “math” of color models like HSL is only very loosely related to the science of human color perception. It was a model developed by computer graphics researchers of the 1970s who were not very knowledgeable about 20th century color science and dealing with very limited hardware capabilities compared to today, roughly based on outdated ideas from the 17th–19th century... and frankly not very well designed even within those constraints. As a result, leaning too heavily on HSL (especially for novices) typically leads to garbage results. An experienced artist picking colors visually will do much better than someone largely relying on HSL numbers.

If you want to pick colors based on numbers, look up the Munsell color system (a big lookup table from the early 20th century; the “modern” version was developed by the leading American color scientists of the 1940s), CIELAB (from the 1970s, an inferior but based-on-a-simple-formula Munsell clone), or CIECAM or IPT models (more recent and more complicated formulas).


But let's not throw away the baby with the bath water...

A huge value of HSL is being able to verify that you're keeping hue constant. Or, to change hue everywhere slightly (when you decide you want a 214 blue instead of 217).

The second value of HSL is that it's easy to look at a code and understand its brightness and saturation semantically.

But I agree that you absolutely need to manually pick appropriate lightness and saturation values to match what you want perceptually, and that changing lightness often requires changing saturation as well.


If you want to be able to control hue still, you can use CIE LCH which is comparable to HSL but better matches our colour perception.


Yes, LCH is easier to use for picking colors than other CIELAB color spaces. To try an LCH color picker, you can use http://davidjohnstone.net/pages/lch-lab-colour-gradient-pick... (as linked in another comment).

You can also use the better-implemented color picker for the HSLuv color space at http://www.hsluv.org/. HSLuv is just like LCH except that it stretches the saturated colors for each hue so that any saturation coordinate represents a valid color, unlike LCH’s chroma coordinate. The downside is that the color’s chroma (colorfulness) can change when you drag the hue slider.


> HSLuv is just like LCH

To be clear, HSLuv, is based on CIELCHuv, the cylindrical transformation of CIELUV [0]; the LCH in David Johnstone's colour picker is CIELCHab, the cylindrical transformation of CIELAB [1].

Of course, that doesn't contradict your comment about the pros and cons of HSLuv's "saturation" component.

[0] https://en.wikipedia.org/wiki/CIELUV

[1] https://en.wikipedia.org/wiki/CIELAB_color_space


“LCH” is just the same as CIELAB, but in polar coordinates.

Prefer CIELAB to CIELUV for this type of use.


Having someone on your team that understands and values this stuff is Priceless to anyone building a user friendly product.


I think it still has some value. A few years ago I was building my color palette, and discovered through trial and error that if I keep saturation and luminosity constant, and just change hue to cover the color space, I get a pretty good looking set of colors. I'm not sure if there's science behind it, but it works in practice, at least for me.


Can you point me to any resources where I can learn more?


More than you ever wanted to know, in one well-illustrated blog post: http://jamie-wong.com/post/color/


That's awesome. It makes me think, though, that we could do a lot better than RGB given accurate values for actual human cone sensitivity and better subpixel colors. We should be able to get a digital gamut that fully spans the visible spectrum.


Yes we could get much better results with more primaries in our displays. It would take some fancier digital signal processing, and more importantly would only be especially useful for images designed with the wider gamut in mind (or potentially even multispectral images), but is possible using current technology, and probably not impossibly expensive.

Personally I would love to see displays made grids of hexagonal pixels, and maybe 7 primaries. Since almost every image that goes to displays today already needs to be rescaled at runtime, the processing shouldn’t need to be impossibly much more expensive than current square-grid resampling.

I would also love to see digital camera sensors with more primaries in a better pixel arrangement.


7 seems like overkill, but ok. :D Is that helpful for being able to display the full gamut of visible color more than 4 primaries, or even just 3 that are closer aligned to our eyes?


I picked 7 because it works nicely with hexagonal pixels. :-)

But the primaries can be relatively close together in color. It’s fine if we have e.g. 2 reds, 2 blues, and 3 greens instead of 1 of each.

Or for an LCD, some of them could be broader-spectrum primaries which were brighter but less colorful, while others could be more intense narrow-spectrum primaries. This would make the display more color accurate for various observers (more robust against “observer metamerism”), and would make the display overall brighter for the same intensity of backlight.

Or I dunno.. I’m not an expert in display technology, I’m sure the engineers could come up with many ideas.


http://davidjohnstone.net/pages/lch-lab-colour-gradient-pick...

You could learn more, or just use Lch! The colours you can pull out of this tool are amazing.


Pick up any color science book from the last 50 years (you should hopefully be able to find a few at any medium-sized public library).

If you want an online resource, try https://www.handprint.com/LS/CVS/color.html


This is an interesting idea. Seems like a good practice in larger projects though. I like your choice in words, lightest, lighter, light, base, dark, darker, darkest. Its the same naming convention as tailwinds, minus the word "base".

Is the word "pallete" really necessary? Why not just organize it like this instead?

  // Colors
  $blue-lightest: hsl(201, 75%, 66%);
  $blue-lighter:  hsl(201, 75%, 61%);
  $blue-light:    hsl(201, 75%, 56%);
  $blue           hsl(201, 75%, 51%);
  $blue-dark      hsl(201, 75%, 46%);
  $blue-darker    hsl(201, 75%, 41%);
  $blue-darkest   hsl(201, 75%, 36%);
and

  body {
    background-color: mix($red,$purple-light);
    color: $blue-dark;
  }
I am surprised the author did not mention HSL code anywhere, especially in the section about creating shades. I use HSL for everything, it should be standard practice.


The palette does two jobs. First, it makes sure you don't overwrite yourself somewhere else in the codebase. It also helps you easily see where someone has goofed since they aren't using the palette when defining a color. You could write everything that way, but you have to spend more effort maintaining the project.


Okay good point

If it's a solo project I would probably just stick to what I wrote, but for larger projects I see the benefits. Since someone might define another $color-variable elsewhere


I made something like that for myself before SASS etc. were a thing, and it's been working so great for me that I keep using it, even though it's kinda derpy. First, I have a bunch of vars, such as

    hue9, top_bg_sat, top_bg1_lum, top_bg2_lum
Only those get changed when making new color schemes, and the colors are made up from them like so:

    hsl top bg1: [hsl hue9 [float top_bg_sat] [float top_bg1_lum]]
    hsl top bg2: [hsl hue9 [float top_bg_sat] [float top_bg2_lum]]
Those colors in I use in the CSS so they can get replaced by the final HSLA color:

    background:	<:top bg1>;
    background:	linear-gradient(to bottom, <:top bg1 l/1.125> 0%, <:top bg1> 10%, <:top bg2> 90%, <:top bg2 l*1.125> 100%);
allowing modifiers, such e.g. "use this color, but with luminance divided by 1.125".

I would look into options before rolling my own again, but even rolling my own made my life so much easier, so quickly, I would still recommend it just because it's fun.


> background-color: palette(blue, "light")

Having never used Sass, this syntax strikes me as odd.

Is there a CSS pre-processor similar to Sass but where you would instead write it as “background-color: palette.blue.light”?


You can use CSS variables, no preprocessor necessary for newer browsers:

  :root {
    --palette-blue-light: blue;
  }
  background-color: var(--palette-blue-light);


Great suggestion, but due to extremely poor support [0], it might be best to use a polyfill [1]

[0] https://caniuse.com/#feat=css-variables [1] https://github.com/aaronbarker/css-variables-polyfill (or https://github.com/jhildenbiddle/css-vars-ponyfill)

Personally, I don't like forcing JS to make things render properly on the client, but it depends on the project whether it's acceptable or not.

However, it kind of defeats the purpose, because if you're willing to use a polyfill, then you may as well use sass or less as a solution anyway (and get a range of benefits that they provide).


I haven't used it in a number of years, but Stylus apparently lets you access hashes[0] using dots:

  palette = {
    blue: {
      light: hsl(201, 75%, 56%)
      base: hsl(201, 75%, 51%)
      dark: hsl(201, 75%, 46%)
    }
  }
  
  palette.blue.light
  // => hsl(201, 75%, 56%)
It was a fun preprocessor, even if you could go overboard with it (for instance, dropping colons). I used it in a few node projects, but didn't do much beyond that because it never really took off like Sass. Sass is, well, everywhere. Stylus, on the other hand, appears to be either dead or close enough to it. While I've got a list of issues with Sass--mainly because I prefer the SASS syntax over SCSS--none of them are dealbreakers.

0. http://stylus-lang.com/docs/hashes.html


Why is it odd? You're just calling a function with two arguments.


That function call is an alias for: map-get(map-get($palettes, 'blue'), light)

Which, in a language with dot accessors, could be accessed like: $palette.blue.light

I don't think he means that the function call is odd but rather that it's odd that you have to create and call a function to be as concise. Some of the oldest and longest Sass issue threads are about this missing feature.


Not really a preprocessor per se, but look into JSS. Since it’s just JavaScript, you could use the object syntax you asked about.


If you're using Less, try http://strapless.io/ (my take on organizing colors in a project)


The point of a palette is that if your blue is your accent colour, the grey will already be a bit blueish and work great with it


By the way, you can also generate CSS using e.g. Python. No need for yet another domain specific language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: