I'm using CSS column count property to achieve 2 columns. When I have a button with hover animation - the first column button works fine but the 2nd column button give a weird jump on hover.
For container I'm using
column-count: 2;
for button its
transition: all ease-in .2s;
transform: translateX(0);
and button hover its
transform: translateX(10px);
I've made a little fiddle for demonstration. Its not working only in Chrome - weirdly.
http://jsfiddle.net/jp6vt97g/2/
Any Idea guys?
There seems to be a bug in Chrome when using transform inside columns. As a workaround, you can animate margin-left instead of transform.
.cta-txt {
display: inline-block;
transition: all ease-in .2s;
margin-left: 0;
}
.cta-txt:hover{
margin-left: 10px;
}
http://jsfiddle.net/dfgueg49/1/
Related
I found some code for a link hover effect and while it works fine, I don't understand why it works.
Specifically:
#navbar a:after {
content: '';
position: absolute;
left: 0;
display: inline-block;
height: 1em;
width: 100%;
border-bottom: 1px solid;
margin-top: 10px;
opacity: 0;
-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
transition: opacity 0.35s, transform 0.35s;
-webkit-transform: scale(0,1);
transform: scale(0,1);
}
#navbar a:hover:after {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(0.9);
}
This produces an underline effect on the link when hovering.
My question is:
1.) Why doesn't the transition/transform on the a:after take place when the page loads? Why does it only occur when hovering over the element (even though it's not within the hover)?
Although I can obviously see what is occurring from viewing the page, trying to better understand how exactly this works.
I have added one fiddle where you can go and check the code
[https://jsfiddle.net/vickykumarui/96xw3fzv/][1]
Now let me explain what is happening on hover
Initially you have add this code for pseudo element after
transform: scale(0.1); // The scale() function is specified with either one or two values, which represent the amount of scaling to be applied in each direction.
opacity: 1; // initially after element is not visible
Now on hover this property changes to
transform: scale(0.9);
opacity: 1;
When these properties changes it does not changes suddenly but it changes slowly in .35s in animated way from this code
transition: opacity 0.35s, transform 0.35s;
transition is applied on both property opacity and transform and 0.35s is time of transition
Note: Based on your comment if you change initial property to
opacity: 1;
transform: scale(0.9);
You see that coming initially also
It does happen. Change the opacity to 1 in the first rule. You don't see it because it's technically hidden when the page loads. When you hover, the opacity becomes one and becomes visible.
I have blog post with set of images that are enlarged on hover. My problem is that when i enlarge element and it overlaps with other image that is later in page render order then the next image is on top of the enlarged one.
The easy way to stop this is to give some kind of z-index on :hover pseudo selector. But then i have very pesky problem when just after I stop hovering my image then next one is on top of it for fraction of second.
You can see behaviour in this imgur album or on jsfiddle(hover first image)
In short i have following css for hovering effect:
.photo-exp
{
position: relative;
transition: all .4s ease-in-out;
/* some properties deleted which have no connection to hovering effect */
}
.photo-exp:hover
{
transform: scale(1.7);
z-index : 10;
}
It would be very easy to have same effect with javascript and setTimeout function.
But i would like to avoid javascript solution and have some CSS workaround which will change slowly z-index in time after hovering ends.
I tried CSS transition but it is not working
I tried to eddit this snippet but i could not get it working in the way that i wanted.
You need to assign a new transition-delay property, and remove it as soon as the hover begins. That way the z-index can persist for some time even after the mouse is gone. It's a little counter-intuitive; I would expect that the delay should be added on hover and removed off-hover but the opposite works on chrome:
.expander {
position: absolute;
left: 50%; top: 50%;
width: 100px; height: 100px;
margin-top: -50px; margin-left: -50px;
z-index: 1;
transition: transform 400ms 0ms, z-index 0ms 400ms; /* That final "400ms" delays the z-index transition! */
}
.expander:hover {
transform: scale(1.8);
z-index: 2; /* A hovered expander is always on top */
transition: transform 400ms 0ms, z-index 0ms 0ms; /* Remove the z-index transition delay on hover. This is counter-intuitive but works. */
}
.expander:nth-child(1) {
margin-left: -105px;
background-color: #a00000;
}
.expander:nth-child(2) {
margin-left: 5px;
background-color: #00af00;
}
<div class="expander"></div>
<div class="expander"></div>
Note that (unless you try to mouse around really quickly in order to break it) neither square bleeds through the other, not even for a frame, when they expand.
I've also finally managed to solve by myself my problem.
It's more intuitive than #Gershom Maes answer in my opinion.
Fiddle
I have used animation system to achieve the result.
#keyframes nohovering {
0% { z-index: 9; }
100% { z-index: 1; }
}
#keyframes hovering {
0% { z-index: 10; }
100% { z-index: 10; }
}
First one will be by default fired on selector without :hover like this
animation: nohovering 0.9s;
It will guarantee that after i complete my hovering it will go smoothly down from z-index 9 to z-index 1. After hovering my image will be on top of other images. When i tested it for z-index 10 for 0% i had a little glitch when i tried to hovered 2 images at same time and then hover only 1 of them.
For my hovering selector I used:
animation: hovering 0.1s infinite;
It will just loop my image on z-index 10. On hover it will always be on top of the other images. Short animation time guarantee that it will go off after hovering stopped in maximum time of 0.1s.
After deleting normal static z-indexes it works.
I'm trying to create a slightly animated pushable button.
My goal is to achieve a button like this:
see the source code (jsfiddle)
with using exactly one HTML tag and the minimal amount of new CSS features like transform and transition.
However as you see in the jsfiddle; if you click the button at least twice the whole line (and the content beneath) bounces too.
That is ofcourse because of the margin set within the :active selector.
My second approach was using the the CSS transform property. That worked perfectly except I still had the need the change the height of the button (which will result in the same problem).
So my question is: How can I achieve the same effect without adjusting the positions of other elements?
How can I achieve the same effect without adjusting the positions of other elements?
I suggest using position: relative; for the button, then set top: 2px for :active pseudo-class, as follows:
button {
/* Other styles... */
position: relative; /* position the element as relative */
outline: none; /* Just added for the demo */
}
button:active {
top: 2px; /* move the element without affecting the others' position */
box-shadow: inset 0px 2px 1px 0px rgba(0, 0, 0, .1);
}
JSFiddle Demo.
You can use transform: translate property over top/left properties (Check here if you know why) and of course if you don't care about legacy IE browsers:
button {
....
transition: all .1s ease-in-out;
-moz-transition: all .1s ease-in-out;
-webkit-transition: all .1s ease-in-out;
....
}
button:active {
transform: translatey(2px);
-moz-transform: translatey(2px);
-webkit-transform: translatey(2px);
...
}
Demo
Would like to know how to hide an div after a set of css3 animation. Here's my code:
#box {
position: absolute;
top: 200px;
left: 200px;
width: 200px;
height: 150px;
background-color: red;
}
#box:hover {
-webkit-animation: scaleme 1s;
}
#-webkit-keyframes scaleme {
0% {
-webkit-transform: scale(1);
opacity: 1;
}
100% {
-webkit-transform: scale(3);
opacity: 0;
display: none;
}
}
<div id='box'>
hover me
</div>
Here's the jsfiddle sample for better illustration:
http://jsfiddle.net/mochatony/Pu5Jf/18/
Any idea how to do hide the box permanently, best without javascript?
Unfortunately there is no best solution using only CSS3. Animations always return to theirs default values (see at Safari Developer Library).
But you can try to play with -webkit-animation-fill-mode property.
For example:
#box:hover{
-webkit-animation:scaleme 1s;
-webkit-animation-fill-mode: forwards;
}
It's at least not immediately return a box to display:block; state.
Using JavaScript you can do this by using webkitAnimationEnd event.
For example:
var myBox = document.getElementById('box');
myBox.addEventListener('webkitAnimationEnd',function( event ) { myBox.style.display = 'none'; }, false);
Example on jsFiddle
Change your animation definition to:
-webkit-animation:scaleme 1s forwards;
This is a value for the animation fill mode. A value of 'forwards' tells the animation to apply the property values defined in its last executing keyframe after the final iteration of the animation, until the animation style is removed.
Of course in your example the animation style will be removed when the hover is removed. At the moment I can see the need for a small piece of JavaScript to add a class which triggers the animation. Since the class would never be removed (until the page is reloaded) the div would stay hidden.
Since elements of CSS animations end in their original CSS state, make the original state hidden by scaling it to zero or removing its opacity:
div.container {
transform: scale(0);
-webkit-transform: scale(0);
}
or
div.container {
opacity: 0;
}
Once the animation is completed, the div will go back to its original CSS, which is hidden.
That can (kind of) be solved without using JavaScript. Since animations use keyframes, what you ask for is possible by setting the duration time to a way too high value, say 1000s, and letting you transition end at a low frame, for example 0.1%.
By doing this, the animation never ends and therefore stay in shape.
#box:hover {
-webkit-animation:scaleme 1000s;
}
#-webkit-keyframes scaleme {
0% { -webkit-transform: scale(1); opacity: 1; }
0.1%, 100% { -webkit-transform: scale(3); opacity: 0;display:none; }
}
1000s is not necessary in this particular example though. 10s should be enough for hover effects.
It is, however, also possible to skip the animation and use basic transitions instead.
#box2:hover {
-webkit-transition: all 1s;
-moz-transition: all 1s;
-o-transition: all 1s;
transition: all 1s;
-moz-transform: scale(3);
-webkit-transform: scale(3);
opacity: 0;
}
I forked your fiddle and altered it, adding the two for comparison: http://jsfiddle.net/madr/Ru8wu/3/
(I also added -moz- since there is no reason not to. -o- or -ms- might also be of interest).
I have this animation which I use for a div appear on screen so it comes from the bottom and stays at its final position.
#-webkit-keyframes slide {
from { opacity: 0; -webkit-transform: translateY(500px); }
to { opacity: 1; -webkit-transform: translateY(0); }
}
.module {
-webkit-animation: slide .4s 0 1 normal ease none;
}
I was thinking if it is possible that when I assign class='done' for that div it could take the same animation and play it reversely simulating the same effect hiding the div.
like:
.module.done {
-webkit-animation: slide .4s 0 1 alternate ease none;
}
but it seems it always start from the 1 iteration in the second case I would like to reverse the animation so it could start from the original position and then slide up 500px
Is it possible to achieve using the same animation or do I have to create a new one with inverted values?
Thanks
This specific use case works best with CSS transitions, plus you get free Opera and FF 3.5+ support. This is the basic syntax:
#notice {
-vendor-transition: -webkit-transform 2s ease;
}
#notice.pop {
-vendor-transform: translateY(50px);
}
When you add or remove .pop, the animation is automatically done for you.
Check out the working example:
http://jsfiddle.net/qLKzX/
I believe you can do this by setting the animation-delay to an appropriate negative value (so it starts at the first reversal).