1

We have a design system that comes with a number of CSS custom properties for colors, e.g.:

:root {
  --color--blue-1: oklch(88.6% 0.023 238);
}

We're using the relatively new color format oklch.

Now I need to CSS calc() a color that is 50% lighter, using the oklch(from...) function. I cannot use opacity or alpha for the task because it needs to be a solid color that remains the same regardless of any background.

The desired result would be

:root {
  --color-blue-1-50: oklch(94.2% 0.023 238);
}

The formula is simple: Just pick the l from lch, then the new l_new will be:

l_new = l + ((100% - l) / 2)

So basically, just add half of what's missing to 100% to the l in lch.

How can I put this into a CSS calc function like this:

:root {
  --color-blue-1-50: oklch(from var(--color-blue-1) calc(/* these are the missing bits */) c h);
}

I tried this, but it just shows up as an invalid value:

:root {
  --color-blue-1-50: oklch(from var(--color-blue-1) calc(l + calc(100% - l / 2)) c h);
}

:root {
  --color-blue-1: oklch(94.2% 0.023 238);
  --color-blue-1-50: oklch(from var(--color-blue-1) calc(l + (100% - l) / 2) c h);
}

div {
  display: block;
  height: 100px;
  width: 100px;
}

.original {
  background-color: var(--color-blue-1);
}

.fifty-percent-lighter {
  background-color: var(--color-blue-1-50);
}

.faked {
  opacity: 0.5;
}
<div class="original">original</div>
<div class="fifty-percent-lighter">50% lighter</div>
<div class="original faked">50% lighter using opacity</div>

4
  • 1
    that l% ìs clearly invalid Commented May 16, 2024 at 14:43
  • I know, it didn't work without the % either. If anyone can make it work, that surely would be you, right? I have almost unlimited trust in your CSS capabilities. Commented May 16, 2024 at 14:44
  • you also have an extra - in the name in the last formula and did you try calc(l/2 + 1/2)? (or replace the 100% with 1 in your example) Commented May 16, 2024 at 14:49
  • @TemaniAfif I've set up a snippet. Commented May 16, 2024 at 15:07

1 Answer 1

3

Your formula can also be seen as (l/2 + 50%) then instead of 50% you have to use .5

:root {
  --color-blue-1: oklch(80.2% 0.023 238);
  --color-blue-50: oklch(from var(--color-blue-1) calc(l/2 + .5) c h);
}

div {
  display: block;
  height: 100px;
  width: 100px;
}

.original {
  background-color: var(--color-blue-1);
}

.fifty-percent-lighter {
  background-color: var(--color-blue-50);
}

.faked {
  opacity: 0.5;
}
<div class="original">original</div>
<div class="fifty-percent-lighter">50% lighter</div>
<div class="original faked">50% lighter using opacity</div>

Sign up to request clarification or add additional context in comments.

1 Comment

The solution is to use lightness as a value between 0 and 1 instead of a percentage indeed. calc(l + (1 - l) / 2) also worked. Thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.