Skip to content

Color stops - predefined shades of the same color addressed by index #845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zpdDG4gta8XKpMCd opened this issue Jun 23, 2012 · 16 comments
Closed

Comments

@zpdDG4gta8XKpMCd
Copy link

Hi,

This is a feature request. I am a designer who happened to work on CSS. This is what I suggest has a big value and would be nice if incorporated into less.

It is a great time saver being able to define a base color and then get all derived colors by applying the darken and lighten function. There is a problem however that at extreme values (too dark or too bright) these functions give a result that visually doesn't look good (if the color is too close to white is just being cut off and dark things fall into black). So it would be nice to be able to specify a predefined set of discrete colors as shades (stops) of the base color, for example for the shades of RED we would have:

@reds: [#100, #200, #300, #400, #500, #600, #700, #800, #900, #a00, #b00, #c00, #d00, #e00, #f00]; /* all stops of RED that we want to consider /
@thered = @reds[9]; /
a base shade of RED */

and later use a notation like

@thered[+3] or @thered[-2] to refer to #c00 and #700 respectively which are 3 stops lighter and 2 stops darker shades of the base red as defined in the array

same can be done inside of a parametrized mixin, for example

.shaded(@bg) { /* assuming bg is a color stop, that is a single color from the array of shades */
background-color:@bg; border-top: solid 1px @bg[+3]; border-right: solid 1px @bg[-3]; border-bottom: solid 1px @bg[-3]; border-left: solid 1px @bg[+3];
}

Again, the problem with achieving the same using darken/lighten or any other function is that these functions are linear and do not account for the non-linear nature of picking a next matching shade of a color.

Thank you!

@pronebird
Copy link

It seems like overkill for me, why don't just specify variables for your color scheme and do whatever you want with them inside of your colors.less? Person who would just jump into such CSS will be frustrated..

@zpdDG4gta8XKpMCd
Copy link
Author

How would I do that? Ok, it's not a problem to define @red1, @red2, ... @RedN variables that hold shades of the red color. Now, suppose we have a shade at hands (say @red6), and we need a darker shade of it (which is @Red5). You suggest that I just hardcode @Red5 everywhere where I need a darker shade. Really? Wouldn't it be nicer to have something like this instead: .darkerBg(@Colors, @index) { background-color: @Colors[@index - 1]; } If that is cool we can close over the index making it a part of the variable and then use just @Colors[+1] notation which would mean @Colors[@index + 1]

@pronebird
Copy link

It just brings unnecessary complexity. 10+ different tint colors seem a lot. Your problem is more theoretical than practical.

@zpdDG4gta8XKpMCd
Copy link
Author

You have wtitten lots of CSS as far as I can see. Good luck.

@matthew-dean
Copy link
Member

Yeah, I get what you're going for, but it does seem like an awful lot of complexity that has very niche usage.

@zpdDG4gta8XKpMCd
Copy link
Author

but this is the only way to control the shades of color which aren't linear by their nature. Simple example is that the blue color with an offset in HSB doesn't give the same intensity as the green color with the same offset. Which means in order to get the same visually looking shade different HSB values need to be applied to different colors. Which renders color functions dependent on the color they are applied to. Which in its turn makes the entire stylesheet needs to be hardcoded to be consistent with the picked base color, which opposes the very idea of having base colors as independent variables.

@matthew-dean
Copy link
Member

Again, I understand the issue, but your solution is overly complex and arbitrary. You're bringing in the idea of a fixed color palette, which makes a certain kind of sense, but the way you've handled it is not intuitive. @bg[+3] is not a familiar notation to a programmer. I can't see this going into LESS unless it was a much simpler solution.

@jscheel
Copy link

jscheel commented Aug 7, 2012

This helps with css sprite sheets. You could declare an array of extension classes, then use a mixin loop to generate your background positions.

@Synchro
Copy link
Member

Synchro commented Aug 7, 2012

This approach is, semantically speaking, very ugly. If you're styling things with colour names like @TheRed, you're going to be in trouble when you actually want it to be blue. I'd suggest using a less file that maps colour names to semantic classes, i.e. a palette, so you might have

@BoxHeaderBar: @theRed;
@BoxBackground: @theBlue;

As far as differences in colour scaling, you're quite right; there are several pulls pending that incorporate luma calculations (including a couple of mine), and using a proper luma calculation instead of linear scaling would avoid the problem that led you to this convoluted solution in the first place.

@zpdDG4gta8XKpMCd
Copy link
Author

@Synchro, I picked that name just to better illustrate the example, it doesn't mean I use names like this. Having a function that does a better job is nice as long as it does it right, but when it doesn't I'd rather had an array of hand-picked colors and some index variable to manipulate it. Basically an array is a discrete function that maps the index to a value. There are no arrays in less, that's a shame.

@lukeapage
Copy link
Member

Maybe off topic, bu you can simulate arrays by using @@var to look up a
array using the name in @var..

@jscheel
Copy link

jscheel commented Aug 8, 2012

@agatronic can you please elaborate? Right now I am storing the array as a string, then using javascript to eval (disgusting, I know) it for use. It's an incredibly janky approach.

@lukeapage
Copy link
Member

well, its pretty hacky and I think @Synchro has a better idea.. but if you really really need an "array" you could maybe do something like

@col1: #111;
@col2: #222;
/// ...

@index: 1;
@accessor: ~"@col@{index}";
@col: @@acessor;

but its a bit complicated..

I would solve this like @syncro says - by having a set of variables you use (e.g. boxheaderbar or even darkhighlightcolor) and then having a less file that defines these colors for each variant you need - then you get even more control than having an array. Alternatively using advanced color functions when they are merged in.

anyway... I think this request is basically a duplicate of property accessors.. see #76 and #6

which is how this would be implemented?

Which is a feature that was removed from less.js and we get asked for about 1 in every 100 issues and should definitely consider whether it should get added back.

Anyone agree it should be closed (as a duplicate?)

@jscheel
Copy link

jscheel commented Aug 8, 2012

@agatronic that's still not a very scalable solution. For example, in my use (css sprite sheet), I have 100 different sprite positions that are generated, based on the file extension that is added to the class. That means 100 separate variables.

@Synchro
Copy link
Member

Synchro commented Aug 20, 2012

Short of having more complete array syntax in general, I can see that being able to generate a sequence of classes with calculated offsets for spriting would be a useful addition, particularly when sprites are the same size (as in the icons in bootstrap), however, that's a different request to what this issue is about - I suggest you make another ticket for it.

@lukeapage
Copy link
Member

with the new pick function this is possible

@mynum: 2;
@colors: red green blue;
background: pick(@colors, @mynum);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants