Is it possible to change only the alpha of a rgba background colour on hover?

CssHoverBackground ColorRgba

Css Problem Overview


I have a set of <a> tags with differing rgba background colours but the same alpha. Is it possible to write a single css style that will change only the opacity of the rgba attribute?

A quick example of the code:

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

And the styles

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

What I would like to do is write a single style that would change the opacity when the <a> is hovered over, yet keep the colour unchanged.

Something like

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

Css Solutions


Solution 1 - Css

This is now possible with custom properties:

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

To understand how this works, see https://stackoverflow.com/questions/40010597/how-do-i-apply-opacity-to-a-css-color-variable/41265350#41265350

If custom properties are not an option, see the original answer below.


Unfortunately, no, you'll have to specify the red, green and blue values again for each individual class:

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

You can only use the inherit keyword alone as a value for the property, and even then the use of inherit isn't appropriate here.

Solution 2 - Css

You could do various things to avoid having to hard code the numbers if you want to. Some of these methods only work if you use a plain white background as they're really adding white on top rather than reducing opacity. The first one should work fine for everything provided:

  • you aren't already using the psuedo-element for something; and
  • you can set position to relative or absolute on the <div> tag
Option 1: ::before psuedo-element:
.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;
}
Option 2: white gif overlay:
.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;
}
Option 3: box-shadow method:

A variation of the gif method, but may have performance issues.

.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 examples: http://codepen.io/chrisboon27/pen/ACdka

Solution 3 - Css

No, it's not possible.

You could try a CSS pre-processor, though, if you want to do this sort of thing.

From what I could see, at least LESS and Sass have functions that can make colors more, or less, transparent.

Solution 4 - Css

It's now 2017 and this is now possible with

CSS custom properties / CSS Variables (Caniuse)

One classic use case for CSS variables is the ability to individualize parts of a property's value.

So here, instead of repeating the whole rgba expression once again - we split up or 'individulaize' the rgba values into 2 parts / variables (one for the rgb value and one for the alpha)

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

Then, on hover we can now just modify the --alpha variable:

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

Further reading:

Individualizing CSS Properties with CSS Variables (Dan Wilson)

Solution 5 - Css

No, that's not possible.

If you want to use rgba, you must set each value together. There's no way to only change the alpha.

Solution 6 - Css

there is an alternative,you can add a linear-gradient background image onto the original color.

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
}

also, with css3 filter property,you can do that too,but it seems that it will change the text color

a:hover{
   filter: brightness(80%) //darker
}
a:hover{
   filter: brightness(120%) //lighter
}

here is a jsfiddle:https://jsfiddle.net/zhangyu911013/epwyL296/2/

Solution 7 - Css

Why not use :hover and specify a different opacity in the hover class?

a:hover {
     opacity:0.6
}

Solution 8 - Css

simple solution :

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

exemple : https://jsfiddle.net/epwyL296/14/

just play with alpha of background. if you want light instead of darkness, just replace #000 by #fff

Solution 9 - Css

I had a similar problem. I had 18 different divs working as buttons, and each with a different color. Rather than figure out the color codes for each or use a div:hover selector to change the opacity (which affects all children) I used the pseudo-class :before like in @Chris Boon's answer.

Because I wanted to do the coloring on the individual elements, I used :before to create a transparent white div on :hover. This is a very basic washout.

#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;
}

According to CanIUse.com, this should have something like 92% support as of early 2014. (http://caniuse.com/#feat=css-gencontent)

Solution 10 - Css

You can do this with CSS variables, although it's a little messy.

First, set a variable containing just the RGB values, in order, of the color you want to use:

:root {
  --color-success-rgb: 80, 184, 60; 
}

Then you can assign an RGBA value for a color and pull everything but the alpha value from this variable:

.button--success {
  background: rgba(var(--color-success-rgb), 0.8);
}

This isn't super pretty, but it lets you use the same RGB values but different alpha values for a color.

Solution 11 - Css

Update: It's not possible to do that unfortunately. You'll need to write two separate selectors of:


a.green:hover {background-color: rgba(118,76,41,1);}
a.brown:hover {background-color: rgba(118,76,41,1);}
According to the W3C, the rgba property doesn't have/support the inherit value.

Solution 12 - Css

I faced a similar problem. Here's what I did and it works fine( only alpha changes on hover and also the text is not affected) by the following steps:

  1. Apply a highlighted(or any of your choice) class to whichever element you wish to change background alpha of.

  2. Get the background color rgba

  3. Store it in a string and manipulate it(change alpha) as you want on hover(mouseenter and mouseleave)

HTML Code:

<div class="highlighted brown">Link 1</div><br><br>
<div class="highlighted green">Link 1</div>

CSS Code:

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

Javascript Code:

$(document).on({
			
			mouseenter: function() {
			
			var rgba_str = $(this).css("background-color");
			var new_rgba_str ="rgba(" + rgba_str.substring(rgba_str.lastIndexOf("(")+1,rgba_str.lastIndexOf(",")) + ", 0.5)";	
               
				$(this).css("background-color",new_rgba_str ); 
	           },
    
	         mouseleave: function(){
	        
	        	 var rgba_str = $(this).css("background-color");
                
			var new_rgba_str ="rgba(" + rgba_str.substring(rgba_str.lastIndexOf("(")+1,rgba_str.lastIndexOf(",")) + ", 0.8)";				
				$(this).css("background-color",new_rgba_str ); 

	           }
     
		},'.highlighted');

Working Fiddle:http://jsfiddle.net/HGHT6/1/

Solution 13 - Css

Simple workaround with opacity if you can accommodate a slight change in background-color:

.yourClass {
    // Your style here //
    opacity: 0.9;
}

.yourClass:hover, .yourClass:focus {
    opacity: 0.7;
}

.yourClass:active {
    opacity: 1;
    box-shadow: none;
}

.yourClass:hover, .yourClass:focus, .yourClass:active {
    text-decoration: none;
    outline: none;
}

Solution 14 - Css

Building on Yu Zhang's answer:

In :root, (or parent component in Blazor) set css variables:

--bg-img-light: linear-gradient(hsla(255,100%,100%,.2) 100%, transparent 100%);
--bg-img-dark: linear-gradient(hsla(0,0%,0%,.2) 100%, transparent 100%);

Then on any element that you want to apply a hover effect on:

.buttontomakelighter:hover {
  background-image: var(--bg-img-light);
}

.buttontomakedarker:hover {
  background-image: var(--bg-img-dark);
}

Solution 15 - Css

This is about the simplest way; put this in your css stylesheet:

a:hover { color : #c00; } 

done!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFireflightView Question on Stackoverflow
Solution 1 - CssBoltClockView Answer on Stackoverflow
Solution 2 - CssChris BoonView Answer on Stackoverflow
Solution 3 - CssmercatorView Answer on Stackoverflow
Solution 4 - CssDanieldView Answer on Stackoverflow
Solution 5 - CssthirtydotView Answer on Stackoverflow
Solution 6 - CssYu ZhangView Answer on Stackoverflow
Solution 7 - CssDiodeus - James MacFarlaneView Answer on Stackoverflow
Solution 8 - CssMatrixView Answer on Stackoverflow
Solution 9 - CssJosiahView Answer on Stackoverflow
Solution 10 - CssAdam HollettView Answer on Stackoverflow
Solution 11 - CssayypView Answer on Stackoverflow
Solution 12 - CssRakhiView Answer on Stackoverflow
Solution 13 - CssAlfred WallaceView Answer on Stackoverflow
Solution 14 - CssNeil WView Answer on Stackoverflow
Solution 15 - Cssdr. nullView Answer on Stackoverflow