currentColor与透明度的搭配

20
有没有一种方法可以改变一个边框的不透明度,而这个边框的颜色是从currentColor继承的呢?比如,在#inner2中继承currentColor并将其不透明度设置为0.25
寻找纯css的解决方案。例如,类似以下内容的东西:

#outer{
  color: rgba(255,0,0,1);
}

.inner{
  display: block;
  width: 100%;
  height: 10px;
  margin-bottom: 5px;
  border: 2px solid currentColor;
}

#inner2{
  /* This is where I want to inherit current color */
  /* ... but still set it to 0.25 opacity */
  border-color: rgba(255,0,0,0.25);
}
<div id='outer'>
  <div id='inner1' class='inner'></div>
  <div id='inner2' class='inner'></div>
</div>


1
不可能...你可以使用一些技巧,比如使用继承颜色的 before/after,然后在它们上面设置 opacity - vsync
如果你想这样使用,sass scss 将是最好的选择! - Jack jdeoel
我想到了一个愚蠢的主意,要不我们把外层的透明度设为0.25,这样继承它的元素就能完全接收到它,无需改动。然后再在外层上叠加4个这样的元素,哈哈。 - encryptoferia
4个回答

14

color-mix

caniuse支持表格

color-mix可以用来混合currentColor与其他颜色(如transparent):

html {
  display: grid;
  place-items: center;
  height: 100vh;
  box-sizing: border-box;
  font: 700 6em Arial;
  
  /* actual fun: */
  color: Salmon;
  background: color-mix(in srgb, currentColor 20%, transparent);
  border: 20px solid color-mix(in srgb, currentColor 50%, transparent);
}
AWESOME


之前的答案:

你把currentColor值和inherit混淆了,后者是默认值。对于border属性,你不需要使用currentColor,因为它是border的默认值。

#inner1#inner2都继承了最近的父元素的颜色(红色),并且边框默认使用该颜色。

以下解决方案将始终有效,无论颜色的来源是什么(内联style属性、外部CSS或远祖继承):

#outer{ color:red; }
#inner1, #inner2{ 
    padding: 2em; 
    margin-top: 1em;  
}
#inner1{ border:5px solid; } 

#inner2{ position:relative; }

#inner2::before{  
  content:'';
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  border:5px solid;
  opacity:.5;
}
<div id='outer'>
  <div id='inner1'>inner 1</div>
  <div id='inner2'>inner 2</div>
</div>

此外,请查看我的其他答案在这里,它使用了尖端的语法。

嗯,好的,很有趣...这似乎是一个可行的解决方案。在示例中,#inner2#inner1小吗?不确定为什么呢>? - Zze
是的,它的行为不同,因为边框不是 div 的实际部分,而是位于其上方,因此不占用任何空间。您可以通过在两个 div 上使用 box-shadow 而不是 border 来解决此问题,或者只需在第二个 div 上使用不同的 padding 进行补偿。 - vsync
@Zze - 给 #inner1 设置 box-shadow: 0 0 0 5px inset;,而不是边框 :) - vsync

7
你可以使用CSS变量来实现类似的行为:

#outer{
  --border-r: 255;
  --border-g: 0;
  --border-b: 0;
  color: rgba(var(--border-r),var(--border-g),var(--border-b),1);
}

.inner{
  display: block;
  width: 100%;
  height: 10px;
  margin-bottom: 5px;
  border: 2px solid;
}

#inner2{
  color: rgba(var(--border-r),var(--border-g),var(--border-b),0.25);
}
<div id='outer'>
  <div id='inner1' class='inner'></div>
  <div id='inner2' class='inner'></div>
</div>


不需要在边框中写入 currentColor,这是没有意义的。 - vsync
谢谢,我忘记删除它了 =) - fen1x
虽然这个方法可以奏效,但这并不灵活,因为颜色可能来自内联的“style”属性、外部CSS文件或者是未知祖先的颜色(因此你无法确切地知道在哪里设置变量)。 - vsync
我受到了这个的启发,我确实认为这是有效的,只需要一些调整。看看这个演示:https://codepen.io/nicetransition/pen/bGWOVMN - Kevin Mack
@vsync currentColor 是指同一元素的文本颜色,它并不是毫无意义的。如果您希望边框与 color: 属性相同,请使用 currentColor。 - Vitim.us

2
你现在可以以更直接的方式实现这一点,至少在现代浏览器中,使用color-mix函数。
示例:

#outer {
  color: rgba(255,0,0,1);
}

.inner {
  display: block;
  width: 100%;
  height: 10px;
  margin-bottom: 5px;
  border: 2px solid currentColor;
}

#inner2 {
  border-color: color-mix(in srgb, currentColor 25%, transparent);
}
<div id='outer'>
  <div id='inner1' class='inner'></div>
  <div id='inner2' class='inner'></div>
</div>

你可以选择一个颜色空间(我在这里为你选择了SRGB),以及混合的比例。如果你省略了比例,它将默认为50%。
然而,请注意,如果当前颜色已经部分透明,这将使其更加透明;这并不替换alpha通道。要实现这一点,我们需要等待相对颜色CSS Color Level 5的另一部分)。

是的,我支持“color-mix”!现在我可以在页面上放置数百个带有半透明层的元素,而不会使我的RAM使用量过高。使用“opacity”会为每个元素创建一个新的“堆叠上下文”(层),这并不总是最佳实践。 - ShortFuse

1

Check this out:

:root {
  --color-r: 0;
  --color-g: 0;
  --color-b: 0;
  --color-a: 1;
}

[class*=-color] {
  color: rgba(var(--color-r), var(--color-g), var(--color-b), var(--color-a));
}

[class*=-background] {
  --background-r: var(--color-r);
  --background-g: var(--color-g);
  --background-b: var(--color-b);
  --background-color-a: var(--color-a);
  background-color: rgba(var(--color-r), var(--color-g), var(--color-b), var(--color-a));
}

[class*=dark] {
  --color-r: 0;
  --color-g: 0;
  --color-b: 0;
}

[class*=light] {
  --color-r: 255;
  --color-g: 255;
  --color-b: 255;
}

[class*=primary] {
  --color-r: 200;
  --color-g: 2;
  --color-b: 33;
}

[class*=secondary] {
  --color-r: 102;
  --color-g: 102;
  --color-b: 102;
}

[class*="--alpha-0"], [class*="--alpha-00"] {
  --color-a: 0;
}

[class*="--alpha-10"] {
  --color-a: .1;
}

[class*="--alpha-20"] {
  --color-a: .2;
}

[class*="--alpha-30"] {
  --color-a: .3;
}

[class*="--alpha-40"] {
  --color-a: .4;
}

[class*="--alpha-50"] {
  --color-a: .5;
}

[class*="--alpha-60"] {
  --color-a: .6;
}

[class*="--alpha-70"] {
  --color-a: .7;
}

[class*="--alpha-80"] {
  --color-a: .8;
}

[class*="--alpha-90"] {
  --color-a: .9;
}

[class*="--alpha-100"] {
  --color-a: 1;
}

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