There is an issue with this property, while trying to animate a text, I'm using a text cursor to follow the text but on certain point of the animation this "cursor" (just a line) doesn't do what I put on the code, so... I don't know what is happening to it.
Here you have the piece of code:
.code {
position: relative;
width: 0px;
height: 180px;
animation: coding 1.4s;
animation-fill-mode: forwards;
animation-timing-function: steps(20);
overflow: hidden;
}
#keyframes coding {
0% {
width: 0;
}
100% {
width: 230px;
}
}
.code p {
color: red;
width: 258px;
letter-spacing: 3px;
display: inline-block;
}
.code span {
position: absolute;
top: 10px;
right: 0;
color: red;
animation: cods 7s;
animation-fill-mode: forwards;
font-size: 20px;
}
#keyframes cods {
0% {
opacity: 1;
top: 10px;
right: 0;
}
50% {
top: 10px;
right: 0;
}
75% {
top: 30px;
right: 0;
}
100% {
top: 30px;
left: 0;
}
}
<div class="code">
<p><I am the animated text></p><span>|</span>
</div>
as you see here, the cursor first go to the left and then go to the bottom, but that's not on the code. from 50% to 75% I'm telling: "go 20px down" and then from 75% to 100%: "go left".
Fixed it by changing left: 0 into right: 100% in the 100% keyframe!
Related
I have this Keyframe Animation where i move a dot in a square:
* {
margin: 0;
padding: 0;
}
#dot {
height: 10px;
width: 10px;
background: #000;
border-radius: 100%;
position: absolute;
animation: moveDotOne 2s infinite;
transition: all 0.3s;
top: 0;
left: 0;
}
#keyframes moveDotOne {
0% {
top: 0;
}
25% {
top: 20px;
}
50% {
left: 20px;
}
75% {
top: 0;
}
100% {
left: 0;
}
}
<div id="dot"></div>
The only problem is that the 25% keyframe is already running when the 0% isn't even finished. How can i fix that?
Think about what the animation is making it transition the value from.
When it hits 50% it sets left: 20px. So it then transitions from something to 20px. What is that something?
You haven't specified anything. So it is the default value.
You can't transition from auto so it jumps.
Set starting values for left and top in your CSS. Don't assign them only with the animation.
As pointed out you need to think about both x&y positions for the transitions - added variables here to make the effect easier to observe. At each keyframe a x and y position (top,left) are specified.
* {
margin: 0;
padding: 0;
}
:root{
--d:80px;
--w:90px;
}
#box{
padding:1rem;border:1px solid red;
width:var(--w);
height:var(--w);
}
#dot {
height: 10px;
width: 10px;
background: #000;
border-radius: 100%;
position: absolute;
animation: moveDotOne 5s infinite;
transition: all 0.3s;
margin:1rem;
}
#keyframes moveDotOne {
0% {
top:0;
left:0;
}
25% {
top:var(--d);
left:0;
}
50% {
top:var(--d);
left:var(--d);
}
75% {
top:0;
left:var(--d);
}
100%{
top:0;
left:0;
}
}
<div id='box'>
<div id="dot"></div>
</div>
I have created a border-like keyframe CSS style. When I hover the button the border-like animation should start from top-right to top-left then to bottom-left then after to bottom-right and finally to top-right again. When I hover the button the previous sequence should happen and is already created. However; when hovered, the text inside the button moves, which makes the button looks weird.
I looked at the answer to this question, but it's not applicable in my case as I am not using border styling on hover. Instead, I am changing the background color, width, and height of the three spans, not borders.
How can I prevent this shake with the method the animation is created?
CodePen: https://codepen.io/Tes3awy/pen/ZZRpBW
HTML
<div class="wrapper">
<a class="custom-btn" href="https://mince.34way.com/about/" title="About">
About Us
<span class="border-top"></span>
<span class="border-right"></span>
<span class="border-bottom"></span>
<span class="border-left"></span>
</a>
</div>
CSS
body {
position: relative;
height: 100vh;
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.custom-btn {
position: relative;
width: 183px;
height: 55px;
line-height: 55px;
display: inline-block;
text-align: center;
text-transform: uppercase;
margin: 0 auto;
border: 2px solid #77a942;
color: #77a942;
text-decoration: none;
}
span[class^="border-"] {
opacity: 0;
}
.border-top {
position: absolute;
top: -2px;
right: 0;
width: 100%;
height: 3px;
background-color: transparent;
}
.border-left {
position: absolute;
top: 0;
left: -2px;
width: 3px;
height: 100%;
background-color: transparent;
}
.border-bottom {
position: absolute;
left: 0;
bottom: -2px;
width: 100%;
height: 3px;
background-color: transparent;
}
.border-right {
position: absolute;
bottom: 0;
right: -2px;
width: 3px;
height: 100%;
background-color: transparent;
}
.custom-btn:hover .border-top {
animation: animateTop .2s 1 alternate ease forwards;
}
.custom-btn:hover .border-left {
animation: animateLeft .2s 1 alternate ease forwards;
animation-delay: .2s;
}
.custom-btn:hover .border-bottom {
animation: animateBottom .2s 1 alternate ease forwards;
animation-delay: .4s;
}
.custom-btn:hover .border-right {
animation: animateRight .2s 1 alternate ease forwards;
animation-delay: .6s;
}
#keyframes animateTop {
0% {
width: 0;
height: 0;
opacity: 0;
background-color: #77a942;
}
50% {
width: 50%;
height: 3px;
opacity: 1;
background-color: #77a942;
}
100% {
width: 100%;
height: 3px;
opacity: 1;
background-color: #77a942;
}
}
#keyframes animateLeft {
0% {
width: 0;
height: 0;
opacity: 0;
background-color: #77a942;
}
50% {
width: 3px;
height: 50%;
opacity: 1;
background-color: #77a942;
}
100% {
width: 3px;
height: 100%;
opacity: 1;
background-color: #77a942;
}
}
#keyframes animateBottom {
0% {
width: 0;
height: 0;
opacity: 0;
background-color:#77a942;
}
50% {
width: 50%;
height: 3px;
opacity: 1;
background-color:#77a942;
}
100% {
width: 100%;
height: 3px;
opacity: 1;
background-color:#77a942;
}
}
#keyframes animateRight {
0% {
width: 0;
height: 0;
opacity: 0;
background-color: #77a942;
}
50% {
width: 3px;
height: 50%;
opacity: 1;
background-color: #77a942;
}
100% {
width: 3px;
height: 100%;
opacity: 1;
background-color: #77a942;
}
}
When you translate things by 50%, they may end up in-between pixels. When you use a transition, CSS tends to change its mind on what pixel it rounds to. Try to make sure that the button you're centering text in has height/width that CSS has a definite position it can settle on when you divide it by half.
I have a simple animation running on an element which loops moving a "star" element from place to place using absolute positioning. It fades in and out briefly using opacity before moving to the next location, then repeating. This works fine in Chrome and Firefox, but of course IE/Edge is having issues. It can best be seen here: Codepen
Issue: In IE/Edge the animation runs correctly through the first iteration, but as soon as the animation starts looping, the opacity and absolute position changes get out of sync to the point where the "star" is fading in/out WHILE it's moving which shouldn't be the case. Chrome shows the ideal animation steps: Fade In, Fade out, Move, Stop, Repeat.
Here's the code:
#import url(https://fonts.googleapis.com/css?family=Mr+Dafoe);
#-webkit-keyframes star-effect {
0% {
left: -7%;
top: 44%;
opacity: 0;
}
5% {
opacity: 1;
}
10% {
left: -7%;
top: 44%;
opacity: 0;
}
35% {
left: 44%;
top: 0%;
opacity: 0;
}
40% {
opacity: 1;
}
45% {
left: 44%;
top: 0%;
opacity: 0;
}
70% {
left: 90%;
top: 6%;
opacity: 0;
}
75% {
opacity: 1;
}
80% {
left: 90%;
top: 6%;
opacity: 0;
}
100% {
left: -7%;
top: 44%;
opacity: 0;
}
}
body{
background: #000;
margin: 0;
padding: 50px;
font-size: 16px;
width: 100%;
font-family: "Helvetica Neue",helvetica,Arial,sans-serif;
overflow-x: hidden;
}
h1{
position: relative;
height: 1.35em;
line-height: 1;
font-size: 10rem;
margin: 0;
transition: font-size .2s linear;
}
h1 > span:nth-child(1){
position: absolute;
padding-left: 30px;
padding-right: 50px;
top: 0px;
font-family: 'Mr Dafoe', cursive;
font-size: .87em;
margin-top: 0px;
margin-bottom: 0;
color: #fd5afa;
text-shadow: -2px -2px 0 #FFBAF2;
-webkit-filter: drop-shadow(3px 3px 1px #441F62);
-webkit-transform: skew(-5deg,-5deg);
font-weight: normal;
z-index: 2;
-webkit-backface-visibility: hidden;
}
h1 span.star{
position: absolute;
display: block;
left: -7%;
top: 44%;
width: 80px;
height: 80px;
z-index: 4;
opacity: 0;
-webkit-animation-name: star-effect;
animation-name: star-effect;
-webkit-animation-duration: 6s;
animation-duration: 6s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
h1 span.star:before{
position: absolute;
content: '';
background-image: -webkit-radial-gradient(#fff 20%, transparent 80%);
width: 100%;
height: 2px;
display: block;
top: 50%;
}
h1 span.star:after{
position: absolute;
content: '';
background-image: -webkit-radial-gradient(#fff 0%, transparent 90%);
width: 2px;
height: 100%;
display: block;
left: 50%;
}
<body>
<h1>
<span>Word<span class="star"></span></span>
</h1>
</body>
Here's a simple example of what I mean.
HTML
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
CSS
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
-
If you view in Chrome, both black bars slide out perfectly. The one transitioning from behind, and the one in front.
If you view it in Firefox, the bar transitioning from behind is broken. It sometimes works, but mostly it ignores the slide animation and just appears at the end of the animation duration.
I've re-created this a number of times and it seems that items that transition from behind another element are broken in firefox.
I've tried using -moz- which doesn't work. IS there anything else you can think of?
I've tried it without the absolute positioning, with z-indexs. and nothing seems to work.
EDIT ----
I appreciate work-around ideas, but I'd really like to know the route cause of this if anyone knows?
Thanks very much.
It seems Firefox is inconsistent when animate the transform property, and I can't say why (yet), most likely a bug though.
Here is 2 workarounds to achieve the same effect
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
0% {
transform: translateY(-1px);
}
0.1% {
transform: translateY(0px);
}
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 0px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
top: -20px;
}
}
#keyframes test-ani2 {
100% {
height: 20px;
bottom: -20px;
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
The solution relies on the z-index property of your elements: if you don't specify it the elements lay out one on top of the others, following the flow of the HTML document, when their "position" is set to "absolute". So "ht-txt1" is underneath "headtest" and "ht-tx2" is on top of "headtest".
To correct this "ht-tx1" and "ht-tx2" should take a "z-index" value of -1, so they are hidden underneath "headtest".
As for FF compatibility you need to prefix your "transform" effect with -moz-, check http://caniuse.com/#feat=transforms2d for more details.
Here's the CSS style code:
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
z-index: -1;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
z-index: -1;
}
#keyframes test-ani1 {
100% {
-ms-transform: translateY(-20px);
-webkit-transform: translateY(-20px);
-moz-transform: translateY(-20px);
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
-ms-transform: translateY(20px);
-webkit-transform: translateY(20px);
-moz-transform: translateY(20px);
transform: translateY(20px);
}
}
I'm trying to achieve this button animation on hover using only CSS solution :
I've succeed on find a way doing this with css keyframe , but now i'm facing some an unexpected slow motion effect, for now I'm only experimenting this with the top left corner here is what I've done so far :
HTML
<div class="borderTop"></div>
CSS
a {
width: 150px;
height: 50px;
border: 2px solid;
margin: 0 auto;
margin-top: 20%;
display: block;
}
a:hover .borderTop {
width: 10px;
height: 2px;
border-top: 2px solid;
position: relative;
top: -2px;
-webkit-animation: topTheleft 2s alternate;
animation: topTheleft 2s alternate;
}
.borderTop {
width: 10px;
height: 2px;
border-top: 2px solid;
position: relative;
top: -2px;
left: 50px;
}
#-webkit-keyframes topTheleft {
0% { left: -2px; }
50% { left: -30px; }
100% { left: -70px; display: none; }
}
#-o-keyframes topTheleft {
0% { left: -2px; }
50% { left: -30px; }
100% { left: -70px; display: none; }
}
#-moz-keyframes topTheleft {
0% { left: -2px; }
50% { left: -30px; }
100% { left: -70px; display: none; }
}
#keyframes topTheleft {
0% { left: -2px; }
50% { left: -30px; }
100% { left: -70px; display: none; }
}
LIVE DEMO
any help on how to avoid this slow motion on the middle of the animation would be highly appreciated , thank you in advance
edit, is there a way to make the line hide when reach the left: -70px with a transition effect not ansta-hide, any other solution to do it are welcome too
Try getting rid of the 50% lines:
#-webkit-keyframes topTheleft {
0% { left: -2px; }
100% { left: -70px; display: none; }
}
#-o-keyframes topTheleft {
0% { left: -2px; }
100% { left: -70px; display: none; }
}
#-moz-keyframes topTheleft {
0% { left: -2px; }
100% { left: -70px; display: none; }
}
#keyframes topTheleft {
0% { left: -2px; }
100% { left: -70px; display: none; }
}
It looks like the default timing function is ease-in-out : from one animation step to the other, the speed goes slow-fast-slow, to make it look more natural (real physics cannot make an object got from speed 0 to 100 instantaneously).
So what happens is the animation starts slow at 0%, goes fast, then slows down for the 50% step, then accelerates again
Is this what you are looking for ?
https://jsfiddle.net/kvyqyg19/1/
a:hover .borderTop {
/* .. */
-webkit-animation: topTheleft 2s alternate;
animation: topTheleft 2s alternate;
animation-timing-function: linear;
}
#-webkit-keyframes topTheleft {
0% { left: -2px; }
100% { left: -70px; display: none; }
}
/* .. */
I removed the middle (50%) step and set the animation-timing-function: linear;