To witness the bug, hover on the right-side of the overlay box here (don't move your mouse even 1px after hovering):
http://jsfiddle.net/V99rf/
<style>
.container, .hoverMover {width:100px; height:100px; background:rgba(0,0,0,.2);}
.container {position:relative;}
.hoverMover {position:absolute; top:0; left:50px;}
.container:hover .hoverMover {background:green; left:0;}
.trans {-webkit-transition: all 1s ease-in-out; transition: all 1s ease-in-out;}
</style>
<div class="container">
<div class="hoverMover trans">
</div>
</div>
Notice that even after the dom element moves to the left, it remains green with a ":hover" being set. This gets unset as soon as you move the mouse. How do I make it unset when the dom element moves from under the mouse, even if the mouse isn't moved?
A recursive javascript timeout would be unsatisfying, but may be the only way...?
This is only possible with an event, so you will need some sort of iterative loop to accomplish what you are looking for.
Related
I found a wired thing when I apply the transform to an element, it changes the z-index order, the code as:
<button class="test">
click me
</button>
css:
.test{
border-radius:100px;
transition:all 1s;
position:relative;
}
.test:hover{
transform:translateY(30px);
}
.test::after{
content:'';
position:absolute;
z-index:-1;
top:0;
left:0;
background:blue;
width:100%;
height:100%;
}
codepen: https://codepen.io/JianNCI/pen/jZQRpz?editors=1100
I was intending to hide the :: after content by setting thez-index order to -1 and I am setting the blue background color for distinguishing them. but once I hovering on the button, the hiding content will overlap the button. so my questions are:
Why the z-index:-1not working when I hovering on it? it is supposed to remain as -1 since I only set the transform property within the hover effect.
When I replace the transform property like color: red, it is work as I expected. So I am wondering if this the transform makes the z-index:-1 lose effect in this case?
If there's a better way of doing what I'm about to ask, please let me know, but so far this is the best I could come up with
I want to have a set of divs that contain a sliding div inside of them. The sliding divs would contain content pulled from the latest post. So they might not always be exactly the same height.
The start position would be to have the title showing, then have the whole div show when the parent is hovered over.
The problem I'm having with only using bottom position is that when the screen gets too thin, more than just the title shows up. Using top, I do lose some of the title, but I'm willing to sacrifice that.
So instead I decided to use both top and bottom, and just flip where auto is in order to make the complete div show. (I don't want to have the sliding div to be the same height as the containing div)
When I do this though, the transition doesn't work. I tried using top, bottom, and all in the transition, but it's all the same result - no transition.
Can someone please explain a) Why this isn't working b) what would make it work without going to jQuery.
HTML:
<div class="innerLeftPosts">
<div class="mainPostHome">
<div class="postSlideCover">
<h3>Hello this is a test</h3>
<p>This is some test content that would go in here and take up some space</p>
</div>
</div>
<div class="secondaryPostHome">
<div class="postSlideCover">
<h3>Hello this is a test</h3>
<p>This is some test content that would go in here and take up some space</p>
</div>
</div>
</div>
CSS:
.postSlideCover{
width:calc(100% - 20px);
height:auto;
position:absolute;
transition:all 0.4s ease-out;
-webkit-transition:all 0.4s ease-out;
}
.mainPostHome .postSlideCover{
top:83%;
bottom:auto;
}
.mainPostHome:hover .postSlideCover{
top:auto;
bottom:0;
}
Fiddle for full and visual example: https://jsfiddle.net/60nxpfs8/
Here:
.postSlideCover{
width:calc(100% - 20px);
height:auto;
position:absolute;
transition:all 0.4s ease-out;
-webkit-transition:all 0.4s ease-out;
bottom: 0;
}
.mainPostHome .postSlideCover{
transform: translateY(60%);
}
.mainPostHome:hover .postSlideCover{
transform: translateY(0);
}
With a JSFiddle
We can use the transform property translateY to use the height of the element as the metric which we move it (100% relates to 100% of the element height). This has the added benefit of being able to use hardware acceleration (as opposed to software) to animate.
When adding transitions to an element and altering the width and/or height and -webkit-transform:translate3d, the transition animation stutters. It appears to animate the width/height change first, as well translate it partially, then snaps to the final translated position. When returning to the original style, however, the animation is smooth. I'm only seeing this in Safari (version 8.0.6 tested). Here's some example css
#foo{
width:100%;
height:200px;
border:1px solid black;
position:relative;
}
#poop{
width:25px;
height:25px;
background-color:green;
position:absolute;
right:50%;
top:50%;
-webkit-transition: all 1s;
transform:translate3d(0,0,0);
-webkit-transform:translate3d(0,0,0);
}
#foo .blah{
transform:translate3d(-100%,-100%,0);
-webkit-transform:translate3d(-100%,-100%,0);
width:100px;
height:100px; }
And a jsfiddle http://jsfiddle.net/84w4hj99/4/
I'm using jquery to add a class to the element on a button click for the sake of demonstration, but first noticed it when using :hover to get the same effect. Am I missing something here or is it just a problem with Safari, and does anyone know a workaround? Thanks.
Try using transform: scale() instead of changing the width and height. You will have a smooth transition in this case. However, you will have to adjust the top & right or transform: translate3D() properties to position your object back to the correct position. Should be easy.
See http://jsfiddle.net/y3xqak1z/
In the fiddle below, I've a transition on visibility and opacity separately. The latter works but the former doesn't. Moreover, in case of visibility, the transition time is interpreted as delay on hover out. Happens in both Chrome & Firefox. Is this a bug?
http://jsfiddle.net/0r218mdo/3/
Case 1:
#inner{
visibility:hidden;
transition:visibility 1000ms;
}
#outer:hover #inner{
visibility:visible;
}
Case 2:
#inner1{
opacity:0;
transition:opacity 1000ms;
}
#outer1:hover #inner1{
opacity:1;
}
This is not a bug- you can only transition on ordinal/calculable properties (an easy way of thinking of this is any property with a numeric start and end number value..though there are a few exceptions).
This is because transitions work by calculating keyframes between two values, and producing an animation by extrapolating intermediate amounts.
visibility in this case is a binary setting (visible/hidden), so once the transition duration elapses, the property simply switches state, you see this as a delay- but it can actually be seen as the final keyframe of the transition animation, with the intermediary keyframes not having been calculated (what constitutes the values between hidden/visible? Opacity? Dimension? As it is not explicit, they are not calculated).
opacity is a value setting (0-1), so keyframes can be calculated across the duration provided.
A list of transitionable (animatable) properties can be found here
Visibility is animatable. Check this blog post about it: http://www.greywyvern.com/?post=337
You can see it here too: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
Let's say you have a menu that you want to fade-in and fade-out on mouse hover. If you use opacity:0 only, your transparent menu will still be there and it will animate when you hover the invisible area. But if you add visibility:hidden, you can eliminate this problem:
div {
width:100px;
height:20px;
}
.menu {
visibility:hidden;
opacity:0;
transition:visibility 0.3s linear,opacity 0.3s linear;
background:#eee;
width:100px;
margin:0;
padding:5px;
list-style:none;
}
div:hover > .menu {
visibility:visible;
opacity:1;
}
<div>
Open Menu
<ul class="menu">
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Visibility is an animatable property according to the spec, but transitions on visibility do not work gradually, as one might expect. Instead transitions on visibility delay hiding an element. On the other hand making an element visible works immediately. This is as it is defined by the spec (in the case of the default timing function) and as it is implemented in the browsers.
This also is a useful behavior, since in fact one can imagine various visual effects to hide an element. Fading out an element is just one kind of visual effect that is specified using opacity. Other visual effects might move away the element using e.g. the transform property, also see http://taccgl.org/blog/css-transition-visibility.html
It is often useful to combine the opacity transition with a visibility transition! Although opacity appears to do the right thing, fully transparent elements (with opacity:0) still receive mouse events. So e.g. links on an element that was faded out with an opacity transition alone, still respond to clicks (although not visible) and links behind the faded element do not work (although being visible through the faded element). See http://taccgl.org/blog/css-transition-opacity-for-fade-effects.html.
This strange behavior can be avoided by just using both transitions, the transition on visibility and the transition on opacity. Thereby the visibility property is used to disable mouse events for the element while opacity is used for the visual effect. However care must be taken not to hide the element while the visual effect is playing, which would otherwise not be visible. Here the special semantics of the visibility transition becomes handy. When hiding an element the element stays visible while playing the visual effect and is hidden afterwards. On the other hand when revealing an element, the visibility transition makes the element visible immediately, i.e. before playing the visual effect.
If you want to delay the visibility then the code snippet below could be a solution.
Because the 'visibility' property is on/off you could use the transition-delay property to control the timing of when the object should be visible.
div {
width:100px;
height:20px;
}
.menu {
transition-delay: 0s;
transition-duration: 0s;
transition-property: opacity;
background:#eee;
width:100px;
margin:0;
height: 0px;
opacity: 0;
list-style:none;
overflow: hidden;
}
div:hover > .menu {
height: initial;
transition-delay: 1s;
opacity: 1;
}
<div>
Open Menu
<ul class="menu">
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
I have successfully animated a div using #keyframes but I need to alter properties of child elements of that div at the same time. Is there a way to address a child element from within a keyframe?
HTML
<div class="layoutBlocks" id="layoutBlock1">
<div class="Wrappers">
<div class="transparentBG"> <!--semi=transparent underlay-->
</div>
</div>
<div class="Wrappers">
<div class="articles" id="article1">
<table>
<tr><th>heading</th></tr>
<tr><td>article</td></tr>
</table>
</div>
</div>
CSS
#layoutBlock1 {
left: 0%;
top: 0%;
width: 49.75%;
height: 49.25%;
-webkit-animation: LlB1 1s;
animation: LlB1 1s;
}
#-webkit-keyframes LlB1 {
0% {width:50%; height:50%; z-index: 1;}
100% {width:100%; height:100%; z-index: 100;}
}
#keyframes LlB1 {
0% {width:50; height:50%; z-index: 1;}
100% {width:100%; height:100%; z-index: 100;}
}
(All the extra wrappers are to make the semi-transparent background and rounded corners work on Android.)
(I think transforms might be easier than keyframes here but my ultimate goal is to add a few more effects down the line.)
As my keyframe moves & resizes the layoutBlock1 div, I want to make the semi-transparent underlay opaque, but since it's a child element, I can't figure out how to address it. Is this possible?
Addressing the child node from the keyframe is not possible.
But, there might be a few hacks:
Having another animation with the same duration, but with animation and settings for the child node
Another way to achieve this is to use some of the JS libraries for animation. Eg.: https://animejs.com
You cannot change a child element from within a keyframe unless that keyframe has been called on the element. You could have another animation going on, and you could assign that to the child element and set it to have the same duration.
If you want the same animation to happen to the child element, you could just call the keyframe on the child element.