Button loading indicator border animation - css

I want to animate the button while waiting for an async call to finish. Disabling the button and putting a spinner in the middle or next to it obviously works, but feels a little boring these days. I thought it would be neat to have a little border animation on loop. Similar to
https://codepen.io/sarath-ar/pen/dMKxxM
Specifically, the 3rd button they have demoed. It fills the border nicely on hover, but what I'm imagining is after it fills the border, it then undoes the border color in the same direction. It "chases" the other animation if you will.
I was fiddling with their css, but I can't seem to figure out how to loop the border animation (I did successfully reverse the animation), but I'm struggling to loop it due to the :before and :after.
So I guess the primary quest is, how do you loop an animation when it relies on the ::before and ::after css selectors. To simplify, how would I loop the below css? (I realize that isn't all the css, but in general how would you loop that?)
.btn-1::before{
right: 0;
top: 0;
}
.btn-1::after{
left: 0;
bottom: 0;
}
.btn-1:hover::before, .btn-1:hover::after{
transition-delay: 0s;
}

What you want to use is CSS animation and have it continue looping through the animation via animation-iteration-count: infinite.
Here's what this would look like: https://codepen.io/jerrylow/pen/eXmroN?editors=1100
For simplicity imaging we want each edge's duration to be 1s. The total time becomes 8s because 1s per side for 4 sides times 2 because there's the unwind cycle. A side's animation looks like this:
#keyframes btn-border-top {
0% {
left: auto;
right: 0;
width: 0%;
}
12.5% {
left: auto;
right: 0;
width: 100%;
}
12.6% {
left: 0;
right: auto;
}
50% {
width: 100%;
}
62.5% {
width: 0%;
}
100% {
left: 0;
right: auto;
width: 0%;
}
}
The animation will run for the whole 8s so 1/8th is 12.5% after a full cycle (4s) you want to unwind for the 5th second which is 50% - 62.5% (12.5 * 5). After that we want to keep it at "winded" up until the next cycle.
Edit: If you want an overlap for the cycle to kick in before the next cycle starts you can play with the percentage by calculating the time yourself.

Related

Is there a way to have transition only on a single CSS change?

I want to rotate and move a square (<img>) to a specific mouse click on screen.
I want the rotation to happen instantly, but the movement happen linearly, over a duration of time (distance/speed).
However, I can't find a way to separate these two actions. I set the img rotation first and afterwards set it's style.left/top with a style.transitionDuration, but the rotation ends up with a duration as well.
Is there a way to only include the transitionDuration on the change of left and top, thus excluding it from the rotation?
You can explicitly specify which properties to transition. If you want the rotation to be instant, just omit it from the transition:
document.querySelector('img')
.addEventListener('click',
({target}) => target.classList.toggle('clicked')
);
img {
top: 0;
left: 0;
position: absolute;
transition: top 1s ease, left 1s ease;
}
.clicked {
transform: rotate(90deg);
left: 100px;
top: 100px;
}
<img src="//placekitten.com/100" />
You can do it with the transition property.
img.style.transition = 'top 1s linear, left 1s linear';
Now the only transitions applied are for both top and left.

Animation disappears after animation in MSIE11

I have this strange bug in MSIE11, where an animated element disappears right after the end of an animation.
See this example
.cta-43274891247129739-info {
position: absolute;
left: 0;
top: 50px;
margin: 10px 10px;
animation: cta-43274891247129739 4s 1s both ease-out;
text-align: center;
}
#keyframes cta-43274891247129739 {
0% {
transform: translateY(1em);
opacity: 0;
}
16.6667%, 83.3333% {
opacity: 1;
transform: translateY(0em);
}
100% {
transform: translateY(-40px);
}
}
<div class="cta-43274891247129739-info">This animation fades in from the bottom, makes a short stop and then translates up to its final halt. But not on MSIE11, where it will dissappear apruptely at the end of the animation </div>
MSIE11 has issues with animations, particularly with calculations involving different units.
In your particular example, the animation works perfectly, until the very last keyframe. After reaching 100%, it seems like the text has disappeared, but its actually still there, only moved up by 40em.
So the workflow looks something like this:
moves up by 1em => moves up by 0em => moves up by 40px => moves up by 40em
So by the last point, the text is already far above the viewport it seems like it has disappeared.
The solution to this is not to mix px's and em's.
If you change -40px to -4em on the last keyframe, the animation will work okay, maybe won't be the pixel perfect, but at least it will work.

Current element hiding, after hover on it (opacity changed)

I have a block with .cube class - which implement a red cube.
.cube {
position: absolute;
top: 50px;
left: 50px;
width: 20px;
height: 20px;
background: red;
transition: .3s opacity;
}
And pseudo-selector :before with a "border" around it (actually it's just more larger cube around .cube class).
.cube::before {
position: absolute;
top: -10px; left: -10px;
right: -10px; bottom: -10px;
content: '';
background: black;
z-index: -1;
}
On :hover I change my opacity in .cube class.
.cube:hover {
opacity: .5;
}
The question is: why .cube class on hover is disappears, in turn, it is not "under" :before. Where it?
Here is JSFiddle. Thanks!
.cube {
position: absolute;
top: 50px;
left: 50px;
width: 20px;
height: 20px;
background: red;
transition: .3s opacity;
}
.cube::before {
position: absolute;
top: -10px; left: -10px;
right: -10px; bottom: -10px;
content: '';
background: black;
z-index: -1;
}
.cube:hover {
opacity: .5;
}
<div class="cube"></div>
Paulie_D was right! The stacking context is being affected. Check this out here for more information:
https://www.w3.org/TR/css3-color/#transparency
I decided to modify your example to show what's going on a bit more easily. I must say, you don't see browser stacking context coming into play this way every day! (Sorry)
Here's what I've done:
Extended the duration of the original transition
Added a transition of a different time to differentiate each direction of the interim change.
Changed the color from black to cyan to help with visual color changes (A brighter color will help one see the difference between 'above' and 'below' in stack
Added a reduced opacity style to the (presently) cyan colored :before element.
Here's the fiddle:
https://jsfiddle.net/c5d5thhk/
Instructions: Mouse over the box. Please Note:
the change in color relative to the timing of the relevant transition.
that the appearance in color (affected by opacity) never truly finishes changing back to its initial state (until an end-'flick' at the very end of the transition) when coded like this. This is because the inherent change in stacking context is never allowed to return back to the initial state smoothly as the transition commands. This is why I've changed the coloring to cyan and added the opacity rules that I have.
Don't forget: ::before is inherently before the rest of the element in source order. It may help to see this fiddle with ::before changed to ::after to help demonstrate the other side of the fence. https://jsfiddle.net/c5d5thhk/1/
And yes, there is some buggy behavior on several browsers for this demo; sometimes the transition never allows the stacking context to return to its initial order, even when the opacity has finished its course in the transition's entire duration of 3s (3 seconds) - if this gets in the way of your testing, play around with the mouse a bit; the agitation should cause it to resolve within a few moments if it doesn't on its own.
Edit:
Just saw that the MDN has a much clearer breakdown than the W3C (surprise, surprise) on how the stacking context goes. Check it out here:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
Also, check this out for influencing stacks:
https://developer.mozilla.org/en-US/docs/Web/CSS/isolation
Edit 2: (added comment)
Here's a bit more information. As for your repeated question, your red box's box model is behind the black box. However, because of the rendering process taken to address transparency, it isn't shown in your example when the opacity style is engaged. In other words: even though the black box has a reduced opacity where one expects to have any content behind it revealed, the red box will still not be shown because of the process taken for the alpha channel. If you'd like to learn more about this, try running this with an SVG.

Make CSS animation stop after it leaves visible screen

Using css animation I have an object that moves from the left to the right of the screen. However I've noticed that the animation is actually continuing after it has exited the right of the screen, which causes Chrome horizontal scroll bars to appear.
If you scroll right, it just shows the animated object no longer moving and a white background screen.
How do I kill the animation as soon as it leaves the view able screen?
The actual animation can be seen here. http://crea8tion.com/ChristmasMessage/index.html
The CSS code for the object is
.santa {
width: 1000px;
position: absolute;
top: -14%;
left: -55%;
-webkit-animation: santa-move 1s 1s ease-out forwards;
-webkit-animation-delay:5s;animation-delay:5s;
-webkit-animation-duration: 25s;
}
#-webkit-keyframes santa-move {
100% { left: 100%;}
}
There is a simple way to remove this extra scrollbar.
You can add a simple overlay: hidden to the parent div. In your case:
.columns {
overflow: hidden;
}
In this case, the santa animation didn't anymore add the horizontal scrollbar.

animate inline element scroll full width

for the following paragraph, I want to animate to scroll span element upon mouse hover. It will scroll to the right until the end.
<div class="one_line">
<span>
NoMagic framework doesn't try to put anything into the blackbox. We hope you read the core source code and try to get fully understanding before you start to using it. And we hope you forking our project and creating your own database helper function sets based on your need.
Using NoMagic, you will turn the MySQL database into a schemaless solution, the schemaless database will save your time so that you don't need to spend to much time in planning database table structure.
</span>
</div>
the css I already have
.one_line {
line-height: 1.5em;
height: 1.5em;
position: relative;
width: 600px;
overflow-x: hidden;
span {
white-space: nowrap;
height: 100%;
display: inline-block;
position: absolute;
&:hover {
animation-name: scroll;
animation-duration: 6s;
}
}
}
#keyframes scroll {
50% {
left: 100%;
}
}
Up to my knowledge using CSS animate we can only animate the entire tag itself but not the content in it (i.e.) in this case we can move the entire span across the page dimension but not the text inside it. So i made it using transform property which is more flexible.
I have a jsfiddle here to demonstrate this.
CSS Animate code that i had changed:
#keyframes scroll {
0% {
transform:translateX(0);
}
100% {
transform:translateX(-100%);
}
}
Hope this will be useful.

Resources