Multiple animations with CSS3 not working as expected - html

I have a set of divs that I'm animating in different ways. The first one swings/flips onto the stack using:
#-webkit-keyframes cardflip {
from {
-webkit-transform: perspective(2000) rotateY(90deg);
-webkit-transform-origin: 100% 0%;
}
to {
-webkit-transform: perspective(2000) rotateY(0deg);
-webkit-transform-origin: 100% 0%;
-webkit-transform: translate3d(0, 0, 0);
}
}
While the others are using transforms:
#cards .card:nth-child(2) { -webkit-transform: translate3d(0, 171px, 0); transform: translate3d(0, 183px, 0); }
#cards .card:nth-child(3) { -webkit-transform: translate3d(0, 342px, 0); transform: translate3d(0, 352px, 0); }
#cards .card:nth-child(4) { -webkit-transform: translate3d(0, 513px, 0); transform: translate3d(0, 521px, 0); }
#cards .card:nth-child(5) { -webkit-transform: translate3d(0, 684px, 0); transform: translate3d(0, 690px, 0); }
#cards .card:nth-child(6) { -webkit-transform: translate3d(0, 855px, 0); transform: translate3d(0, 859px, 0); }
#cards .card:nth-child(7) { -webkit-transform: translate3d(0, 1026px, 0); transform: translate3d(0, 1028px, 0); }
What I expect to happen is when I add a new div in the first position the other 'cards' slide down, and the first one flips into the top position. But it seems that the way I have it set up, the sliding animation doesn't happen when I add the new div on top of the stack, it just snaps to its new position. How can I fix this?
By the way, I'm only working in Chrome, hence the lack of non-webkit prefixes.
Fiddle.

You have to do it with a little bit of javascript, toggling a class instead. This is because the CSS selector of first child is immediately used and because transferring from an animation to a transition doesn't work the way you might think it might
var count = 0;
setInterval(function() {
$('#cards').prepend('<div class="card">testadd' + count++ + '</div>' );
setTimeout(function() {
document.getElementsByClassName("card")[0].className = "card first";
}, 10); // Fire just after it's added so it transitions
$('#cards .card:last').remove();
}, 5000);
CSS
#cards .first { -webkit-transform:translate3d(0,0,0) rotateY(0deg); }
#cards .card:nth-child(1) { z-index: 1000; }
Demo
(The count was for testing purposes)

Related

CSS: Infinitely looping animation doesn't interpolate between the first and last keyframes

I'm fairly certain I'm noticing this right and I can't seem to find a proper solution anywhere. I have a CSS animation that's meant to loop infinitely, it already works but has a problem.
// CSS
#keyframes myanim {
0% { transform: translate(0, 0) rotate(0deg) skewX(0deg); }
25% { transform: translate(5px, 5px) rotate(1deg) skewX(1deg); }
50% { transform: translate(0, 0) rotate(0eg) skewX(0deg); }
75% { transform: translate(-5px, -5px) rotate(-1deg) skewX(-1deg); }
100% { transform: translate(0, 0) rotate(0deg) skewX(0deg); }
}
// JS
element.style.animation = "myanim " + mytimer + "s infinite";
Keyframe interpolation doesn't seem to work around the seams. Between points 0% and 100% there's no interpolation: When the animation just started or is approaching the end each iteration, it slows down / sets into place / speeds up instead of maintaining its constant rhythm like between the other keyframes. It it possible to tell the browser to interpret all keyframes in a circular manner for the loop to work as intended?
# MirceaKitsune is right you need to use the linear animation property.
I tried out the animation and it works, here is the fiddle:
.animated-heading {
animation: linear myanim 2s infinite;
}
#keyframes myanim {
0% {
transform: translate(0, 0) rotate(0deg) skewX(0deg);
}
12.5% {
transform: translate(2.5px, 2.5px) rotate(0.5deg) skewX(0.5deg);
}
25% {
transform: translate(5px, 5px) rotate(1deg) skewX(1deg);
}
37.5% {
transform: translate(2.5px, 2.5px) rotate(0.5deg) skewX(0.5deg);
}
50% {
transform: translate(0, 0) rotate(0eg) skewX(0deg);
}
62.5% {
transform: translate(-2.5px, -2.5px) rotate(-0.5deg) skewX(-0.5deg);
}
75% {
transform: translate(-5px, -5px) rotate(-1deg) skewX(-1deg);
}
87.5% {
transform: translate(-2.5px, -2.5px) rotate(-0.5deg) skewX(-0.5deg);
}
100% {
transform: translate(0, 0) rotate(0deg) skewX(0deg);
}
}
<h1 class="animated-heading">animated-heading</h1>

Forge ControlGroup.addControl(Button) -> Slide-In Transition

Is there a possibility to have a transition when adding dynamically a new button to the control group?
For example, in this code, it would be nice to show the new button with a slide-In.
valuesOfParameter.forEach(valueOfParameter => {
// iterative Button
var buttonIterativ = new Autodesk.Viewing.UI.Button(valueOfParameter);
// Click Event
buttonIterativ.onClick = (event) => {
console.log(valueOfParameter);
};
buttonIterativ.addClass(valueOfParameter);
controlGroup.addControl(buttonIterativ);
// controlGroup.addControl(buttonIterativ);
$('#' + valueOfParameter).append('<style>.' + valueOfParameter + ':before{content: attr(data-before); font-size: 20px; color: white;}</style>');
$('#' + valueOfParameter.toString()).attr('data-before', valueOfParameter);
});
Thank you
The easiest way would be to go with CSS3 animation - you can pull it off with no code level changes required, e.g.:
.buttonSlide_in{
animation: slideMe .7s ease-in;
}
#keyframes slideMe{
0%{
transform: skewX(53deg) translateX(-500px);
opacity: 0;
}
60%{
transform: translateX(0px);
}
62%{
transform: skewX(0deg) translateX(30px);
}
70%{
transform: skew(-20deg);
opacity: 1;
}
80%{
transform: skew(0deg) translate(0);
}
90%{
transform: skew(-5deg);
}
100%{
transform: skew(0deg);
}
}
See here to get started and you'd get the attention from the right community if you add more relevant tags such as HTML/CSS animation to your question

css transitions: hover out transition not working if hover in is not allowed to complete

I have a div, for which css transitions are applied on hover,
on hover in, a transition is applied on the :before element, and on hover out, same transition (reversed) is applied on the :before element.
here is the html:
<section class="strips">
<article class="strips__strip">
<div class="strip__content">
<h1 class="strip__title">Title</h1>
</div>
</article>
</section>
and (important parts of) the css:
.strips .strip__content:hover:before {
transform: skew(180deg) scale(1) translate(0, 0);
opacity: 0.1;
}
.strips .strip__content:before {
content: "";
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: white;
opacity: 0.05;
transform-origin: center center;
transform: skew(180deg) scaleY(0) translate(0, 0);
transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}
Now, the transitions work smoothly if i allow tem to finish, but say, if i dont allow the hover in transition to finish , and quickly hover out, then the hover out transition does not work.
here is a fiddle:
https://jsfiddle.net/x2pavnac/
(try hovering out before the transition finishes).
I am not sure why this happens and how this issue can be addressed in css.
EDIT:
i have simplified the transition and also increased opacity, so it is more visible.
Updated fiddle: https://jsfiddle.net/x2pavnac/4/
I am not sure why this works well for others, but i found a typo in my css which was the issue in my case:
.strips .strip__content:before {
transform: skew(180deg) scaleY(0) translate(0, 0);
}
.strips .strip__content:hover:before {
transform: skew(180deg) scale(1) translate(0, 0);
opacity: 0.1;
}
should be
.strips .strip__content:before {
transform: skew(180deg) scaleY(0) translate(0, 0);
}
.strips .strip__content:hover:before {
transform: skew(180deg) scaleY(1) translate(0, 0);
opacity: 0.1;
}
notice the scaleY(1) instead of scale(1).
I am still not sure why it worked correctly for others though, even with the typo.

Pure CSS transform scale from current value

When applying a CSS scale transform to an element, is it possible to set the 'from' value as the current scale?
For example, consider the following 2 CSS keyframes used to apply separate growing and shrinking animation transforms:
#-webkit-keyframes grow
{
from { -webkit-transform: scale(0,0); }
to { -webkit-transform: scale(1,1); }
}
#-webkit-keyframes shrink
{
from { -webkit-transform: scale(1,1); }
to { -webkit-transform: scale(0,0); }
}
This will successfully scale the element it's applied to, but always from 0 to 1 (or vice-versa). If the shrink keyframe gets applied before the grow keyframe has finished, it has the effect of 'jumping' the scale to 0 before the transform begins.
You can see this effect in this jsFiddle showing CSS scale transform on mouseover
Notice that if you mouse over the black square and then quickly mouse out, the scale transform is not smooth.
What I'm essentially after is something like the following:
#-webkit-keyframes grow
{
from { -webkit-transform: CURRENT_SCALE; }
to { -webkit-transform: scale(1,1); }
}
Your animation makes the element go from 0% scale to 100% scale on hover, and from 100% to 0% scale on mouseOut.
I think in this case, the solution could be setting the basic scale of the element according to its start point :
#output
{
width: 200px;
height: 200px;
border-radius: 50%;
background: #FF0000;
display: inline-block;
-ms-transform: scale(0,0);
transform: scale(0,0);
-webkit-transform: scale(0,0);
}
In this case, I would harldy recommend using pure CSS solution, using transition on :hover : http://jsfiddle.net/bg6aj/21/
You wont have any "jumping" effect :
#output
{
width: 200px;
height: 200px;
border-radius: 50%;
background: #FF0000;
display: block;
-ms-transform: scale(0,0);
transform: scale(0,0);
-webkit-transform: scale(0,0);
transition: all .2s;
-webkit-transition: all .2s;
}
#touchPad:hover + #output {
-ms-transform: scale(1,1);
transform: scale(1,1);
-webkit-transform: scale(1,1);
}
At this point, you'll have no more jumping effect.
Then : can we do something like :
#-webkit-keyframes grow
{
from { -webkit-transform: scale(0,0); }
to { -webkit-transform: scale(1,1); }
}
Answer : quite easy :
#-webkit-keyframes grow
{
0% { -webkit-transform: scale(1,1); }
50% { -webkit-transform: scale(0,0); }
100% { -webkit-transform: scale(1,1); }
}
Which means: take my element (as scale default is 100%), render it with 0% scale at 50% of the animation, and turn it back at 100%. Trying to set something like current_scale doesn't make sense.
Considering that, I'll definitely choose the Transition solution.

Can you use CSS to mirror/flip text?

Is it possible to use CSS/CSS3 to mirror text?
Specifically, I have this scissors char “✂” (✂) that I'd like to display pointing left and not right.
You can use CSS transformations to achieve this. A horizontal flip would involve scaling the div like this:
-moz-transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
transform: scale(-1, 1);
And a vertical flip would involve scaling the div like this:
-moz-transform: scale(1, -1);
-webkit-transform: scale(1, -1);
-o-transform: scale(1, -1);
-ms-transform: scale(1, -1);
transform: scale(1, -1);
DEMO:
span{ display: inline-block; margin:1em; }
.flip_H{ transform: scale(-1, 1); color:red; }
.flip_V{ transform: scale(1, -1); color:green; }
<span class='flip_H'>Demo text ✂</span>
<span class='flip_V'>Demo text ✂</span>
-moz-transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
transform: scale(-1, 1);
The two parameters are X axis, and Y axis, -1 will be a mirror, but you can scale to any size you like to suit your needs. Upside down and backwards would be (-1, -1).
If you're interested in the best option available for cross browser support back in 2011, see my older answer.
Real mirror:
.mirror{
display: inline-block;
font-size: 30px;
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
-moz-transform: matrix(-1, 0, 0, 1, 0, 0);
-o-transform: matrix(-1, 0, 0, 1, 0, 0);
transform: matrix(-1, 0, 0, 1, 0, 0);
}
<span class='mirror'>Mirror Text<span>
You can user either
.your-class{
position:absolute;
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
}
or
.your-class{
position:absolute;
transform: rotate(360deg) scaleX(-1);
}
Notice that setting position to absolute is very important! If you won't set it, you will need to set display: inline-block;
I cobbled together this solution by scouring the Internet including
Stack Overflow answers,
MSDN articles,
http://css-tricks.com/almanac/properties/t/transform/,
http://caniuse.com/#search=transform,
http://browserhacks.com/, and
http://www.useragentman.com/IETransformsTranslator/.
This solution seems to work in all browsers including IE6+, using scale(-1,1) (a proper mirror) and appropriate filter/-ms-filter properties when necessary (IE6-8):
/* Cross-browser mirroring of content. Note that CSS pre-processors
like Less cough on the media hack.
Microsoft recommends using BasicImage as a more efficent/faster form of
mirroring, instead of FlipH or some kind of Matrix scaling/transform.
#see http://msdn.microsoft.com/en-us/library/ms532972%28v=vs.85%29.aspx
#see http://msdn.microsoft.com/en-us/library/ms532992%28v=vs.85%29.aspx
*/
/* IE8 only via hack: necessary because IE9+ will also interpret -ms-filter,
and mirroring something that's already mirrored results in no net change! */
#media \0screen {
.mirror {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(mirror=1)";
}
}
.mirror {
/* IE6 and 7 via hack */
*filter: progid:DXImageTransform.Microsoft.BasicImage(mirror=1);
/* Standards browsers, including IE9+ */
-moz-transform: scale(-1,1);
-ms-transform: scale(-1,1);
-o-transform: scale(-1,1); /* Op 11.5 only */
-webkit-transform: scale(-1,1);
transform: scale(-1,1);
}
There's also the rotateY for a real mirror one:
transform: rotateY(180deg);
Which, perhaps, is even more clear and understandable.
EDIT: Doesn't seem to work on Opera though… sadly. But it works fine on Firefox. I guess it might required to implicitly say that we are doing some kind of translate3d perhaps? Or something like that.
For cross browser compatibility create this class
.mirror-icon:before {
-webkit-transform: scale(-1, 1);
-moz-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
transform: scale(-1, 1);
}
And add it to your icon class, i.e.
<i class="icon-search mirror-icon"></i>
to get a search icon with the handle on the left
you can use 'transform' to achieve this.
http://jsfiddle.net/aRcQ8/
css:
-moz-transform: rotate(-180deg);
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
Just adding a working demo for horizontal and vertical mirror flip.
.horizontal-flip {
-moz-transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
transform: scale(-1, 1);
}
.vertical-flip {
-moz-transform: scale(1, -1);
-webkit-transform: scale(1, -1);
-o-transform: scale(1, -1);
-ms-transform: scale(1, -1);
transform: scale(1, -1);
}
<div class="horizontal-flip">
Hello, World
<input type="text">
</div>
<hr>
<div class="vertical-flip">
Hello, World
<input type="text">
</div>
That works fine with font icons like 's7 stroke icons' and 'font-awesome':
.mirror {
display: inline-block;
transform: scaleX(-1);
}
And then on target element:
<button>
<span class="s7-back mirror"></span>
<span>Next</span>
</button>
Just one more example how the character could be flipped. Add vendor prefixes if you need ones but for now all modern browsers support unprefixed transform property. The only exception is Opera if Opera Mini mode is enabled (~3% world users).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Text rotation</title>
<style type="text/css" media="screen">
.scissors {
display: inline-block;
font-size: 50px;
color: red;
}
.original {
color: initial;
}
.flipped {
transform: rotateZ(180deg);
}
.upward {
transform: rotateZ(-90deg);
}
.downward {
transform: rotateZ(90deg);
}
</style>
</head>
<body>
<ul>
<li>Original: <span class="scissors original">✂</span></li>
<li>Flipped: <span class="scissors flipped">✂</span></li>
<li>Upward: <span class="scissors upward">✂</span></li>
<li>Downward: <span class="scissors downward">✂</span></li>
</ul>
</body>
</html>
We can make pretty cool text effects using very little code, with css keyframes, and its alternate property (try removing alternate to see the difference):
span {
font-weight: 1000; font-size: 3.3em;
}
small {
display: inline-block;
font-size: 2.3em;
animation: 1s infinite alternate coolrotate
}
#keyframes coolrotate {
from {
transform: scale(1, 1) translate(-0.1em, 0)
}
to {
transform: scale(-1, 1) translate(0, 0)
}
}
<span>
<span>c</span>
<small>o</small>
<span>o</span>
<small>L</small>
<small>...</small>
</span>
this is what worked for me for <span class="navigation-pipe">></span>
display:inline-block;
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=4);
just need display:inline-block or block to rotate. So basically first answer is good. But -180 didn't worked.
You could try box-reflect
box-reflect: 20px right;
see CSS property box-reflect compatibility? for more details
direction: rtl; is probably what you are looking for.