Affecting an already hovered element, when another is hovered - css

I saw other posts about affecting other elements, when one is hovered, but can we have something like a hover-ception? For example, in my code, the description shows when we hover on the sidebar image, but when you hover on the description, the effect of hovering the image goes away. Can we like, have #sidebarimage:hover #description:hover #sidebarimage(:hover) or something? I want the image to stay faded (the effect it gets when its hovered) when my courser is on the description (whhich is over the image). I cant wrap my head around it. Thank you.
https://www.dropbox.com/s/atyrxbvs246bpmt/Screenshot%202014-11-07%2010.09.21.png?dl=0
#sidebarimage img:hover {
-webkit-transition: opacity 0.6s linear;
opacity: 0.5;
z-index:1;
}
#sidebarimage:hover #description {
margin-top:-50%;
z-index:200;
opacity:1;
-moz-transition-duration:0.6s;
-webkit-transition-duration:0.6s;
-o-transition-duration:0.6s;
}

This appears to be a bug. From the W3C specs for CSS Color:
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’.
In your code, the #description has an opacity of 1, and so doesn't get assigned a position in the stacking order. As such, it gets drawn behind the image which now has an opacity of 0.5. However, if you assigned the #description a non-1 value, it appears to display correctly.
Take a look at this JSFiddle. Try setting the opacity to 1 and observe the difference. I added a red background around the #description just to make it easier to see.
For more detailed information, you could take a look at this related StackOverflow question:
css opacity affecting sibling image opacity

Related

Why is CSS Hover behaviour flaky?

I want to create a button (using only css and html) that reveals another button beneath it on hover by rotating on it's lowermost axis.
I've been mostly successful: http://codepen.io/machinarius/pen/BdtCb
But as you can see on my pen the hover behaviour is flaky at best, it resets the animation on any movement of the cursor. Why id that happening? Isn't -webkit-animation-fill-mode: both; supposed to reverse the animation once the selector goes off?
There seem to be two parts to this question:
Why is the hovering flaky?
Like Palpatim said, as soon as the unfold-button is hovered over, it jumps away, so you'll need to have an unmoving element that will catch your hovers without un-hovering itself. So let's add a div that will do this:
<div class="container">
<div class="unfold-button orange">
Hello World
</div>
</div>
Likewise, let's update the CSS selector accordingly:
.container:hover .unfold-button {
Now if you put that in your HTML, you'll see that the hovering is no longer flaky. However, as you described, it still isn't animating back into place. This brings us to our second question:
Why is the animation not reversing?
Actually, animation-fill-mode does not mean that the animation will reverse back when the animation is no longer assigned; it only determines what attributes "fill out" before and after the animation occurs. If you remove the line defining animation-fill-mode, you'll see that the only difference is that, without it, the animation reverts after completing.
Also, elements have no memory of the animation values that they used to have, so as soon as an element's animation attribute changes, the element immediately "pops" into what it is assigned to be with no influence from any previous values of animation.
As a result, what's actually happening with your CSS is that, when the unfold-button is hovered over, it is handed the unfold animation and plays it (like it should), but when it is un-hovered, it suddenly has no animation assigned, so having "forgotten" about the animation, it just snaps back to what it was originally assigned to be.
Considering that the unfold animation is one simple motion, I would recommend expressing it instead as a transition:
.unfold-button {
/* ... */
border-style: none;
box-sizing: border-box;
transform-origin: 50% 100%;
-webkit-transform-origin: 50% 100%;
-webkit-transition: 0.5s;
transform: rotateX(0deg);
-webkit-transform: rotateX(0deg);
}
.container:hover .unfold-button {
-transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
}
Note how the transition attribute is maintained throughout both the hovered and non-hovered states. Like with animation, no animation results from it without its immediate presence.
And there you have it!
If the HTML and CSS look like what I have sitting in front of me right now, all should be good.
There's a little bit more information about reversing a CSS animation on hover-out here:
How to make CSS Animation reverse on hover-out?
The problem is that you're applying your animation on the :hover pseudo-class. Once the animation happens, you're no longer hovering, and so the animation resets. Try wrapping a container class around your animation element, and applying your animation trigger to the container's :hover, as in the example on https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode.

CSS: hover not working due to opacity

I'm having a strangs CSS problem.
Below is a very simple code sample, demonstrating the problem.
<html>
<head>
<style>
.hover {
float: right;
}
.hover:hover {
background-color: blue;
}
.blocker {
opacity: 0.5;
}
</style>
</head>
<body>
<div class="hover">hover</div>
<div class="blocker">blocker</div>
</body>
</html>
I have a div A, floating over another div B, which has an opacity of 0.5. And I want to add a CSS hover rule to the floating div. But for some reason I can't.
Whether I float right or left, doesn't matter.
But when I change the opacity to 1, the hover rule works all of a sudden.
Can anybody explain this behaviour?
I can "fix" the problem by wrapping the content of the blocker div in a span, but it feels like I shouldn't have to.
Here's a jsFiddle, demonstrating the problem: http://jsfiddle.net/ed82z/1/
Simply put - it is "above" it if the opacity has a less than 1 value.
The key term here is a Stacking Context.
By setting opacity to a value less than one, it is layered differently according to the specification since it receives a new stacking context and is positioned beneath the element.
It is specified here float and in opacity:
The root element forms the root stacking context. Other stacking contexts are generated by any positioned element (including relatively positioned elements) having a computed value of 'z-index' other than 'auto'. Stacking contexts are not necessarily related to containing blocks. In future levels of CSS, other properties may introduce stacking contexts, for example 'opacity' [CSS3COLOR].
From opacity:
Since an element with opacity less than 1 is composited from a single offscreen image, content outside of it cannot be layered in z-order between pieces of content inside of it. For the same reason, implementations must create a new stacking context for any element with opacity less than 1. 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’. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that ‘auto’ is treated as ‘0’ since a new stacking context is always created. See section 9.9 and Appendix E of [CSS21] for more information on stacking contexts. The rules in this paragraph do not apply to SVG elements, since SVG has its own rendering model ([SVG11], Chapter 3).
How to fix it:
You can set pointer-events to none , see this fiddle.
Adding overflow: hidden worked for me:
.blocker {
opacity: 0.5;
overflow:hidden;
}
Or:
.blocker {
opacity: 0.5;
position:relative;
z-index:-1;
}
(thank you #Eyal Barta for this option)
http://jsfiddle.net/ed82z/7/
This is because .blocker overlays your other div, easily shown with firebug or other dev tools.
When you add opacity you add a 'stacking context'.
This occurs because these DIVs have special properties which cause them to form a stacking context.
In this case: elements with an opacity value less than 1. Which is giving your div a z-index, and it is causing the div to be rendered in a different order.
The Stacking Context
In .blocker class is overlapping the .hover class because of float:right;
.blocker {
opacity: 0.5;
width:100px
}
you can fix this set float:left in blocker class or else set width:100px to fixed width for div it won't overlap.

CSS position and opacity styles interfering with hover and click events

Recently I was playing around with a custom modal and I was having difficulty with dismissing it.
Basically there is an anchor tag with an absolute position placed on a div with a relative position. Css hover styles were not applied to it when the mouse was clearly above the anchor also the click event was not being fired.
Examples:
Defective Dismiss Anchor
Working Dismiss Anchor
The difference between these two examples is in the css
In the defective case the following styles are present
.modalDialog
{
/* ... */
-webkit-transition: opacity 400ms ease-in;
-moz-transition: opacity 400ms ease-in;
transition: opacity 400ms ease-in;
pointer-events: none;
}
.modalDialog:target
{
opacity: 1;
pointer-events: auto;
}
In the working examples all of these styles have been removed, but everything else stays the same.
My original assumptions about z-index being the culprate proved to be untrue, also I am doubting that fixed and relative positions are to blame (unconfirmed), it looks like opacity is to blame.
I realize why the removed styles are not needed, but I don't understand why they were preventing the hover and click events from firing?
An explanation would be appreciated.
It's the pointer-events: none that causes the problem.
This property controls how elements respond to mouse events, in this case hover and click.
It looks like it's tried to be overridden on the :target selector, but this won't work in this case, because .modalDialog:target means 'when the url is #modalDialog'. But, that .modalDialog doesn't have an ID so it can't be a target anyway.
From CSS tricks:
The :target pseudo selector in CSS matches when the hash in the URL and the id of an element are the same.
This is a fiddle update with just the pointer-events CSS rules removed, and it works.
http://jsfiddle.net/zPgj8/11/

Set dropdown menu parent background to transparent, keep children opaque

There is a navigation menu near the top of http://eaglesflight.sites.hubspot.com/conference for which I would like to have the parent items (TRAINING, COMPANY, RESOURCES) have transparent backgrounds, while maintaining the current opacity of the children on hover.
Essentially, I want to be able to see the background image behind the parent items of the navigation as opposed to the solid colour that is currently there.
I'm an amateur, tasked with doing some web development at work. Any help is greatly appreciated.
Remove background: #1d3d6f from the .nav-menu li and add it to .hs-menu-children-wrapper
for the hover, remove background: #fff from .nav-menu a:hover
If you don't set a background-color, you'll see whatever is behind the element.
...while maintaining the current opacity of the children on hover.
So seems like you already tryed to set a opacity to the element:
.hs-menu-wrapper.hs-menu-flow-horizontal>ul li.hs-item-has-children
{
position: relative;
opacity: 0.8;
}
Now indeed, the child elements also have this hover. This is because the parent element is "stronger". You can just re-adjust the opacity on hover:
.hs-menu-item.hs-menu-depth-1.hs-item-has-children:hover
{
opacity: 1;
}
jsFiddle
Note The COMPANY is not semi-transparent, because it has no child element. You can change this if you want by including the element with no children to the semi-transparent opacity
Hope this helped you :)

Buggy blink effect with CSS multiple transition when use 'all' property

I have a problem with the CSS transition property.
I need to declare two transitions for a section-tag. Every transition with the section should have a duration of 1s, only the background should have a duration of 0.3s
So my CSS-transition code would look like that:
section{
background: black;
transition: all 1s ease, background 0.3s ease;
}
section:hover{
background: green;
transform: translateY(100px);
}
But when I hovering the link now, the background get animated in 1s and it blinks strangely.
Here the codepen Demo
Someone know why this happend? And how can I realize my goal?
And yes, I need the all property!
EDIT
Just found a strange one. In the linked codepen above, it blinks. But when I animate also the padding, it stop blinking! But the background will be animated in 1s...
Here's the second demo
I have tried this in code pen, the problem not in the transition property.
Better you use div tag for the link background and create separate transition for that.
Surely div tag will give the best solution for your problem.
The problem occurred because as you hover over the element, it starts moving downwards.
When the element is not hovered, it would revert back.
Now as you hover, the elements starts moving and then loses the hover immediately which causes it to return to original state but again gains the hover effect as it again receives the mouse-over event which also cause blink, and the strange phenomenon you observed.
If you place mouse close towards the bottom, you observe the desired effect.
The fix should be that you write a hover for the container that contains these elements and apply the effect to these elements.
Besides you've applied transition in only 1 state which also may be the reason for blink;
try using transitions to both the statements like below:
section{
width:300px;
height:300px;
background:black;
color:white;
transition: background 0.3s ease, all 3s ease;
}
section:hover{
background:green;
transition: background 0.3s ease, all 3s ease;
}

Resources