Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

css opacity affecting sibling image opacity

Tags:

css

I have a simple div with two children, a div with an image and yet another div as below:

<div style="width: 500px;">
    <div class="settingicon righty">
        <img src="/images/icons/setting.png" />
    </div>
    <div class="schedulepicker quat todaytoday">MONDAY</div>
</div>

I wanted so that when the second div is hovered, it reduces its opacity to 0.9, so in my CSS my .schedulpicker has this rule:

.schedulepicker:hover {
    opacity: 0.9;
}

The problem is when it is hovered, the sibling image changes in opacity as well. Why is this so?

EDIT

Here's a fiddle http://jsfiddle.net/VUzg9/4/

i am starting to wonder could it actually be the file itself.

EDIT 2

tested with jpg and gif, probably not the image issue.

like image 994
Crays Avatar asked Oct 28 '13 14:10

Crays


People also ask

Is opacity inherited CSS?

Opacity is not inherited, but because the parent has opacity that applies to everything within it. You cannot make a child element less transparent than the parent, without some trickery. Values are a number from 0 to 1 representing the opacity of the channel (the “alpha” channel).

How do you use opacity without affecting children's elements?

The simplest way to create a transparent background, without affecting any child elements, is by using the rgba function. This only affects the color itself and has outstanding support among browsers.

How can I change background opacity without affecting text?

One approach you can use is to put the background-image styles in a pseudo-element of the parent element. Since the pseudo-element is a sort of child of the parent, you can change the opacity of it without affecting the text content.

Can we give opacity in percentage?

A <number> in the range 0.0 to 1.0 , inclusive, or a <percentage> in the range 0% to 100% , inclusive, representing the opacity of the channel (that is, the value of its alpha channel).


2 Answers

You need to set the position (default is static) and a z-index for your image.

See jsfiddle

.righty {
    float: right;
    position: relative;
    z-index: 100;
}

The opacity you're setting on #schedulepicker is creating a new stacking context, and stacking contexts affect z-indexes. Since you didn't specify z-indexes manually, they're being auto assigned, and #schedulepicker has a higher value than #settingicon because it comes later in the markup.

EDIT

The W3C color module says the following:

If an element with opacity less than 1 is not positioned, implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with ‘z-index: 0’ and ‘opacity: 1’.

like image 196
damian Avatar answered Nov 24 '22 07:11

damian


Great question - it looks like a bug.

You need to put a position and a z-index on it in order to get it to work.

.righty {
    float: right;
    position: relative; 
    z-index: 1;
}

http://jsfiddle.net/VUzg9/9/

EDIT I want to add to this answer because it's a very intriguing problem.

If we look at the spec it tells us that:

In future levels of CSS, other properties may introduce stacking contexts, 
for example 'opacity' [CSS3COLOR].

As @enfredH04 pointed out in his answer, as soon as the element changes opacity, it appears to then gain a stacking context (maybe Blink implemented a part of the spec [quoted above] that has not actually been written, or at least published, yet?) It's sibling does not have it's own stacking context and, thus, appears behind the element that changes opacity.

You can see this if you give the element a starting opacity of 0.9 - http://jsfiddle.net/VUzg9/11/ - at this point it must gain a stacking context. (Interestingly a starting opacity of 1 does not give it a stacking context).

like image 41
Adam Avatar answered Nov 24 '22 06:11

Adam