在悬停时仅更改RGBA背景颜色的Alpha通道是否可行?

135

我有一组具有不同rgba背景颜色但相同alpha值的<a>标签。是否可能编写一个单一的css样式,仅更改rgba属性的不透明度?

以下是代码的快速示例:

 <a href="#"><img src="" /><div class="brown">Link 1</div></a>
 <a href="#"><img src="" /><div class="green">Link 2</div></a> 

还有样式

a {display: block; position: relative}
.brown {position: absolute; bottom: 0; background-color: rgba(118,76,41,.8);}
.green {position: absolute; bottom: 0; background-color: rgba(51,91,11,.8);}
我想做的是编写一个单一的样式,当鼠标悬停在标签上时更改不透明度,但保持颜色不变。

像这样

a:hover .green, a:hover .brown {background-color: rgba(inherit,inherit,inherit,1);}

顺便问一下,你的div元素在a元素里面是干什么的? - BoltClock
@mercator:好的,我错过了那个。 - BoltClock
@BoltClock,对于这个效果编码的最简单方法似乎是使用单个a标签,而不是一个包围着img和另一个包围着文本的标签。HTML 5支持它是一个很好的奖励。 - Fireflight
1
当这个问题被提出时,使用 CSS 是不可能做到的。现在,使用 CSS 变量 就可以了 - 正如我在我的回答中所示。 - Danield
这是一个链接,供那些想知道如何将 RGB 转换为 RGBA 的人使用(https://dev59.com/rmw15IYBdhLWcg3wWqV0)。 - djvg
15个回答

82

现在可以使用自定义属性实现这一点:

.brown { --rgb: 118, 76, 41; }
.green { --rgb: 51, 91, 11; }

a { display: block; position: relative; }
div { position: absolute; bottom: 0; background-color: rgba(var(--rgb), 0.8); }
a:hover div { background-color: rgba(var(--rgb), 1); }

为了理解它的工作原理,请参阅如何将透明度应用于CSS颜色变量? 如果自定义属性不可用,请查看下面的原始答案。
不幸的是,对于每个单独的类,您都必须再次指定红色,绿色和蓝色的值:
a { display: block; position: relative; }

.brown { position: absolute; bottom: 0; background-color: rgba(118, 76, 41, 0.8); }
a:hover .brown { background-color: rgba(118, 76, 41, 1); }

.green { position: absolute; bottom: 0; background-color: rgba(51, 91, 11, 0.8); }
a:hover .green { background-color: rgba(51, 91, 11, 1); }

你只能在属性值中使用 inherit 这个关键字,而即使是这种情况,使用 inherit 也不合适。

迫不及待地等待颜色修改功能(https://www.w3.org/TR/css-color-5/),这样我们就不必将颜色通道定义为列表了。 - ahong

18

如果你希望避免硬编码数字,可以尝试一些方法。其中一些方法仅适用于使用纯白色背景,并在其上添加白色而不是降低透明度的情况。第一个方法应该适用于所有情况,只要:

  • 你没有已经在伪元素中使用它;并且
  • 你可以将<div>标签的position设置为相对或绝对位置。

选项1:::before伪元素:

.before_method{
  position:relative;
}
.before_method:before{
  display:block;
  content:" ";
  position:absolute;
  z-index:-1;
  background:rgb(18, 176, 41);
  top:0;
  left:0;
  right:0;
  bottom:0;
  opacity:0.5;
}
.before_method:hover:before{
  opacity:1;
}

选项2:白色GIF覆盖层:

.image_method{
  background-color: rgb(118, 76, 41);
  background-image: url(https://upload.wikimedia.org/wikipedia/commons/f/fc/Translucent_50_percent_white.png)
}
.image_method:hover{
  background-image:none;
}

选项三:box-shadow 方法:

这是 gif 方法的变体,但可能会出现性能问题。

.shadow_method{
  background-color: rgb(18, 176, 41);
  box-shadow:inset 0 0 0 99999px rgba(255,255,255,0.2);
}
.shadow_method:hover{
  box-shadow:none;
}

CodePen示例:http://codepen.io/chrisboon27/pen/ACdka


好的回答,谢谢。我发现第三个选项很有用,如果我反转这种方法会更简单:不使用任何额外的内容,而在悬停时使用:box-shadow: inset 0 0 0 99999px rgba(128,128,128,0.2)。这对我来说是必要的,因为我的行交替为白色和浅灰色,所以原始答案没有改变白色。 - Dovev Hefetz
非常喜欢阴影的方法。 - Maseed

13

不,这是不可能的。

不过,如果你想要做这样的事情,可以尝试使用CSS 预处理器

据我所知,至少LESSSass有函数可以使颜色更加透明或不透明。


1
我总是忘记SCSS/LESS。总是。也许我需要开始真正使用它们。 - BoltClock
1
在SCSS中,它是transparentize([color], 0.8)。请参阅http://sass-lang.com/documentation/Sass/Script/Functions.html#transparentize-instance_method - Arian Acosta

9

现在是2017年,通过

CSS自定义属性/CSS变量 (Caniuse)

CSS变量的一个经典用例是能够个性化属性值的部分。

因此,在这里,我们将rgba值分成两个部分/变量(一个用于RGB值,一个用于Alpha),而不是再次重复整个RGBA表达式。

.brown { 
  --rgb: 118, 76, 41; 
}
.green {
  --rgb: 51, 91, 11;
}
.brown, .green {
  --alpha: 0.3;
  background-color: rgba(var(--rgb), var(--alpha));
}

然后,在悬停时,我们现在只需修改--alpha变量即可:

a:hover .green, a:hover .brown {
  --alpha: 1;
}

a {
  display: block;
  position: relative;
}
.brown { 
  --rgb: 118, 76, 41; 
}
.green {
  --rgb: 51, 91, 11;
}
.brown, .green {
  display: inline-block;
  --alpha: 0.3;
  background-color: rgba(var(--rgb), var(--alpha));
  font-size: 40px;
  margin: 20px;
}

a:hover .green, a:hover .brown {
  --alpha: 1;
}
<a href="#">
  <div class="brown">Link 1</div>
</a>
<a href="#">
  <div class="green">Link 2</div>
</a>

Codepen

进一步阅读:

使用CSS变量个性化定制CSS属性(Dan Wilson)


6

有一种替代方案,您可以在原始颜色上添加线性渐变背景图像。

a{
  background: green
}
a:hover{
  background-image:linear-gradient(hsla(0,0%,0%,.2) 100%,transparent 100%) // darker
}
a:hover{
  background-image:linear-gradient(hsla(255,100%,100%,.2) 100%,transparent 100%) // lighter
}

此外,使用CSS3滤镜属性也可以实现此功能,但似乎会改变文本颜色。
a:hover{
   filter: brightness(80%) //darker
}
a:hover{
   filter: brightness(120%) //lighter
}

这里有一个 JSFiddle:https://jsfiddle.net/zhangyu911013/epwyL296/2/


到目前为止,这是我唯一满意的答案。 - Andre Elrico
同意安德烈的观点。可以进一步简化使用CSS变量。我已经添加了一个答案来澄清。 - Neil W

6
不,这是不可能的。 如果你想使用rgba,必须同时设置每个值。没有办法只改变alpha值。

3

为什么不使用:hover并在悬停类中指定不同的不透明度?

a:hover {
     opacity:0.6
}

14
因为这会影响整个元素。 - BoltClock
3
使用SVG对象,可以使用fill-opacity属性。 - Aprillion
1
不仅包括整个元素,还包括所有子元素。 - Daniel F
也许不是完美的,但对于某些情况来说很有用。 - Matthew Nichols

2

简单的解决方案:

a
{
    position: relative;
    display:inline-block;
    background: rgba(red, 0.75);
    padding: 20px;


   &:before
   {
     content: ' ';
     position: absolute;
     left: 0;
     top: 0;
     width: 100%;
     height: 100%;
   }

   &:hover
   {
     &:before
     {
       background-color: rgba(#000, 0.25); 
     }
   }
}

示例: https://jsfiddle.net/epwyL296/14/ 只需调整背景的alpha值即可。如果您想要亮色而不是暗色,只需将 #000 替换为 #fff。

2
我有一个类似的问题。我有18个不同的 div 充当按钮,每个都有不同的颜色。而不是为每个确定颜色代码或使用 div:hover 选择器更改不透明度(影响所有子元素),我像 @Chris Boon 的答案中所示一样使用了伪类 :before。
因为我想对单独的元素进行着色,所以我使用了 :before,在 :hover 上创建了一个透明白色的 div。这是一个非常基本的淡化效果。
#categories div {
    position:relative;
    width:100px;
    height:100px;
    float:left;
    border:1px solid black;
    display:table-cell;
}

#categories div:before{
    content:"";
    position:absolute;
    top:0px;
    left:0px;
    width:100px;
    height:100px;
}

#categories div:hover:before {
    background-color:white;
    opacity:0.2;
}

#a_Particular_Div {
    background-color:red;
}

根据CanIUse.com网站,截至2014年初,这应该有大约92%的支持率。(http://caniuse.com/#feat=css-gencontent

2
你可以使用CSS变量来实现,但可能会有一些混乱。
首先,设置一个包含所需颜色的RGB值(按顺序)的变量:
:root {
  --color-success-rgb: 80, 184, 60; 
}

然后,您可以为颜色分配RGBA值,并从此变量中提取除alpha值以外的所有内容:
.button--success {
  background: rgba(var(--color-success-rgb), 0.8);
}

这并不是非常美观,但它允许您对一个颜色使用相同的RGB值,但不同的alpha值。


1
这是一个合理的解决方案。并且,带有颜色的变量不必放在:root上,它可以放在元素的类上,设置其基本颜色。谢谢! - Brad

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