Skip to content
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

add color functions to raise/lower brightness #1853

Closed
wants to merge 1 commit into from
Closed

add color functions to raise/lower brightness #1853

wants to merge 1 commit into from

Conversation

Sinetheta
Copy link
Contributor

brighten(color, amount) and dim(color, amount) which use the existing HSV helpers to adjust the brightness of a color.

As long as Photoshop remains a dominant force in the design world, we're going to have to deal with HSV (aka HSB). The ability to adjust "brightness" makes dealing with these much easier.

@seven-phases-max
Copy link
Member

dim? This really confused me as a non-native speaker (I can look in dictionary of course but I have never seen this word in context of colour processing before).

@Sinetheta
Copy link
Contributor Author

@seven-phases-max I wasn't sure what to name it, since "darken" is already being used to change lightness. Any suggestions?

http://thesaurus.com/browse/darken

@seven-phases-max
Copy link
Member

@Sinetheta Honestly I don't know too :)

@Sinetheta
Copy link
Contributor Author

blacken?

@lukeapage
Copy link
Member

I think the names work. So presumably this does something significantly
different to the existing colour functions?

@Sinetheta
Copy link
Contributor Author

Yes, HSL and HSV are different color models. Hue is the same, but they have different interpretations of how to move around the "colorfulness" of a particular hue (HSV is more like blending paint, HSL is meant to be more like how humans perceive the difference between colors).

For example, today I was working from a Photoshop file provided by a coworker, and to them all the color transitions made sense. A button used a gradient from a color over a range of "brightness", a hover state did the same thing but was 15% less HSB saturated. These kinds of operations were repeated throughout the file.

But when it came time to translate that to web, there was a problem. Instead of being write a couple concise mixins, I would need buckets of a variables, all those particular colors which have no simple relationship in another color model.

ps: it might actually be more appropriate for me to include 2 functions for modifying saturation in HSB as well.

brighten  += brightness
shade     -= brightness
chroma    += saturation (hsv)
tone      -= saturation (hsv)

*just pulling these names out of thing air from painting terms

@lukeapage
Copy link
Member

Could the same thing be achieved with softlight / darklight and shades of
grey? I have to admit I don't know much about colour models and would have
to refer to @Synchro over whether these should go in. If its lightness in a
different colour model, would a colour model parameter to lighten/darken
make more sense? Just throwing it out there as an option.

On 6 February 2014 07:26, Kevin Attfield notifications@github.com wrote:

Yes, HSL and HSV http://en.wikipedia.org/wiki/HSL_and_HSV are different
color models. Hue is the same, but they have different interpretations of
how to move around the "coloryness" of a particular hue (HSV is more like
blending paint, HSL is meant to be more like how humans percieve the
difference between colors).

For example, today I was working from a Photoshop file provided by a
coworker, and to them all the color transitions made sense. A button used a
gradient from a color over a range of "brightness", a hover state did the
same thing but was 15% less HSB saturated. These kinds of operations were
repeated throughout the file.

But when it came time to translate that to web, there was a problem.
Instead of being write a couple concise mixins, I would need buckets of a
variables, all those particular colors which have no simple relationship in
another color model.

Reply to this email directly or view it on GitHubhttps://github.com//pull/1853#issuecomment-34298644
.

@seven-phases-max
Copy link
Member

would a colour model parameter to lighten/darken make more sense?

Btw. this is a good idea. When I was in the blending functions I had a thought that some kind of a blend(mode, ...) function that could expose all blending modes exactly since most of the missing blending modes can't be implemented as separate functions only because of their conflicting names (e.g. darken, lighten, saturation etc.).
Same could apply to the adjustments functions, e.g. darken(color, hsv), saturate(color, hsl) etc.

@Synchro
Copy link
Member

Synchro commented Feb 6, 2014

We do already have the hsvhue, hsvsaturation, hsvvalue functions, so you can already do most of this with those plus a little math. In terms of DRY, would it not be better for brighten/dim to be one function with a wrapper to call the other with a negated value since brighten(@c, 10%) is the same as dim(@c, -10%)?

I'm torn between having different names for each operation and adding a colorspace param - the latter would clearly allow easy addition of more colorspaces and reduce the proliferation of function names, but OTOH the operations are not exactly analagous in each colorspace - i.e. darken in HSL does not produce the same results as dim in HSB/V.

I can see hsva being useful as we can't currently do that at all.

@matthew-dean
Copy link
Member

I sort of feel like Less.js now has too many color functions natively. These additional functions are useful for smaller and smaller segments of users. If you look at the documentation, it's the one part that can't really be explained briefly (and often aren't explained at all), so it's a barrier for someone just learning the language. IMO much of the color parts of Less.js should be moved to a plugin model (non-core) when such a model actually exists (and is documented).

@Sinetheta
Copy link
Contributor Author

thanks @Synchro I never thought of using hsvvalue, so technically what I'm doing with brighten could be done with the equivalent statement:

background: brighten(gray, 20);
background: hsv(hue(gray), min(hsvsaturation(gray) + 20, 100%), hsvvalue(gray));

It's not exactly pretty, since we can't define our own functions (without a hack?), but it certainly gets the job done without complicating the library.

@seven-phases-max
Copy link
Member

since we can't define our own functions (without a hack?)

We can, via hack or by using the corresponding plugin.

As for doing this via math and/or other functions, it will be a bit unfair to not provide brighten/dim since we have things like:

tint(red, 10%);  // equal to mix(white, red, 10%);
shade(red, 10%); // equal to mix(black, red, 10%);
difference(#654, #321); // equal to (#654 - #321);
// etc.

But sure, we definitely need to think of how to bring the iron order to the colour functions subsystem (and their naming especially... We could slowly move forward by marking some old names deprecated and optionally move some of the functions to plugins as suggested by @matthew-dean). For example:
"todo: provide saturation(@color, @model: hsv), mark hsvsaturation as deprecated, (optionally provide hsvsaturation or saturation-hsv as sugar in a plugin)" etc...

(Btw., too bad the CSS4 Colors stuff is still in its early draft stage otherwise we could start to move in this direction. Curiosuly things like color(red s(- 10%) s(- 10%)) don't even need significant changes in the parser, though their current syntax is insane to be honest).

@Soviut
Copy link

Soviut commented Feb 6, 2014

I'm wondering if perhaps the naming of the functions is part of the reason there are so many currently. For example, darken() and brighten() could be a single brightness() function which accepts positive and negative values as the 2nd argument.

@seven-phases-max
Copy link
Member

function which accepts positive and negative values as the 2nd argument.

In fact both darken() and brighten() (as well as most of other "opposite" function pairs) already work that way (i.e. darken(red, -10%) is valid and is equal to brighten(red, 10%)). So having both is more like a semantic goody rather then a real necessity. I.e. verb/antiverbs for adjustment/modifying functions (e.g. saturate/desaturate) and nouns for "get value of" type of functions (e.g. saturation).

Technically it could be even just one function:

saturation(@colour);       // return S value of the colour
saturation(@colour,  10%); // increase S value and return new colour
saturation(@colour, -10%); // decrease S value and return new colour

(Though I can guess how this could look confusing if the same function returns different things i.e. color vs. number).

@Sinetheta
Copy link
Contributor Author

@seven-phases-max also, although the "mixins as functions" trick is neat, I think they still can't be used as arguments to other mixins. So, not much help when the goal is:

button {
    .gradient(brighten(@background, 10%), @background);
}

@seven-phases-max
Copy link
Member

I think they still can't be used as arguments to other mixins.

It's just a matter of formatting:

button {
    .brighten(@background, 10%); .gradient(@-, @background);
}

There's nothing you can't do via mixins and scope. But it is barely on topic (i.e. my remark was just more to "hack / not hack" thing, nothing else).

@lukeapage
Copy link
Member

I think we would like to provide a function, rather than officially recommend the work-around of calling mixins.

The question now is how.

@seven-phases-max description of saturation with a colour model for me sounds the simplest thing to do. And although I agree it doesn't seem like a big thing, we get alot of requests for new functions that basically the old functions with a different color model.

How does that sound to you @Sinetheta ?

@matthew-dean
Copy link
Member

I agree it doesn't seem like a big thing, we get alot of requests for new functions that basically the old functions with a different color model.

So why not add an optional "color model" to function calls?

@Synchro
Copy link
Member

Synchro commented Feb 19, 2014

The problem with that is that there are not necessarily exact parallels between the params across color spaces, for example while saturation and hue are the same in HSV and HSL, the lightness/value acts a bit differently.

@seven-phases-max
Copy link
Member

in HSV and HSL, the lightness/value acts a bit differently.

Hmm, indeed. But I guess it's not that critical, we don't have to be that restrictive, our goal is just to prevent that enormous amount of potential functions with strange names. E.g. if semantically a shared function name is too confusing we can leave both lightness/hsv-value functions as they are (or they optionally can also accept model parameter and do the same thing, after all a higher hsv-value is lighter than a lower hsv-value :)

@Synchro
Copy link
Member

Synchro commented Feb 19, 2014

There are probably not that many functions that have properties similar enough to do this with, so we'd need separate functions for them anyway.

As an alternative to a colorspace param, could we not derive it from the input color? So brightness would affect L given an HSL value, but V given HSV? I guess that could be confusing if you pass in an RGB value and rely on it being converted into some other space before applying the transformation.

@seven-phases-max
Copy link
Member

So brightness would affect L given an HSL value, but V given HSV?

In Less we don't have HSL or HSV color object actually. Less color object is always just an RGBA color so only a function name or its parameters can guide what to do (i.e. the conversion is always performed anyway).

@lukeapage
Copy link
Member

v2 supports plugins for new functions. See https://github.com/less/less-plugin-advanced-color-functions

Feel free to make a pr against that, I would be happy taking anything useful into that.

@matthew-dean
Copy link
Member

Per my comment earlier in this thread, I would support deprecating existing color blending functions and moving them to the advanced color functions plugin (after a deprecation period), and adding HSB and other special color functions to that plugin.

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

Successfully merging this pull request may close these issues.

None yet

6 participants