CSS Animation Starting From Middle - css

I have a pretty simple animation that has borders that I created animate in width, in height, and then the center fades in.
The issue I'm having is I can't figure out how to animate from the center, rather than left to right (for the top and bottom borders) and top to bottom (for the side borders).
Is there any simple way to get the animation to happen from the middle?
Example of the code for the top and bottom animation:
#keyframes tb {
0% {width: 0;}
100% {width: 800px}
}
JSFiddle of the code.

You need to animate the left and top, too. For the horizontal bars, set the property left to 400px (50%) on the first keyframe, and to 0px on the last keyframe. Same goes for the vertical bars. Here is your fixed example:
#import url(https://fonts.googleapis.com/css?family=Montserrat:700);
html{
background: black;
}
#holder{
width: 800px;
display: block;
position: relative;
}
#follower {
display: block;
text-align: center;
padding: 20px;
font-family: 'Montserrat', sans-serif;
font-size: 30px;
line-height: 70px;
color: #fff;
background: rgba(255,255,255,.1);
animation: main 2s ease-out;
-webkit-animation: main 2s ease-out;
}
#keyframes main {
0% {opacity: 0}
50% {opacity: 0}
100%{opacity: 1}
}
#-webkit-keyframes main {
0% {opacity: 0}
50% {opacity: 0}
100%{opacity: 1}
}
#t, #b {
width: 800px;
height: 2px;
background: #fff;
position: absolute;
display: block;
animation: tb .5s 1 ease-out;
-webkit-animation: tb .5s 1 ease-out;
}
#t {
top: 0;
left: 0;
}
#b{
bottom: 0;
left: 0;
}
#r, #l {
width: 2px;
height: 110px;
background: #fff;
position: absolute;
display: block;
animation: rl 1s 1 ease-out;
-webkit-animation: rl 1s 1 ease-out;
}
#r{
left: 0;
top: 0;
}
#l {
right: 0;
top: 0;
}
#keyframes tb {
0% {
width: 0;
left: 400px;
}
100% {
width: 800px
left: 0;
}
}
#keyframes rl {
0% {height: 0}
50% {
height: 0;
top: 55px;
}
100% {
height: 110px;
top: 0;
}
}
<div id="holder">
<div id="t"></div>
<div id="b"></div>
<div id="r"></div>
<div id="l"></div>
<div id="follower">
Super Long Text Goest Here!
</div>
</div>

You can play around with your timing, and make it start at right point in your animation... using an animation-delay.
E.g.
#keyframes makeFatter {
0% {width: 0;}
100% {width: 800px}
}
#makeMeFat {
animation-name: makeFatter;
animation-duration: 5s;
animation-delay: -2.5s; /* Makes it start at 50% of your animation, i.e. width: 400px */
/* blah blah... rest of the CSS code */
}

Related

CSS Animation changing height is jittering

I'm trying to make an animation for drawing a square border on hover.
It's working fine but when drawing the left side of the border the bottom of the border is jittering
Here's a link to the codepen https://codepen.io/Taggagii/pen/GRxYpXY to see the code and the jittering that's happening.
My approach is to just animate the ::before element to render the top and right sides and the ::after element to render the bottom and left sides. To animate both of them I'm just modifying their width and height attributes so it doesn't really make sense to me that only the bottom is jittery and not all the sides.
Note: This issue is present on Chrome but not on Firefox
html {
background: #f58442;
}
.center {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.border-renderer {
--border-size: 1px;
--animation-duration: 4s;
--border-z-index: -1;
--border-color: black;
--second-border-final-extent: calc(100% + 2 * var(--border-size));
--first-border-final-extent: calc(100% + var(--border-size));
--size: 200px;
position: relative;
display: inline-block;
background: #ccba87;
padding: 10px;
font-size: 5em;
margin-left: 35vw;
margin-top: 40vh;
}
.border-renderer::before,
.border-renderer::after {
content: '';
background: var(--border-color);
position: absolute;
z-index: var(--border-z-index);
}
.border-renderer::before {
top: calc(-1 * var(--border-size));
left: 0;
}
.border-renderer::after {
top: var(--first-border-final-extent);
right: calc(-1 * var(--border-size));
transform: translateY(-100%);
}
.border-renderer:hover::before {
animation-name: draw-box-top-right;
animation-duration: calc(var(--animation-duration) / 2);
animation-timing-function: ease;
animation-fill-mode: forwards;
}
.border-renderer:hover::after {
animation-name: draw-box-bottom-left;
animation-duration: calc(var(--animation-duration) / 2);
animation-delay: calc(var(--animation-duration) / 2);
animation-timing-function: ease;
animation-fill-mode: forwards;
}
#keyframes draw-box-top-right {
0% {
width: 0%;
height: var(--border-size);
}
50% {
width: var(--first-border-final-extent);
height: var(--border-size);
}
100% {
width: var(--first-border-final-extent);
height: var(--first-border-final-extent);
}
}
#keyframes draw-box-bottom-left {
0% {
width: var(--border-size);
height: var(--border-size);
}
50% {
width: var(--second-border-final-extent);
height: var(--border-size);
}
100% {
width: var(--second-border-final-extent);
height: var(--second-border-final-extent);
}
}
<div class="holder">
<div class="border-renderer">
<div class="center">Mouse over me</div>
</div>
</div>

Is it possible to make CSS Pie timer run only once?

I use CSS Pie Timer, and I struggle to make my pie loading animation run only once.
The order I want the animation to be in:
the circle is not shown
the circle is starting to fill up with a border color
the circle get filled fully
the circle stays filled (and doesn't repeat)
Demo here
<div class="wrapper">
<div class="pie spinner"></div>
<div class="pie filler"></div>
<div class="mask"></div>
</div>
Help will be appreciated!
You just have to remove animation-iteration-count - infinite and add animation-fill-mode as forwards.
Here is the working code
.wrapper {
position: relative;
margin: 40px auto;
background: white;
}
.wrapper, .wrapper * {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.wrapper {
width: 250px;
height: 250px;
}
.wrapper .pie {
width: 50%;
height: 100%;
transform-origin: 100% 50%;
position: absolute;
background: #08C;
border: 5px solid rgba(0,0,0,0.5);
}
.wrapper .spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 200;
border-right: none;
animation: rota 5s linear forwards;
}
.wrapper:hover .spinner,
.wrapper:hover .filler,
.wrapper:hover .mask {
animation-play-state: running;
}
.wrapper .filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
opacity: 0;
z-index: 100;
animation: opa 5s steps(1, end) forwards reverse;
border-left: none;
}
.wrapper .mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 300;
animation: opa 5s steps(1, end) forwards;
}
#keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes opa {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
<div class="wrapper">
<div class="pie spinner"></div>
<div class="pie filler"></div>
<div class="mask"></div>
</div>

Strike in and out animation on hover

I'm trying to make a strikethrough animation like the effect here:
The strike line appears from left to right and disappears from left to right.
#keyframes strike {
0% {
width: 0;
}
50% {
width: 100%;
}
100% {
width: 0;
}
}
.strike {
position: relative;
}
.strike:hover:after {
content: ' ';
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 1px;
background: black;
animation-name: strike;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-fill-mode: fill;
animation-direction: normal;
}
<div>
The text in the span <span class="strike">is what I want to strike out</span>.
</div>
Is there a way to achieve that only with CSS ?
You can use transforms and transform-origin in the keyframe animation to make strike-through apear from left to right and disapear from left to right.
The point is to scale the pseudo element on the X axis for 0 to 1 with a transform origin on the left then back to 0 with a transform origin on the right (similar to this hover effect see last example of the answer).
And here is an example with your markup :
#keyframes strike{
0% { transform-origin: 0% 50%;transform:scaleX(0); }
50% { transform-origin: 0% 50%;transform:scaleX(1); }
50.01% { transform-origin:100% 50%;transform:scaleX(1); }
100% { transform-origin:100% 50%;transform:scaleX(0); }
}
.strike {
position: relative;
}
.strike:hover:after {
content: ' ';
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 1px;
background: black;
animation: strike .75s ease-in-out forwards;
}
<div>
The text in the span <span class="strike">is what I want to strike out</span>.
</div>
Here is a sample using transition, where it on hover toggle left/right position.
.strike {
position: relative;
}
.strike::after {
content: ' ';
position: absolute;
top: 50%;
left: 0;
right: 100%;
height: 1px;
background: black;
}
.strike:hover::after {
right: 0;
left: 100%;
transition: right .5s .0s, left .5s .5s;
}
<div>
The text in the span <span class="strike">is what I want to strike out</span>.
</div>

CSS-Animation go to the right

I have a problem with CSS currently.
https://jsfiddle.net/k9cfdofv/1/
There you can see that the
stripe (parallelogram) comes from the bottom, but it goes a little bit to right before it goes in that state I want it.
So I want it come from the bottom and go to the top without this shift at the end.
CSS-Code:
.stripe {
width: 100px;
height: 100px;
margin-left: 100px;
background: red;
transform: skew(-10deg);
animation: ani 1s linear 1 forwards;
position: absolute;
bottom: 10px;
}
#keyframes ani {
0% {
height: 0px;
}
100% {
height: 700px;
}
}
It can be done by setting a transform-origin for element to be skewed to left bottom.
div {
width: 100px;
height: 100px;
margin-left: 100px;
background: red;
transform: skew(-10deg);
transform-origin: left bottom;
animation: ani 1s linear 10 forwards;
position: absolute;
bottom: 10px;
}
#keyframes ani {
0% {
height: 0px;
}
100% {
height: 700px;
}
}
<div>
</div>

Animate CSS background-position with smooth results (sub-pixel animation)

I'm trying to animate the background-position of a div, slowly, but without it having jerky movement. You can see the result of my current efforts here:
http://jsfiddle.net/5pVr4/2/
#-webkit-keyframes MOVE-BG {
from {
background-position: 0% 0%
}
to {
background-position: 187% 0%
}
}
#content {
width: 100%;
height: 300px;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
text-align: center;
font-size: 26px;
color: #000;
-webkit-animation-name: MOVE-BG;
-webkit-animation-duration: 100s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
}
I have been at this for hours and can't find anything that will animate slowly and smoothly at a sub-pixel level. My current example was made from the example code on this page: http://css-tricks.com/parallax-background-css3/
The smoothness of animation I'm after can be seen on this page's translate() example:
http://css-tricks.com/tale-of-animation-performance/
If it can't be done with the background-position, is there a way to fake the repeating background with multiple divs and move those divs using translate?
Checkout this example:
#content {
height: 300px;
text-align: center;
font-size: 26px;
color: #000;
position:relative;
}
.bg{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
animation-name: MOVE-BG;
animation-duration: 100s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
#keyframes MOVE-BG {
from {
transform: translateX(0);
}
to {
transform: translateX(-187%);
}
}
<div id="content">Foreground content
<div class="bg"></div>
</div>
http://jsfiddle.net/5pVr4/4/
Animating background-position will cause some performance issues. Browsers will animate transform properties much cheaply, including translate.
Here is an example using translate for an infinite slide animation (without prefixes):
http://jsfiddle.net/brunomuller/5pVr4/504/
#-webkit-keyframes bg-slide {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.wrapper {
position:relative;
width:400px;
height: 300px;
overflow:hidden;
}
.content {
position: relative;
text-align: center;
font-size: 26px;
color: #000;
}
.bg {
width: 200%;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) repeat-x;
position:absolute;
top: 0;
bottom: 0;
left: 0;
animation: bg-slide 20s linear infinite;
}
You should adjust your HTML and CSS little bit
Working Demo
HTML
<div id="wrapper">
<div id="page">
Foreground content
</div>
<div id="content"> </div>
</div>
CSS
#-webkit-keyframes MOVE-BG {
from { left: 0; }
to { left: -2000px; }
}
#wrapper {
position:relative;
width:800px;
height: 300px;
overflow:hidden;
}
#page {
text-align: center;
font-size: 26px;
color: #000;
}
#content {
width: 2000px;
height: 300px;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
position:absolute;
top: 0;
left: 0;
z-index:-1;
-webkit-animation-name: MOVE-BG;
-webkit-animation-duration: 100s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
}

Resources