ChatGPT解决这个技术问题 Extra ChatGPT

Dynamically change color to lighter or darker by percentage CSS

css

We have a big application on the site and we have a few links which are, let's say blue color like the blue links on this site. Now I want to make some other links, but with lighter color. Obviously I can just do simply by the hex code adding in the CSS file, but our site lets user decide what colors they want for their customized profile/site (like Twitter).

So, my question is: can we reduce the color by percentage?

Let's say the following code is CSS:

a {
  color: blue;
}

a.lighter {
  color: -50%; // obviously not correct way, but just an idea
}

OR

a.lighter {
  color: blue -50%;  // again not correct, but another example of setting color and then reducing it
}

Is there a way to reduce a color by a percentage?

I'm not into CSS, but what does reducing a color mean? Make it more transparent? Or do you want to change the individual RGB channels of the color?
no, not the transparent, but making the color reduce by hex or rbg or hsl
If you wont, you can manually chose a color using for example this online tool: hexcolortool.com

i
imjared

You can do this with CSS filters in all modern browsers (see the caniuse compatibility table).

.button { color: #ff0000; } /* note: 100% is baseline so 85% is slightly darker, 20% would be significantly darker */ .button:hover { filter: brightness(85%); }

Here's more reading from CSS Tricks about the various filters you can use: https://css-tricks.com/almanac/properties/f/filter/


Also note that the brightness() level is not limited to 100%. You can make it brighter than the original too.
Filter will also apply to any background-image associated with your element. Say if you decorate your links with an icon this way the icon brightness will be altered by that filter.
According to... caniuse.com/#feat=css-filters ... IE11 doesn't support this... and according to... w3counter.com/globalstats.php?year=2017&month=8 ... IE11 is still in the top 10 most used browsers. While I would love to use this feature, until IE11 dies, it doesn't look like I will. :-(
Can I apply it to background-color only? I see it is working against the whole. jsfiddle.net/6trjmaq3/1
This is the best answer when using recursion (for instance nested DIVs) with an indefinite number of steps/levels, but it affects the WHOLE element, not just the background color or just the text color.
T
TylerH

All modern browsers have had 100% filter support since January 2020. Even UC Browser for Android (instead of Chrome, on the $80 phones) supports it.

a {
    /* a nice, modern blue for links */
    color: #118bee;
}
a:active {
    /* Darken on click by 15% (down to 85%) */
    filter: brightness(0.85);
}

Additionally, you can control this dynamically with CSS variables, which have been supported by most browsers since October 2017 (excluding QQ):

:root {
    --color: #118bee;
    --hover-brightness: 1.2;
}
a {
    color: var(--color);
}
a:active {
    /* Darken on click */
    filter: brightness(var(--hover-brightness));
}

Not my project, but one that's great to look at for a real-world example of how great modern CSS can be, check out: MVP.css

Original Answer

If you're using a stack which lets you use Sass or Less, you can use the lighten function:

$linkcolour: #0000FF;

a {
  color: $linkcolour;
}

a.lighter {
  color: lighten($linkcolour, 50%);
}

There's also darken which does the same, but in the opposite direction.


how to do it when backround color is dynamically set in inlines? but I just want always darken it when hovered?
This nice NPM module allows the darkening/lightening of hex colors in JavaScript - https://www.npmjs.com/package/shader
If you want to dynamically apply a lighter or darker shade to any button with a hover effect using just CSS3 and SVG data try my answer stackoverflow.com/a/55828346/6730421
Does this work on-the-fly by passing custom css property at runtime?
can this work with color names? orange for example.
P
Pekka

There is "opacity" which will make the background shine through:

opacity: 0.5;

but I'm not sure this is what you mean. Define "reduce color": Make transparent? Or add white?


@Basit "I guess"? You should know. But in any case, if your background is white, you can "fake" brightness by making it more transparent - I've used this to good effect recently.
The "opacity" trick also work if the background is black (opacity 0.5 makes the color darker on black background).
If this is for the css background: rather than foreground: as far as the meaning of "lighter" or "brighter" and the Google search, this is probably the answer most people are looking for. Also, no worries about support: caniuse.com/#feat=css-opacity
S
Spliff

HSL Colors provide an answer, a HSL color value is specified with: hsl(hue [0,255], saturation %, lightness %).

HSL is supported in IE9+, Firefox, Chrome, Safari, and in Opera 10+

a
{
color:hsl(240,65%,50%);
}
a.lighter 
{
color:hsl(240,65%,75%);
}

s
sparanoid

At the time of writing, here's the best pure CSS implementation for color manipulation I found:

Use CSS variables to define your colors in HSL instead of HEX/RGB format, then use calc() to manipulate them.

Here's a basic example:

:root { --link-color-h: 211; --link-color-s: 100%; --link-color-l: 50%; --link-color-hsl: var(--link-color-h), var(--link-color-s), var(--link-color-l); --link-color: hsl(var(--link-color-hsl)); --link-color-10: hsla(var(--link-color-hsl), .1); --link-color-20: hsla(var(--link-color-hsl), .2); --link-color-30: hsla(var(--link-color-hsl), .3); --link-color-40: hsla(var(--link-color-hsl), .4); --link-color-50: hsla(var(--link-color-hsl), .5); --link-color-60: hsla(var(--link-color-hsl), .6); --link-color-70: hsla(var(--link-color-hsl), .7); --link-color-80: hsla(var(--link-color-hsl), .8); --link-color-90: hsla(var(--link-color-hsl), .9); --link-color-warm: hsl(calc(var(--link-color-h) + 80), var(--link-color-s), var(--link-color-l)); --link-color-cold: hsl(calc(var(--link-color-h) - 80), var(--link-color-s), var(--link-color-l)); --link-color-low: hsl(var(--link-color-h), calc(var(--link-color-s) / 2), var(--link-color-l)); --link-color-lowest: hsl(var(--link-color-h), calc(var(--link-color-s) / 4), var(--link-color-l)); --link-color-light: hsl(var(--link-color-h), var(--link-color-s), calc(var(--link-color-l) / .9)); --link-color-dark: hsl(var(--link-color-h), var(--link-color-s), calc(var(--link-color-l) * .9)); } .flex { display: flex; } .flex > div { flex: 1; height: calc(100vw / 10); }

Color Manipulation (alpha)

Color Manipulation (Hue)

Color Manipulation (Saturation)

Color Manipulation (Lightness)

I also created a CSS framework (still in early stage) to provide basic CSS variables support called root-variables.


is it possible to get this to work with css color names: (ie: orange)
A
AmerllicA

Use the filter pure CSS property. for a complete description of the filter property functions read this awesome article.

I had a same issue like yours, and I fixed it by using the brightness function of filter property:

.my-class {
  background-color: #18d176;
  filter: brightness(90%);
}

See above. IE11 doesn't like that.
August 17th 2021, IE end-of-life 🥳✌️🎉
@amarinediary EoL for IE itself is June 15, 2022. August 17, 2021 was the end of M365 services support in IE... a different thing.
They lied to us back in April ! It just won't go away ! We've all been waiting this day for so long ! @TylerH
@amarinediary The full story of IE11 is that it's tied to the lifecycle of the embedded OSes it is included with, so it will only start going away on June 15, 2022. Any OSes with IE11 built-in that hit EoL after that will mean IE11 is also supported on that OS until those EoLs. However, you can effectively consider IE to be EoL today in terms of what you need to support in web development. If you needed to support IE, you'd know it because your customer would specifically require it, and even then you could probably get away with IE mode in Edge.
t
trebor1979

In LESS, you would use the following variables:

@primary-color: #999;
@primary-color-lighter: lighten(@primary-color, 20%);

This would take the 1st variable and lighten it by 20% (or any other percentage). In this example, you'd end up with your lighter color being: #ccc


n
nCardot

If you want darker color, you can use rgba black with low opacity:

rgba(0, 0, 0, 0.3);

For lighter use white:

rgba(255, 255, 255, 0.3);

This relies on what the background is because it becomes translucent, not lighter
A
Alvaro Montoro

This is an old question, but most of the answers require the use of a preprocessor or JavaScript to operate, or they not only affect the color of the element but also the color of the elements contained within it. I am going to add a kind-of-complicated CSS-only way of doing the same thing. Probably in the future, with the more advanced CSS functions, it will be easier to do.

The idea is based on using:

RGB colors, so you have separate values for red, green, and blue;

CSS variables, to store the color values and the darkness; and

The calc function, to apply the change.

By default darkness will be 1 (for 100%, the regular color), and if you multiply by a number between 0 and 1, you'll be making the color darker. For example, if you multiply by 0.85 each of the values, you'll be making the colors 15% darker (100% - 15% = 85% = 0.85).

Here is an example, I created three classes: .dark, .darker, and .darkest that will make the original color 25%, 50%, and 75% darker respectively:

html { --clarity: 1; } div { display: inline-block; height: 100px; width: 100px; line-height: 100px; color: white; text-align: center; font-family: arial, sans-serif; font-size: 20px; background: rgba( calc(var(--r) * var(--clarity)), calc(var(--g) * var(--clarity)), calc(var(--b) * var(--clarity)) ); } .dark { --clarity: 0.75; } .darker { --clarity: 0.50; } .darkest { --clarity: 0.25; } .red { --r: 255; --g: 0; --b: 0; } .purple { --r: 205; --g: 30; --b: 205; }

0%
25%
50%
75%


0%
25%
50%
75%


J
Joao Tavora

if you decide to use http://compass-style.org/, a sass-based css framework, it provides very useful darken() and lighten() sass functions to dynamically generate css. it's very clean:

@import compass/utilities

$link_color: #bb8f8f
a
  color: $link_color
a:visited
  color: $link_color
a:hover
  color: darken($link_color,10)

generates

a {
  color: #bb8f8f;
}

a:visited {
  color: #bb8f8f;
}

a:hover {
  color: #a86f6f;
}

c
ctford

As far as I know, there's no way you can do this in CSS.

But I think that a little server-side logic could easily do as you suggest. CSS stylesheets are normally static assets, but there is no reason they couldn't be dynamically generated by server-side code. Your server-side script would:

Check a URL parameter to determine the user and therefore the user's chosen colour. Use a URL parameter rather than a session variable so that you can still cache the CSS. Break up the colour into its red, green and blue components Increment each of the three components by a set amount. Experiment with this to get the results you are after. Generate CSS incorporating the new colour

Links to this CSS-generating page would look something like:

<link rel="stylesheet" href="http://yoursite.com/custom.ashx?user=1231">

If you don't use the .css extension be sure to set the MIME-type correctly so that the browser knows to interpret the file as CSS.

(Note that to make colours lighter you have to raise each of the RGB values)


There are javaScript based approaches around that might be easier to implement. See e.g. experts-exchange.com/Programming/Languages/Scripting/JavaScript/…
Interesting suggestion. Would there be a risk of colours flickering as the page loaded if you used JS?
I've used techniques like this -- each user gets his own style sheet -- in conjunction with a preferences page where the user specified color selections. Note you don't have to copy the entire style sheet, and shouldn't. You can have multiple style sheets in a page, so you can have a generic style sheet for the stuff that's the same for everybody and then a custom style sheet for the stuff that's different. In our case we had a default custom style sheet for the (majority of) users who just took the default.
Now that HSL values are supported (IE9+, Firefox, Chrome, Safari, and in Opera 10+) it's possible to just change the lightness without all of the effort calculating a new rgb (w3schools.com/cssref/css_colors_legal.asp) ... scroll down to the HSL / HSLA section...
Y
Yangshun Tay

If you only need to change background color, this is a great approach that is futureproof - Use linear-gradient method on background image!

Check out the example below:

document .getElementById('colorpicker') .addEventListener('change', function(event) { document .documentElement .style.setProperty('--color', event.target.value); }); span { display: inline-block; border-radius: 20px; height: 40px; width: 40px; vertical-align: middle; } .red { background-color: red; } .red-darker { background: linear-gradient( to top, rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25) ) red; } :root { --color: lime; } .dynamic-color { background-color: var(--color); } .dynamic-color-darker { background: linear-gradient( to top, rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25) ) var(--color); }

Static Color
Dynamic Color

Change the dynamic color:

Credits: https://css-tricks.com/css-custom-properties-theming/


This is a very clever answer. I've seen production code that uses this: background-image: linear-gradient(rgba(0,0,0,0.30), rgba(0,0,0,0.30));
Great, contrary to the filter answers, this doesn't mess with my border colors.
N
Nathan Arthur

You could use a little javascript to calculate the darker and lighter color using the rgb().

Fiddle : Not really nice, but it is just for illustration.

What it essentially does is sets a color and selects 20 colors with the same amount (compared to one another) of rgb only with 10 apart.

for (var i=-10; i < $('.row:eq(0) .block').length/2 ; i++) {
 var r = 91;
 var g = 192;
 var b = 222;
 $('.row:eq(1) .block:eq('+(i+10)+')').css('background' , color(r+(i*10),g+(i*10),b+   (i*10))      );
};

C
Chris

Not directly, no. But you could use a site, such as colorschemedesigner.com, that will give you your base color and then give you the hex and rgb codes for different ranges of your base color.

Once I find my color schemes for my site, I put the hex codes for the colors and name them inside a comment section at the top of my stylesheet.

Some other color scheme generators include:

http://www.colorschemer.com/online.html

http://colorschemegenerator.com/

http://www.cssjuice.com/25-popular-color-scheme-and-palette-generators/


How would you make this dynamically though? Since that's what OP asked for
C
Cryptc

If you need to brute force it for older browser compatibility, you can use Colllor to automatically select similar color variations.

Example (color: #a9dbb4):

https://i.stack.imgur.com/UxWQ8.png


s
stephenhay

You could use RGBa ('a' being alpha transparency), but it's not widely supported yet. It will be, though, so you could use it now and add a fallback:

a:link { 
    color: rgb(0,0,255); 
    }
a:link.lighter {
    color: rgb(128,128,255); /* This gets applied only in browsers that don't apply the rgba line */
    }
a:link.lighter { /* This comes after the previous line, so has priority in supporting browsers */
    color: rgba(0,0,255,0.5); /* last value is transparency */
    }

this might help alot, if its supported in major browsers.
A
Adam Whateverson

I am adding an answer using raw CSS3 and SVG without requiring LESS or SASS.

Basically, if the question is to make a colour 10%,25%,50% ligher or darker for the sakes of a global hover effect you can create an SVG data call like this

:root{
--lighten-bg: url('data:image/svg+xml;utf8,<svg version="1.1" id="cssLighten" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve"><rect opacity="0.2" fill="white" width="50" height="50"/></svg>') !important;
--darken-bg: url('data:image/svg+xml;utf8,<svg version="1.1" id="cssDarken" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve"><rect opacity="0.2" fill="black" width="50" height="50"/></svg>') !important;

}

.myButton{
    color: white;
    background-color:blue;
}
.myButton:hover{
    background-image: var(--lighten-bg);
}

For some reason, unknown to me, the SVG won't allow me to enter a hex value in the "fill" attribute but "white" and "black" satisfy my need.

Food for thought: If you didn't mind using images, just use a 50% transparent PNG as the background image. If you wanted to be fancy, call a PHP script as the background image and pass it the HEX and OPACITY values and let it spit out the SVG code above.


To use hex values for fill color, try to encode the hash character using %23 in sted of #. Example: fill="%23bb9988"
L
LordRathan

Try:

a {
  color: hsl(240, 100%, 50%);
}

a:hover {
  color: hsl(240, 100%, 70%);
}

Thanks for your answer - you should note that it is a duplicate of one of the other answers. It is best to check the other answers before replying.
Thank you for that hint. It seems that I've missed the other answer, sorry.
N
NA Hoijtink

Bringing it all together, a table solution done purely with DIV and CSS, try it ;) The browser should support RGBA colors though....

<head>
<style>
    .colored-div-table {
        display: table;
        table-layout: fixed;
    }
    .colored-div-table #col {
        display: table-column;
    }
    .colored-div-table #col:nth-child(odd) {
    }
    .colored-div-table #col:nth-child(even) {
    }
    .colored-div-table #col:nth-child(1){
        background-color: lightblue;
        width: 50px !important;
    }
    .colored-div-table #col:nth-child(2){
        background-color: lightyellow;
        width: 200px !important;
    }
    .colored-div-table #col:nth-child(3){
        background-color: lightcyan;
        width: 50px !important;
    }
    .colored-div-table #row {
        display: table-row;
    }
    .colored-div-table #row div {
        display: table-cell;
    }
    .colored-div-table #row div:nth-child(1) {

    }
    .colored-div-table #row div:nth-child(2) {
    }
    .colored-div-table #row div:nth-child(3) {
    }
    .colored-div-table #row:nth-child(odd) {
        background-color: rgba(0,0,0,0.1)
    }
    .colored-div-table #row:nth-child(even) {
    }
</style>
</head>
<body>

<div id="divtable" class="colored-div-table">
    <div id="col"></div>
    <div id="col"></div>
    <div id="col"></div>  

    <div id="row">
        <div>First Line</div><div>FL C2</div><div>FL C3></div>
    </div>

    <div id="row">
        <div>Second Line</div><div>SL C2</div><div>SL C3></div>
    </div>

    <div id="row">
        <div>Third Line</div><div>TL C2</div><div>TL C3></div>
    </div>

    <div id="row">
        <div>Forth Line</div><div>FL C2</div><div>FL C3></div>
    </div>
    <div id="row">
        <div>Fifth Line</div><div>FL C2</div><div>FL C3></div>
    </div>
    <div id="row">
        <div>Sixth Line</div><div>SL C2</div><div>SL C3></div>
    </div>
    <div id="row">
        <div>Seventh Line</div><div>SL C2</div><div>SL C3></div>
    </div>
    <div id="row">
        <div>Eight Line</div><div>EL C2</div><div>EL C3></div>
    </div>
    <div id="row">
        <div>Nineth Line</div><div>NL C2</div><div>NL C3></div>
    </div>
    <div id="row">
        <div>Tenth Line</div><div>TL C2</div><div>TL C3></div>
    </div>

</div>
</body>

A
Aron Koffler

I know it's late but, you could use a wrapper to your buttons and change a rgba color function opacity level, as said in other answers but with no explicit example.

Here's a pen:

https://codepen.io/aronkof/pen/WzGmjR

#wrapper { width: 50vw; height: 50vh; background-color: #AAA; margin: 20px auto; border-radius: 5px; display: grid; place-items: center; } .btn-wrap { background-color: #000; display: inline-block; } button { transition: all 0.6s linear; background-color: rgba(0, 255, 0, 1); border: none; outline: none; color: #fff; padding: 50px; font-weight: 700; font-size: 2em; } button:hover { background-color: rgba(0, 255, 0, .5); }


s
somedev

One outdated simple answer (in 2013) was to use a 50% transparent white PNG over the color:

div {
    background-color:red;
}

div:hover {
    background-image:url('lighten.png');
}

Where lighten.png is a PNG of a white fill with 50% transparency.

There's much better ways to do this today. I hope people stop commenting now.


This is bad for two reasons: 1. You load an extra file on hover. 2. Buttons will have different sizes.
Even better would be to use base-64 encoded image to skip extra file load.
It's very old solution which was useful so long ago. Now you'd better not to use it. Just use filter/hsl/opacity etc. Just not use ugly image loading way if you can resolve it in program way
This is really a terrible hack, whatever you do, do not do this
This is a piece of history. LEt's respect it that way. ;)
J
Jay

See my comment on Ctford's reply.

I'd think the easy way to lighten a color would be to take each of the RGB components, add to 0xff and divide by 2. If that doesn't give the exact results you want, take 0xff minus the current value times some constant and then add back to the current value. For example if you want to shift 1/3 of the way toward white, take (0xff - current)/3+current.

You'd have to play with it to see what results you got. I would worry that with this simple a formula, a factor big enough to make dark colors fade nicely might make light colors turn completely white, while a factor small enough to make light colors only lighten a little might make dark colors not lighten enough.

Still, I think going by a fraction of the distance to white is more promising than a fixed number of steps.


C
Costa

I found a PHP class that let me do this server side. I just output an inline CSS color style for whatever I need to be lighter/darker. Works great.

http://www.barelyfitz.com/projects/csscolor/

(note that the class uses PEAR for throwing errors, but I didn't want to include PEAR just to modify colors, so I just removed all the PEAR references)

I turned it into a static class with static methods so I can call "lighten" & "darken" functions directly without creating a new object.

Sample usage:

$original_color = 'E58D8D';  
$lighter_color = Css::lighten($original_color, .7);  
$darker_color = Css::darken($original_color, .7);