Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LESS CSS - Adding a percentage to a hex color - How does this work?

Tags:

css

less

Let's say there is a LESS variable representing a CSS color in hex

@primary-color: #0070B8;

Somewhere else in the LESS code, @primary-color is operated on like this.

@new-color: @primary-color + 10%;

@new-color is #0a7ac2.

How did LESS derive the new color? I tried looking at rgb and hsl versions of the @primary-color versus the @new-color, but I don't see the values being a 10% difference in any scale. It looks like it added an absolute value of 10 to the R/G/B component of the hex color, but that seems counter-intuitive. (I presume SASS works similarly.)

#0070B8
0,112,184
(0,112,184)
rgb(0,112,184)
rgb(0%,44%,72%)
hsl(203° 100% 36%)

#0a7ac2
10,122,194
(10,122,194)
rgb(10,122,194)
rgb(4%,48%,76%)
203° 90% 40%

(EDIT: I didn't write this LESS code. I saw it in a repo, and I was trying to figure how this worked, because I couldn't find anything in the LESS documentation that explained the percentage when it's used in a + operation. Bolded text was added by another user.)

like image 628
Stephen Avatar asked Oct 15 '25 13:10

Stephen


2 Answers

See Language Features > Overview > Operations.

Assuming it's actually @new-color: @primary-color + 10%; (and = is just a typo in your Q) it goes like this:

  • if the first operand of an arithmetic expression is a color any subsequent operands are converted to colors too.
  • scalar numeric values (e.g. 10%) are converted to a color as value -> rgb(value, value, value). I.e. 10% is converted to rgb(10, 10, 10) color value (% is irrelevant in this case and it will be the same for 10, 10px, 10whatever etc.)
  • arithmetic operations apply to color operands on a per-RGB-channel basis.

So in summary it's:

#0070b8 -> rgb(0, 112, 184)
10%     -> rgb(10, 10, 10)

rgb(0, 112, 184) + rgb(10, 10, 10) ->
rgb(0 + 10, 112 + 10, 184 + 10) ->
rgb(10, 122, 194)

rgb(10, 122, 194) -> #0a7ac2

Or yet in other words, #0070B8 + 10 is a just shorthand for #0070b8 + #0a0a0a hence the #0a7aC2 result. (And yet again % unit has no effect there and should be removed to make it less confusing).


To answer:

It looks like it added an absolute value of 10 to the R/G/B component of the hex color, but that seems counter-intuitive.

See Strict Units. Basically it is the same as 10px + 10% for example, it will result in 20px (and not in 10px + 10px * 0.1). Same way CSS calc(10px + 10%) is not equal to (10px + 10px * 0.1) though Less arithmetic expressions are not equal to those of calc too since the compiler has no all that information about current element state a browser has.

Yes, % arithmetic is a typical confusion in Less, but note that percentage values in CSS always refer to a value set elsewhere and are never considered to be some kind of "ratio value" on their own. E.g. width: 50% -> 50% of the container width and it's not equal to width: 0.5 or something. So in Less you never assume 10% in an arithmetic expression can refer to some previous value of the same expression and/or being implicitly converted to a unitless ratio (e.g. it's never 10% -> 0.1).

like image 152
seven-phases-max Avatar answered Oct 18 '25 12:10

seven-phases-max


I actually think it just added 10 to each RGB value, because... 10% of what? My guess is that it just used 10 instead of 10%.

What you probably actually want is to use lighten(#0070B8, 10%) which would add 10% (of 255 I think) to each RGB component of the color.


Side note, there are other "math-like" things in LESS that are strange like that too. For example, 10px + 10em is a value that can't be calculated, so I believe it will just add 10+10 and give it the first unit of measure,which would result in 20px.

like image 45
CodingWithSpike Avatar answered Oct 18 '25 12:10

CodingWithSpike



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!