I have a basic button, which I animate initially. But once animated, I want to add a new animation on hover; but it seems to not work for some reason.
For example:
button animation:
.container {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
max-height: 100%;
overflow: hidden;
}
.slide-btn {
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
background-color: #feffff;
box-shadow: 0 2px 20px 0 #686f7638;
margin-top: 10px;
width: 45px;
height: 45px;
animation: testing 1s ease-in forwards;
}
.slide-btn:hover {
transform: scale(1.5);
}
#keyframes testing {
to {
transform: translateX(100px);
}
}
<div class="container">
<div class="slide-btn">></div>
</div>
My guess is that for the CSS animation I'm using forwards, but I really need forwards to be there.
Yes, it's because the forwards that make the animation to override the transform. Instead of forwards you can do like below:
.container {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
max-height: 100%;
overflow: hidden;
}
.slide-btn {
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
background-color: #feffff;
box-shadow: 0 2px 20px 0 #686f7638;
margin-top: 10px;
width: 45px;
height: 45px;
transform: translateX(100px);
transition:0.5s;
animation: testing 1s ease-in;
}
.slide-btn:hover {
transform: translateX(100px) scale(1.5);
}
#keyframes testing {
from {
transform: translateX(0px);
}
}
<div class="container">
<div class="slide-btn">></div>
</div>
how about adding 'animation-fill-mode: none' to '.slide-btn:hover':
.slide-btn:hover {
animation-fill-mode: none;
transform: scale(1.5);
}
Related
I am studying CSS animation. I want my animation moving one by one, as I don't know JS I want to do it by CSS only. How can I do this? I faced the problem of rules from and to in animations, when I change them the animations don't work as expected.
I have the following HTML
body {
margin: 0;
background: grey;
}
main {
font-family: Open Sans;
text-transform: uppercase;
line-height: 1;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
background: transparent;
}
.animation {
width: 20em;
height: 4em;
margin: 1em auto;
position: relative;
}
.squares {
margin: auto;
background: red;
/* display: flex;
flex-wrap: wrap;
justify-content: center;*/
}
.small_square {
width: 10px;
height: 10px;
background-color: white;
text-align: center;
display: block;
text-align: center;
position: relative;
margin: 0;
padding: 0;
left: 48%;
animation: appearance_small 1s ease-in-out;
animation: move_around 3s ease-in-out;
*/
}
.big_square {
margin: auto;
width: 40px;
height: 40px;
background-color: black;
display: block;
position: relative;
top: 30px;
animation: appearance_big 1.3s ease-in-out;
animation-delay: 2s;
animation: spin 3s ease-in-out;
forwards;
}
#keyframes appearance_big {
0% {
transform: scale(0%);
}
100% {
opacity: 1;
}
}
#keyframes appearance_small {
0% {
opacity: 0;
transform: scale(0%);
top: 50px;
}
100% {
opacity: 1;
top: 0px;
}
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}
#keyframes move_around {
from {
transform: translate(50%, 50px) rotate(0turn) translate(-50%, -50px);
}
to {
transform: translate(50%, 50px) rotate(0.50turn) translate(-0%, -50px);
}
<main>
<div id="animation" class="animation">
<div class="squares">
<div class="small_square"></div>
<div class="big_square"></div>
</div>
</main>
I am trying to add scale up animation on a div.
I tried this using both transition and animation property.
In case of transition you can notice that when hovered out the animation is smoothly reversed. However, this doesn't happen when using animation property (the div transitions back to initial width instantly)
Can someone tell me:
Why this behaviour in case of animation only?
How can I achieve the same using animation property?
.animations {
display: flex;
padding: 80px;
width: 100vw;
height: 100vh;
background: linear-gradient(to right, #f3d2d2, white, #cee5f3);
}
.animations > div {
width: 200px;
height: 200px;
margin: 40px;
font-family: system-ui;
display: flex;
flex-direction: column;
align-items: center;
}
.animations > p {
color: black;
flex: 1;
text-align: center;
}
.animations .animated-box {
flex: 2;
width: 100%;
background: grey;
cursor: pointer;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
color: white;
}
.animated-box.scale-up {
}
.animated-box.scale-up:hover {
animation: scale-up 0.5s ease forwards;
transform: scale(1);
}
.animated-box.scale-up-with-mouseout {
transition: transform 0.5s ease-in;
}
.animated-box.scale-up-with-mouseout:hover {
transform: scale(1.2);
}
#keyframes scale-up {
100% {transform: scale(1.2)};
0%{transform: scale(1)};
}
<div class="animations">
<div>
<div class="animated-box scale-up">Hover me</div>
<p>Scale up (with keyframes)</p>
</div>
<div>
<div class="animated-box scale-up-with-mouseout">Hover me</div>
<p>Scale up (with transition)</p>
</div>
</div>
I am doing a typewriter effect where my name gets typed out, and the only thing that works to keep it centered is justify-content: center. The only thing is, I cannot put a paragraph underneath the flex item, and paragraph acts like it isn't there and nothing seems to work. I have tried top: 315px; but it doesn't work.
body {
min-height: 100%;
display: flex;
justify-content: center;
}
h1 {
position: absolute;
animation: type 1s steps(22), blinkTextCursor 500ms steps(44) infinite normal;
overflow: hidden;
white-space: nowrap;
border-right: 4px solid black;
width: 14ch;
transform: translateY(-50%) scale(2);
}
#keyframes type {
0% {
width: 0ch;
}
100% {
width: 15ch;
}
}
#keyframes blinkTextCursor {
from {
border-right-color: black;
}
to {
border-right-color: transparent;
}
#welcome {
position: relative;
top: 315px;
}
<body>
<h1>Hi, I'm Winston</h1>
<p id="welcome">text</p>
</body>
Just needed to remove position absolute and add a flex-direction which in your case is column
body {
min-height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
h1 {
animation: type 1s steps(22),
blinkTextCursor 500ms steps(44) infinite normal;
overflow: hidden;
white-space: nowrap;
border-right: 4px solid black;
width: 14ch;
transform:translateY(-50%) scale(2);
}
#keyframes type {
0% {
width: 0ch;
}
100% {
width: 15ch;
}
}
#keyframes blinkTextCursor{
from{
border-right-color:black;
}
to{
border-right-color:transparent;
}
#welcome {
position: relative;
top: 315px;
}
<body>
<h1>Hi, I'm Winston</h1>
<p id="welcome">text</p>
</body>
Add this to your css.
#welcome{
position: absolute;
margin-top: 100px;
}
Final CSS.
body {
min-height: 100%;
display: flex;
justify-content: center;
align-content: center;
}
h1 {
position: absolute;
animation: type 1s steps(22), blinkTextCursor 500ms steps(44) infinite normal;
overflow: hidden;
white-space: nowrap;
border-right: 4px solid black;
width: 14ch;
transform: translateY(-50%) scale(2);
}
#welcome{
position: absolute;
margin-top: 100px;
}
#keyframes type {
0% {
width: 0ch;
}
100% {
width: 15ch;
}
}
#keyframes blinkTextCursor {
from {
border-right-color: black;
}
to {
border-right-color: transparent;
}
}
I've made a heart with CSS and made it resize, go small - big every second, like normally. But I noticed this strange wobble, that I didn't really put there and is really painful to look at. I aware of few possible duplicate questions, but they didn't really help. Here's a fiddle.
html,
body,
.container {
height: 100%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
.heart {
display: flex;
justify-content: center;
align-items: center;
background-color: red;
transform: rotate(-45deg);
transform-style: preserve-3d;
animation: growMain 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.heart:after,
.heart:before {
background-color: red;
content: "";
border-radius: 50%;
position: absolute;
transform: translateZ(-1px);
}
.heart:after {
animation: growAfter 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.heart:before {
animation: growBefore 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes growMain {
from {
width: 50px;
height: 50px;
}
to {
width: 80px;
height: 80px;
}
}
#keyframes growAfter {
from {
left: 25px;
width: 50px;
height: 50px;
}
to {
left: 40px;
width: 80px;
height: 80px;
}
}
#keyframes growBefore {
from {
top: -25px;
width: 50px;
height: 50px;
}
to {
top: -40px;
width: 80px;
height: 80px;
}
}
.inner {
display: initial;
transform: rotate(45deg);
}
.text {
text-align: center;
color: white;
font-family: "Comic Sans MS";
font-size: 100%;
margin: 0;
}
<div class="container">
<div class="heart">
<div class="inner">
<p class="text">Some text</p>
</div>
</div>
</div>
Animating actual width/height/position tends to not perform super well, especially when doing multiple animations at once like you are here. Moving/resizing elements with transform tends to perform better.
In this case, I would recommend setting the initial size of your heart and then using a scale transformation to make the pulse effect. With this approach, you also get the added benefit of going from three animations to one, which is easier for the browser to handle, and you don't have to worry about syncing them all up.
In order to make the text not shrink along with the heart, you can put a wrapper around it, and absolutely position the text in the center of the wrapper, on top of the heart. Then just transform the heart itself, not the wrapper. (Or if you want the text to shrink along with the heart, keep the same HTML structure you have now.)
html,
body,
.container {
height: 100%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
.heart-wrapper {
position: relative;
width: 80px;
height: 80px;
}
.heart {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: red;
transform: rotate(-45deg) scale(1);
transform-style: preserve-3d;
animation: pulse 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.heart::before {
left: 40px;
}
.heart::after {
top: -40px;
}
.heart::after,
.heart::before {
background-color: red;
content: "";
width: 80px;
height: 80px;
border-radius: 50%;
position: absolute;
transform: translateZ(-1px);
}
#keyframes pulse {
from {
transform: rotate(-45deg) scale(1);
}
to {
transform: rotate(-45deg) scale(0.6);
}
}
.text {
position: absolute;
top: 40%; /* slightly off-center to the top, so it appears centered when the heart shrinks */
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: white;
font-family: "Comic Sans MS";
font-size: 100%;
margin: 0;
}
<div class="container">
<div class="heart-wrapper">
<div class="heart"></div>
<div class="text">some text</div>
</div>
</div>
I want to have an expanding radius that starts from the center of the div instead of it starting on the top left of the div.
Imagine the button has a pulsing outline that goes outwards. That pulsing outline should start from the middle of the div and go out.
See example here: https://jsbin.com/dinehoqaro/edit?html,css,output
You can see that the expansion is starting from the top left.
.circle {
background-color: white;
border: 1px solid red;
border-radius: 50%;
width: 50px;
height: 50px;
animation: pulse 1s infinte;
-webkit-animation: pulse 1.2s infinite;
}
button {
background-color: green;
border: none;
border-radius: 50%;
width: 50px;
height: 50px;
}
#-webkit-keyframes pulse {
from {
width: 50px;
height: 50px;
}
to {
width: 100px height: 100px;
}
}
#keyframes pulse {
from {
width: 50px;
height: 50px;
}
to {
width: 100px;
height: 100px;
}
}
<div class="circle"><button>click here</button></div>
Here's a general solution using CSS flexbox, transform and pseudo-elements.
body {
display: flex;
align-items: center;
justify-content: center;
background-color: lightyellow;
height: 100vh;
margin: 0;
}
#container {
display: flex;
align-items: center;
justify-content: center;
}
.sphere {
display: flex;
background: lightblue;
border-radius: 300px;
height: 100px;
width: 100px;
}
#container::after {
display: flex;
background: lightpink;
border-radius: 300px;
height: 250px;
width: 250px;
animation: pulsate 2.5s ease-out;
animation-iteration-count: infinite;
opacity: 0.0;
content: "";
z-index: -1;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
#keyframes pulsate {
0% {
transform: scale(0.1, 0.1);
opacity: 0.0;
}
50% {
opacity: 1.0;
}
100% {
transform: scale(1.2, 1.2);
opacity: 0.0;
}
}
<div id="container">
<div class="sphere"></div>
</div>
jsFiddle
Also see this awesome solution by #harry: How to create a pulsing glow ring animation in CSS?