I've always been inspired by the HUD display in Iron Man. Specifically how the icons fly in at the initial loading of the suit like here:
https://www.youtube.com/watch?feature=player_embedded&v=ZwOxM0-byvc
However, I haven't found a way in CSS get the images to start at the center of the page, drop to the bottom and then slide into their respective spots. I figured that I would have to use something like this:
from {
opacity: .5;
position: absolute;
left: 50%;
transform: translate3d(0, -100px, 0);
animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
}
60% {
opacity: 1;
position: absolute;
left: 50%;
transform: translate3d(0, 0, 0);
animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
}
to{
left: 0%
}
However, when I do that it creates a weird jitter as it doesn't appear to know how to make the transition smoothly from left center (50% absolute) to then it's respective placement on the page.
Ideas?
Related
This is making me crazy and I hope that someone can give me a simple solution.
So I have a app on my website that allows you to like or dislike Recipes. When disliking there is an animation sending the image to the left, when liking the animation sends the image to the right (based on the Tinder swiping).
On my laptop everything works fine, but when I load the website on my mobile phone after the left animation is done the page is going back to the top, making me scroll back down every time I like something.
The dislike button works just fine. And if I change the Yes animation to the exact same like the No, it works. So it's really something with that animation.
I think the issue is caused because the image goes out of the screen and it then loads back at the top. But I don't understand why it doesn't happen when going to the left and I can't find a good solution
#keyframes yes {
0% {
transform: scale(1) rotateZ(0deg);
left: 0;
}
30% {
transform: scale(1.05) rotateZ(0deg);
left: 0;
}
100% {
transform: rotateZ(45deg);
left: 400px;
}
}
.animateYes {
animation-fill-mode: both;
animation: yes 0.6s linear;
}
.animateYes:before {
transform: rotateZ(-35deg);
background: url(https://i.imgur.com/Zkwj970.png) no-repeat center 10px;
}
#keyframes no {
0% {
transform: rotateZ(360deg);
right: 0;
}
30% {
transform: scale(1.05) rotateZ(360deg);
right: 0;
}
100% {
transform: rotateZ(315deg);
right: 400px;
}
}
.animateNo {
animation-fill-mode: both;
animation: no 0.6s linear;
}
.animateNo:before {
transform: rotateZ(35deg);
background: url(https://i.imgur.com/XqQZ4KR.png) no-repeat center 10px;
}
This is the website: http://ons-kookboek.atwebpages.com/test.html
I'm a beginner in everything about html and CSS and most of my website is copy paste from the internet without me understanding what it exactly does.
it's been awhile. Anyway, having some trouble getting an absolutely positioned element to stay center while animating. What's more is I'm seeing the element "shift" after the animation is complete and I have no idea why. Closest issue I found was css animations moves element position but that didn't solve for this common use case.
Debugging the animation frames, we can see the following:
During animation
After animation
Yuck! Playing with positioning didn't work, but animation-fill-mode did something; however, I noticed translate has no effect on the positioned element during animation or when animation-fill-mode is set to forwards or both. Why? The side effect is when the animation completes the element's position will not be recalculated so no repaint.
Example:
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>Holy guacamole!</strong> You should check in on some of those fields below.
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
and the CSS using animate.css to make life easy:
.alert {
min-width: 500px;
position: absolute;
top: 0;
left: 50%;
animation-name: fadeInDown;
animation-duration: 0.75s;
animation-timing-function: ease-in-out;
/* animation-fill-mode: forwards; */
transform: translateX(-50%);
}
Demo: https://codepen.io/atomicpages/pen/yrymVY?editors=1100
Goals:
Center aligned
Element is at least 500px
Element doesn't move after animation frame completes
Your help is appreciated.
Use custom fadeInDown without animate.css because it is using transform: translate3d(0, -100%, 0) in fadeIndown
.alert {
width: 500px;
top: 0;
left: 50%;
animation-name: fadeInDown;
animation-duration: 0.75s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
transform: translateX(-50%);
position:absolute;
}
#keyframes fadeInDown{
from{
opacity:0;
}
to{
opacity:1;
}
}
#-webkit-keyframes fadeInDown{
from{
opacity:0;
}
to{
opacity:1;
}
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>Holy guacamole!</strong> You should check in on some of those fields below.
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
Try removing transform: translateX, after the animation, the element stays where it is, and change it to left: 0;
.alert {
min-width: 500px;
top: 0;
left: 0;
animation-name: fadeInDown;
animation-duration: 0.75s;
animation-timing-function: ease-in-out;
}
The reason is that the built-in fadeInDown also use transform for its animation, hence resets/override your initial value, and restore it after, unless you use animation-fill-mode: forwards;, which will keep it 50% off the left edge all the time.
And do note, preset transform "values", like translateX doesn't persist when another "value" is added to the "property", all existing values gets overwritten.
Original CSS
#keyframes fadeInDown {
from {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
For yours to work you need to override the built-in one, adding your translateX value to it, and it will behave.
And if you do, there is a prefixed #keyframes rule as well, which also need to be updated.
New CSS
#keyframes fadeInDown {
from {
opacity: 0;
-webkit-transform: translate3d(-50%, -100%, 0);
transform: translate3d(-50%, -100%, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(-50%, 0, 0);
transform: translate3d(-50%, 0, 0);
}
}
As a side note:
With the provided setting it will always take full width and centering it would have no effect, unless you also gave it a max-width somewhere else.
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.
I am not very good at CSS3 animations so I need some help to improve the output.
I am trying to achieve the Windows8 tile effect and I am nearly done.
I am trying to achieve this
and here is the jsfiddle
The CSS which flips is the following.
The suffix '1' is for block1 ,'2' for block2 and so on 'til 5 for five blocks.
/*block one*/
.flip-container1, .front1, .back1 {
position:relative;
width: 432px;
height: 140px;
}
.flipper1 {
-webkit-transition: 0.6s;
-webkit-transform-style: preserve-3d;
-moz-transition: 0.6s;
-moz-transform-style: preserve-3d;
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
.front1, .back1 {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
background: #2FB1BE;
}
.vertical1.flip-container1 {
position: relative;
}
.vertical1 .back1 {
-webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
transform: rotateX(180deg);
}
.vertical1.flip-container1 .flipper1 {
-webkit-transform-origin: 100% 70px;
-moz-transform-origin: 100% 70px;
transform-origin: 100% 70px;
}
#keyframes myFirst{
from{
webkit-transform: rotateX(-180deg);
-moz-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
to{
webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
transform: rotateX(180deg);
}
}
#-webkit-keyframes myFirst{
from{
webkit-transform: rotateX(-180deg);
-moz-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
to{
webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
transform: rotateX(180deg);
}
}
.vertical1.flip-container1 .flipper1{
animation:myFirst 3s;
-webkit-animation:myFirst 3s;
animation-direction:normal;
-webkit-animation-direction:normal;
animation-iteration-count:infinite;
}
Now I want to solve the following two problems:
1- I want that only one tile flips at a time.
Currently, I have applied different animation times which looks fine but multiple tiles are flipping at a time.
2- I want the animation of a particular tile to stop when the backside is shown and then move to another tile and when again its turn comes then front side is shown again. Currently, it shows front side and then immediately shows back side and then pauses for a while.
For your first problem, you'll want to use the :hover pseudo tag, and if needed also use tile-specific ids.
I don't quite understand what you mean by "then move to another tile and when again its turn comes then front side is shown again". But, you have animation-iteration-count: set to infinite so of course the animation will continue on infinitely.
It seems you don't quite understand CSS animations/transitions fully yet. Perhaps you should practice with just making a box grow on mouse hover, then work your way up to making just 1 box flip. W3Schools has a great reference to CSS Animations.
It appears both IE 10 and Firefox snaps elements to whole pixels when animating their position using translate 2d transform in a css keyframe animation.
Chrome and Safari does not, which looks a lot better when animating subtle movements.
The animation is done the following way:
#keyframes bobbingAnim {
0% {
transform: translate(0px, 0px);
animation-timing-function:ease-in-out
}
50% {
transform: translate(0px, 12px);
animation-timing-function:ease-in-out
}
100% {
transform: translate(0px, 0px);
animation-timing-function:ease-in-out
}
}
Here's an example of what I mean:
http://jsfiddle.net/yZgTM/.
Just open it in Chrome and IE 10 (or Firefox) and you should notice the difference in smoothness of the motion.
I realise there might be many factors affecting this behaviour such as if the element is drawn with hardware acceleration or not.
Does anyone know of a fix to try to force browsers to always draw the elements on subpixels?
I found this similar question, but the answer was to animate using a translate transform, which is exactly what I'm doing:
CSS3 Transitions 'snap to pixel'.
Update:
After playing around a bit I found a fix for Firefox, doesn't do anything in IE 10 though. The trick is to scale down the element ever so slightly and use translate3d with a 1px offset in the Z-axis:
#keyframes bobbingAnim {
0% {
transform: scale(0.999, 0.999) translate3d(0px, 0px, 1px);
animation-timing-function:ease-in-out
}
50% {
transform: scale(0.999, 0.999) translate3d(0px, 12px, 1px);
animation-timing-function:ease-in-out
}
100% {
transform: scale(0.999, 0.999) translate3d(0px, 0px, 1px);
animation-timing-function:ease-in-out
}
}
I love your question!
Good job in noticing the pixel-snap in firefox and IE10.
I've researched this subject a while ago and I advise you to check the GSAP forums, as they contain a lot of useful information on web animations.
Here's a topic regarding IE10 pixel-snap issue.
What you need to do is add a minimal rotation to the element. This is so IE and Firefox will redraw it in a different way - which will stop pixel-snap for good :)
Tyr this:
#keyframes bobbingAnim {
0% {
transform: translate(0px, 0px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
50% {
transform: translate(0px, 12px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
100% {
transform: translate(0px, 0px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
}
#Nemanja is correct you will find that if you tweak the speed you will see better results this is fairly typical with css animations. Also it doesn't really make a difference in this case if you enable hardware acceleration. I tidied up the code a little bit and ran it without any issues, i do not have ie10; However, I have 11. You may have to just remove the second transform of translateZ if it doesn't run in 10
body {
background-color: #ccc;
}
.bobbing {
position: absolute;
animation: bobbingAnim ease-in-out .5s infinite;
-moz-animation: bobbingAnim ease-in-out .5s infinite;
-webkit-animation: bobbingAnim ease-in-out .5s infinite;
}
.bobbing.text {
font-size: 50px;
color: #000;
left: 30px;
top: 30px;
}
.bobbing.image {
left: 30px;
top: 150px;
background: url(http://placehold.it/300x100/aa0000&text=Bobbing+image) 50% 50% no-repeat;
width: 310px;
height: 110px;
}
#keyframes bobbingAnim {
50% {
transform: translate(0, 12px) translateZ(0);
}
}
#-webkit-keyframes bobbingAnim {
50% {
-webkit-transform: translate3d(0, 12px, 0);
}
}
#-moz-keyframes bobbingAnim {
50% {
-moz-transform: translate3d(0, 12px, 0);
}
}
There cant be half a pixel movement, there is no such thing.
Your problem is the speed and smoothness of the animation, not the "pixel snapping".