CSS position and opacity styles interfering with hover and click events - css

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/

Related

Affecting an already hovered element, when another is hovered

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

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

Toggling CSS3 animation

I am trying to make a toggle sidebar which animates.
When I try to hide the sidebar with CSS3 Transition property by adding a hidebar class, it works perfectly. But It's a toggle, and when I show it again, there is no transition. The menu just snaps out.
#page-content.hidebar {
transition: margin 0.3s ease;
margin-left: 0;
}
Can anyone suggest how can I have the transition property when I toggle the sidebar to visibility as well?
I am attaching a fiddle as an example.
http://jsfiddle.net/dxYCm/1/
You needed to do several things:
since all rules have been applied using id selectors in css, your class selector had no effect, as in css specificity it had low points to override previous rules specified under id. So you need to add !important. http://htmldog.com/guides/css/intermediate/specificity/ Learn more there...
You needed to put white-space:nowrap; as text/content of first div would curl up as div would get small.
Check it Out>>>
http://jsfiddle.net/techsin/dxYCm/5/
You don't need a hide class at all, jQuery has awesome built in features that do the same thing like .toggle() and .slideToggle!
Here's an example of .toggle
$("a#menu-trigger").click(function () {
$("#page-sidebar").toggle("fast");
$("#page-content").toggleClass("hidebar");
});
Also, you want to apply the transition to #page-content, not #page-content.hidebar so it transitions both expanding and contracting
If you do still want to do it with using a .hide class not changing the jQuery or the HTML, you can do it this way, by toggling the width and height
Relevant CSS for that:
.hide {height:0px; width:0px; color:transparent;}
#page-sidebar {width: 230px; float:left; transition: all 0.3s ease;}

Hovering over CSS transition in Safari lightens certain font color

In my CSS I defined a transition for a class. For some reason, when I hover over the class with the transition, the transition-duration for some reason alters the font color elsewhere (form placeholders and certain links). (This happens only in Safari as far as I can tell.)
Here's a jsFiddle that shows what I'm talking about:
http://jsfiddle.net/EJUhd/
Does anyone know why this occurs and how I can prevent it?
I was struggling with a similar issue.
For me, random links throughout the page became apparently bold (clearly something to do with OSX and anti-aliasing in Safari, as Chrome (in windows 7 and OSX) as well as the same version of Safari in Windows worked fine.
The solution is not obvious, and depending on what you are doing might not be optimal, but adding this line of code fixed the issue:
-webkit-transform: translateZ(0);
This basically triggers the GPU to do animation, and the text no longer had artifacts in my site. Do note that it's not always appropriate to use it, as it may use more battery life and use more resources. Sometimes however, it uses less, so basically check the performance when you add it.
You add this to the normal state not the :hover animated state.
img { -webkit-transform: translateZ(0); }
As opposed to on the:
img:hover { /* not here */ }
The other very positive side effect is that depending on the animation you are doing, it might be smoother through the GPU. So you won't get the choppy animation you mention in your follow up post. In my case, the animation was more seamless in safari. I was doing a 120% scale and 5 degree rotation of an image with some box-shadow appearing at the same time. In my situation, it did not reduce CPU usage unfortunately.
There is no more relevant topic I've found for a problem I had, but that's related to mentioned above issue. So, might be helpful for some one.
In two words: I have some container (popup), some element inside.
Appearing goes the following way: container background is fading up to dark via opacity and element inside is scaling up (like coming closer to us from behind). Everything works great everywhere but not in Safari (Mac/Win/iPhone). Safari "initially" shows my container, but it blinks some strange way (tiny short flash appears).
Only adding -webkit-transform: translateZ(0); (to container!!!) did help.
.container {
-webkit-transform: translateZ(0); /* <-- this */
}
.container section {
-webkit-transform: translateZ(0) scale(.92); /* <-- and I added translate here as well */
-webkit-transition: -webkit-transform .4s, opacity .3s;
opacity:0;
}
.container.active section {
-webkit-transform:translateZ(0) scale(1);
-webkit-transition: -webkit-transform .3s, opacity .3s;
opacity:1;
}
But speaking of the transitions, there was also the following part of code:
.container {
...
top:-5000px;
left:-5000px;
-webkit-transition: opacity .5s, top 0s .5s, left 0s 5s, width 0s 5s, height 0s 5s;
}
.container.active {
-webkit-transition: opacity .5s;
top:0;
left:0;
width:100%;
height:100%;
}
considering, that I want to show/hide the popup using only css switching (and also to make it disappear nicely instead just "display:none").
so, somehow on appearing Safari (obviously) was inheriting transition properties besides "opacity" even as I've overloaded them with only -webkit-transition: opacity .5s;
so, adding the following solved the problem:
.container {
...
-webkit-transition: opacity .5s, top 0s 0s, left 0s 0s, width 0s 0s, height 0s 0s;
}
I can't begin to tell you why it's doing this, but Safari isn't changing your text color, it's anti-aliasing the text differently while the transition is in motion. The text edges get smoother, and the text itself becomes thinner. This is extra obvious if you zoom in on the fiddle with accessibility tools. At some smaller sizes, the shading around the button next to the form text shifts too. (Is it possible that Safari is redrawing some things, or reorienting them on a sub-pixel level during the transitions ? Somebody explain this please, it's driving me nuts now!)
Because I have no real idea why it's doing this either, these might not be the best solutions:
Depending on what you're transforming, replacing the css transform with a javascript animation will probably fix it.
For example in your fiddle, the problem also occurred with a scale transformation, but not with a similar jQuery animate function.
There seem to be some shades and styles where the anti-aliasing change is less obvious (at least in the fiddle), so you could also try styling the placeholders and other effected text differently.
(This thread may help with styling the placeholders, if you go that route: Change an HTML5 input's placeholder color with CSS )
Thanks to the identification of anti-aliasing above, as well as help from the articles below, I modified my code to include translate3d(0,0,0) and the problem disappeared:
-webkit-transition-duration: .17s, .17s translate3d(0,0,0);
The transition isn't as smooth as it once was but that's a subject for another question.
Wonky text anti-aliasing when rotating with webkit-transform in Chrome
http://johanbrook.com/design/css/a-fix-for-antialiasing-issues-in-webkit-browsers/
http://www.webkit.org/blog/386/3d-transforms/
i had the same problem, while a transition some text became antialiased. this happen only in anchor text that are positioned relative e with z-index inside an element positioned and with z-index itself.
if i remove all position and index the problem disappear.
There is a similar problem using transition and translate3d. Sometimes any element on the page with :hover styles shows its hover behavior. I have this problem using a slider. Put the -webkit-transform: translateZ(0); to the :hover element and its behavior is normal.
For rotation() maybe it's fine, but for scale() It didn't worked the -webkit-transform: translateZ(0); formula.
I used :
-webkit-font-smoothing: antialiased;

How to make a div disappear on hover without it flickering when the mouse moves?

I've seen answers suggesting just display:none on the :hover css. But that makes the div flicker when the mouse is moving.
EDIT: Added jsfiddle
display:none will take the element out of the render tree, so it loses :hover state immediately, then reappears and gets :hover again, disappears, reappears, etc...
What you need is:
#elem { opacity:0; filter:alpha(opacity=0); }
It will leave the place empty, so no flickering will appear. (Demo or yours updated)
Optionally with CSS3, but will only work on latest browsers (excluding IE).
Edit: Here is an example # jsfiddle using both jquery and CSS3.
<html>
<head>
<title>CSS3 hover</title>
<style type="text/css">
#hover{
width:100px;
height:100px;
background-color:#000000;
-webkit-transition:opacity 0.2s ease;
-moz-transition:opacity 0.2s ease;
-o-transition:opacity 0.2s ease;
}
#hover:hover{
// Red(0-255), Blue(0-255), Green(0-255), Alpha (0-1)
background-color:rgba(100,100,100,0);
opacity:0;
}
</style>
</head>
<body>
<div id="hover"></div>
</body>
</html>
Use javascript to set a class (eg. invisible) on the object when hovered over. Then use css to display:none when the object has that invisible class. Since it doesn't exist anymore you will have to check mouse coordinates (or use another element mouse hover event) to remove the class and reset the invisible class.
If you have something like this:
div:hover
{
display:none;
}
Then there is no way for you to avoid flickering.
On :hover the element becomes invisible so it is not hovered anymore and it appears again.
As soon as it appears it is getting :hover again and ...
On :hover the element becomes invisible so it is not hovered anymore and it appears again.
As soon as it appears it is getting :hover again and ...
On :hover the element becomes invisible so it is not hovered anymore and it appears again.
As soon as it appears it is getting :hover again and ...
On :hover the element becomes invisible so it is not hovered anymore and it appears again.
As soon as it appears it is getting :hover again and ...
On :hover the element becomes invisible so it is not hovered anymore and it appears again.
As soon as it appears it is getting :hover again and ...
...
It flickers to be short.
A better option would be to use opacity, something like this:
div:hover
{
opacity:0;
}

Resources