通过CSS动态地按百分比更改颜色为较浅或较暗。

565

我们在网站上有一个大型应用程序,有一些链接是蓝色的,就像这个网站上的蓝色链接一样。现在我想创建一些其他链接,但颜色要更浅。显然,我可以通过在CSS文件中添加十六进制代码来简单地实现,但我们的网站允许用户决定他们想要为自定义配置文件/网站使用什么颜色(就像Twitter一样)。

所以,我的问题是:我们能否按百分比减少颜色?

假设以下代码是CSS:

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

或者

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

有没有一种方法可以按百分比减少颜色?


1
我不太懂CSS,但是减少颜色是什么意思呢?是让它更透明吗?还是想要改变颜色的RGB通道? - StampedeXV
不是透明,而是通过十六进制、RGB或HSL减少颜色。 - Basit
1
如果您不想使用默认颜色,您可以手动选择一种颜色,例如使用此在线工具:https://www.hexcolortool.com。 - simhumileco
https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/brightness - Alex L
28个回答

14
如果您决定使用基于Sass的CSS框架http://compass-style.org/,它提供了非常有用的darken()lighten() Sass函数来动态生成CSS。这非常干净简洁。
@import compass/utilities

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

生成

a {
  color: #bb8f8f;
}

a:visited {
  color: #bb8f8f;
}

a:hover {
  color: #a86f6f;
}

13
据我所知,无法通过CSS实现此功能。但我认为一些服务器端逻辑可以轻松地按照您的建议进行操作。CSS样式表通常是静态资源,但没有理由不能由服务器端代码动态生成。您的服务器端脚本应该:
  1. 检查URL参数以确定用户及用户选择的颜色。使用URL参数而不是会话变量,以便仍然可以缓存CSS。
  2. 将颜色分解为其红、绿和蓝三个分量。
  3. 将每个分量增加一定量。尝试这个过程以获得您想要的结果。
  4. 生成包含新颜色的CSS。
链接到生成CSS的页面可能如下所示:
<link rel="stylesheet" href="http://yoursite.com/custom.ashx?user=1231">

如果您不使用.css扩展名,请确保正确设置MIME类型,以便浏览器知道将文件解释为CSS。

(请注意,要使颜色变浅,您必须增加每个RGB值)


有一些基于JavaScript的方法可能更容易实现。例如,请参见http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_21632591.html - Pekka
有趣的建议。如果使用JS,页面加载时会出现颜色闪烁的风险吗? - ctford
我曾经使用过类似的技术——每个用户都有自己的样式表——以及一个偏好设置页面,用户可以在其中指定颜色选择。请注意,您不必复制整个样式表,也不应该这样做。您可以在页面中拥有多个样式表,因此您可以为所有人都相同的内容拥有通用样式表,以及为不同内容拥有自定义样式表。在我们的情况下,我们为(大部分)只使用默认设置的用户提供了默认的自定义样式表。 - Jay
2
解决方案: 使用JavaScript在CSS中生成更浅或更深的颜色。 https://dev59.com/XnI_5IYBdhLWcg3wJfgM - Basit
你应该使用通用处理程序(.ashx)而不是网页表单(.aspx)。 - Alon Gubkin
1
现在支持HSL值(IE9+,Firefox,Chrome,Safari和Opera 10+),可以仅更改亮度而无需计算新的RGB(http://www.w3schools.com/cssref/css_colors_legal.asp)...向下滚动到HSL / HSLA部分... - slushy

6
color-mix() 函数是 CSS Color Module Level 5 规范中即将加入的新功能。它的主要目的是根据指定的比例混合两种或多种颜色。请查看support
:root {
  --primary-color: #FF9900;
  --primary-color-dark: color-mix(in srgb, var(--primary-color), black 20%);
  --primary-color-light: color-mix(in srgb, var(--primary-color), white 20%);
}

.button {
  background: var(--primary-color);
}

.button:hover {
  background: var(--primary-color-dark);
}

技术真棒。CSS越来越好了。 - undefined

5
你可以使用一些javascript代码来计算较暗和较亮的颜色,使用rgb()函数。
演示:这并不是很好看,但只是为了说明问题。
它的本质是设置一个颜色,并选择20个具有相同数量(相互比较)的rgb的颜色,仅相差10。
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))      );
};

3
以下代码对我来说可以使颜色变暗 - 只需在悬停时更改50%即可。
.button {
  display: inline-block;
  background-color: green;
}

.button:hover {
  background-image: linear-gradient(rgb(0 0 0/50%) 0 0);
}

这是仅仅调整背景颜色的亮度/暗度而不影响每个渲染子元素的唯一方法。 - Ivan Sanz Carasa
其他答案也提到了linear-gradient,但这个答案很棒,因为它展示了它可以是多么简单。 - Tao Starbow

3
如果您需要为了兼容旧浏览器而进行暴力破解,可以使用Colllor来自动选择类似的颜色变化。
例如(颜色:#a9dbb4): enter image description here

3

没有直接的方法。但是你可以使用一个网站,例如colorschemedesigner.com,该网站将为您提供基础颜色,然后提供不同范围内的十六进制和RGB代码。

一旦我为我的网站找到了颜色方案,我会将颜色的十六进制代码和名称放在样式表顶部的注释部分中。

其他一些颜色方案生成器包括:


你怎么动态地实现呢?因为这是 OP 要求的。 - Timberman

2

您可以使用RGBa('a'表示alpha透明度),但目前它的支持还不广泛。但是,它将来会得到支持,因此您现在可以使用它并添加一个回退方案:

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 */
    }

如果主流浏览器都支持,这可能会很有帮助。 - Basit

2

我将使用原生CSS3和SVG来回答,而不需要LESS或SASS。

基本上,如果问题是为了全局悬停效果而使颜色变得更亮或更暗,您可以创建一个像这样的SVG数据调用:

Original Answer翻译成"最初的回答"

: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);
}

由于某些我不知道的原因,SVG不允许我在"fill"属性中输入十六进制值,但"white"和"black"满足我的需求。

值得思考的问题: 如果您不介意使用图像,只需使用50%透明的PNG作为背景图像即可。如果您想要更加花哨一些,可以调用PHP脚本作为背景图像,并传递HEX和OPACITY值,让它输出上面的SVG代码。


1
为了使用十六进制值作为填充颜色,请尝试使用%23来编码井号#。例如:fill="%23bb9988" - eye-wonder

1

尝试:

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

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

1
感谢您的回答 - 您应该注意到它是其他答案之一的重复。在回复之前最好检查其他答案。 - ralight
2
谢谢你的提示。看来我错过了另一个答案,抱歉。 - LordRathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接