I cannot figure out how to add a static word after this CSS text animation. Can someone please explain how to add a static word after this text animation? I would like to add the word 'Teams' after the animation. when I try to add the word it overlaps with the spans because it was positioned absolute.
I couldn't figure out how to do it.
<text-block class="sentence">For Modern
<div class="verticalFlip">
<span>Engineering</span>
<span>Manufacturing</span>
<span>Quality</span>
<span>Service</span>
</div>
<text-block/>
<Style>
.sentence {
text-align: left;
}
.verticalFlip {
display: inline;
text-indent: 3px;
}
.verticalFlip span {
animation: vertical 10s linear infinite 0s;
-ms-animation: vertical 10s linear infinite 0s;
-webkit-animation: vertical 10s linear infinite 0s;
opacity: 0;
position: absolute;
overflow: hidden;
height : 40px
}
.verticalFlip span:nth-child(2) {
animation-delay: 2.5s;
-ms-animation-delay: 2.5s;
-webkit-animation-delay: 2.5s;
}
.verticalFlip span:nth-child(3) {
animation-delay: 5s;
-ms-animation-delay: 5s;
-webkit-animation-delay: 5s;
}
.verticalFlip span:nth-child(4) {
animation-delay: 7.5s;
-ms-animation-delay: 7.5s;
-webkit-animation-delay: 7.5s;
}
/*Vertical Flip Animation*/
#-moz-keyframes vertical {
0% { opacity: 0; }
5% { opacity: 0; -moz-transform: rotateX(180deg); }
10% { opacity: 1; -moz-transform: translateY(0px); }
25% { opacity: 1; -moz-transform: translateY(0px); }
30% { opacity: 0; -moz-transform: translateY(0px); }
80% { opacity: 0; }
100% { opacity: 0;}
}
#-webkit-keyframes vertical {
0% { opacity: 0; }
5% { opacity: 0; -webkit-transform: rotateX(180deg); }
10% { opacity: 1; -webkit-transform: translateY(0px); }
25% { opacity: 1; -webkit-transform: translateY(0px); }
30% { opacity: 0; -webkit-transform: translateY(0px); }
80% { opacity: 0; }
100% { opacity: 0; }
}
#-ms-keyframes vertical {
0% { opacity: 0; }
5% { opacity: 0; -ms-transform: rotateX(180deg); }
10% { opacity: 1; -ms-transform: translateY(0px); }
25% { opacity: 1; -ms-transform: translateY(0px); }
30% { opacity: 0; -ms-transform: translateY(0px); }
80% { opacity: 0; }
100% { opacity: 0; }
}
</style>
I used a little trick to just use css without javascript.
.sentence {
text-align: left;
}
.verticalFlip {
display: inline;
font-size: 0;
}
.verticalFlip>span {
position: relative;
display: inline-block;
width: 0;
color: transparent;
font-size: 1rem;
animation: fakeWidth 10s linear infinite 0s;
-ms-animation: fakeWidth 10s linear infinite 0s;
-webkit-animation: fakeWidth 10s linear infinite 0s;
}
.verticalFlip>span:nth-child(2) {
animation-delay: 2.5s;
-ms-animation-delay: 2.5s;
-webkit-animation-delay: 2.5s;
}
.verticalFlip>span:nth-child(3) {
animation-delay: 5s;
-ms-animation-delay: 5s;
-webkit-animation-delay: 5s;
}
.verticalFlip>span:nth-child(4) {
animation-delay: 7.5s;
-ms-animation-delay: 7.5s;
-webkit-animation-delay: 7.5s;
}
.verticalFlip>div {
display: inline-block;
font-size: 1rem;
text-indent: 5px;
}
.verticalFlip>span>span {
position: absolute;
left: 0;
top: 0;
height: 40px;
color: black;
opacity: 0;
z-index: 1;
animation: vertical 10s linear infinite 0s;
-ms-animation: vertical 10s linear infinite 0s;
-webkit-animation: vertical 10s linear infinite 0s;
}
.verticalFlip>span:nth-child(2)>span {
animation-delay: 2.5s;
-ms-animation-delay: 2.5s;
-webkit-animation-delay: 2.5s;
}
.verticalFlip>span:nth-child(3)>span {
animation-delay: 5s;
-ms-animation-delay: 5s;
-webkit-animation-delay: 5s;
}
.verticalFlip>span:nth-child(4)>span {
animation-delay: 7.5s;
-ms-animation-delay: 7.5s;
-webkit-animation-delay: 7.5s;
}
/*Vertical Flip Animation*/
#-moz-keyframes vertical {
0% {
opacity: 0;
}
5% {
opacity: 0;
-moz-transform: rotateX(180deg);
}
10% {
opacity: 1;
-moz-transform: translateY(0px);
}
25% {
opacity: 1;
-moz-transform: translateY(0px);
}
30% {
opacity: 0;
-moz-transform: translateY(0px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-webkit-keyframes vertical {
0% {
opacity: 0;
}
5% {
opacity: 0;
-webkit-transform: rotateX(180deg);
}
10% {
opacity: 1;
-webkit-transform: translateY(0px);
}
25% {
opacity: 1;
-webkit-transform: translateY(0px);
}
30% {
opacity: 0;
-webkit-transform: translateY(0px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-ms-keyframes vertical {
0% {
opacity: 0;
}
5% {
opacity: 0;
-ms-transform: rotateX(180deg);
}
10% {
opacity: 1;
-ms-transform: translateY(0px);
}
25% {
opacity: 1;
-ms-transform: translateY(0px);
}
30% {
opacity: 0;
-ms-transform: translateY(0px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-webkit-keyframes fakeWidth {
0% {
width: 0;
}
5% {
width: auto;
}
25% {
width: auto;
}
30% {
width: 0;
}
100% {
width: 0;
}
}
<text-block class="sentence">For Modern
<div class="verticalFlip">
<span>Engineering<span>Engineering</span></span>
<span>Manufacturing<span>Manufacturing</span></span>
<span>Quality<span>Quality</span></span>
<span>Service<span>Service</span></span>
<div>Teams</div>
</div>
</text-block>
I was trying to do a changing word animation. I have managed to do it. My problem is that this whole sentence is supposed to be one line. Now it is breaking into two lines. How can I manage to get it in one line?
The space between we and solutions is supposed to auto-adjust depending on the changing word.
https://codepen.io/thaha-wahid/pen/abOXvbx
<div class="sliding-statement">
<h1 class="sliding-sentence">
We are engineers, We
<div class="slidingVertical">
<span>Create</span>
<span>Build</span>
<span>Develop</span>
</div>
Solutions
</h1>
</div>
.sliding-statement h1{
font-size: 48px;
margin-bottom: 20px;
padding-bottom: 0;
color: #001b35;
font-weight: bolder;
}
.slidingVertical span{
animation: topToBottom 7.5s linear infinite 0s;
-ms-animation: topToBottom 7.5s linear infinite 0s;
-webkit-animation: topToBottom 7.5s linear infinite 0s;
color: #ffffff;
font-weight: bolder;
opacity: 0;
overflow: hidden;
position: absolute;
background-color: #1ff8dc;
padding: 0px 7px;
}
.slidingVertical span:nth-child(2){
animation-delay: 2.5s;
-ms-animation-delay: 2.5s;
-webkit-animation-delay: 2.5s;
}
.slidingVertical span:nth-child(3){
animation-delay: 5s;
-ms-animation-delay: 5s;
-webkit-animation-delay: 5s;
}
/*topToBottom Animation*/
#-moz-keyframes topToBottom{
0% { opacity: 0; }
5% { opacity: 0; -moz-transform: translateY(-50px); }
10% { opacity: 1; -moz-transform: translateY(0px); }
25% { opacity: 1; -moz-transform: translateY(0px); }
30% { opacity: 0; -moz-transform: translateY(50px); }
80% { opacity: 0; }
100% { opacity: 0; }
}
#-webkit-keyframes topToBottom{
0% { opacity: 0; }
5% { opacity: 0; -webkit-transform: translateY(-50px); }
10% { opacity: 1; -webkit-transform: translateY(0px); }
25% { opacity: 1; -webkit-transform: translateY(0px); }
30% { opacity: 0; -webkit-transform: translateY(50px); }
80% { opacity: 0; }
100% { opacity: 0; }
}
#-ms-keyframes topToBottom{
0% { opacity: 0; }
5% { opacity: 0; -ms-transform: translateY(-50px); }
10% { opacity: 1; -ms-transform: translateY(0px); }
25% { opacity: 1; -ms-transform: translateY(0px); }
30% { opacity: 0; -ms-transform: translateY(50px); }
80% { opacity: 0; }
100% { opacity: 0; }
}
The position absolute styles takes the DOM element not occupy any space in the line. So you can use the parent div to set width based on the child element animation or set the parent width to a constant width.
https://codepen.io/rohinikumar4073/pen/bGdzVOj
body {
background-color: #a3d5d3;
}
.slidingVertical {
display: inline-block;
width: 170px;
display: inline-block;
height: 44px;
animation: changeWidth 7.5s infinite;
}
#keyframes changeWidth {
0%,
32% {
width: 150px;
}
33%,
66% {
width: 120px;
}
67%,
100% {
width: 180px;
}
}
.sliding-statement h1 {
font-size: 48px;
margin-bottom: 20px;
padding-bottom: 0;
color: #001b35;
font-weight: bolder;
}
.slidingVertical span {
animation: topToBottom 7.5s linear infinite 0s;
-ms-animation: topToBottom 7.5s linear infinite 0s;
-webkit-animation: topToBottom 7.5s linear infinite 0s;
color: #ffffff;
font-weight: bolder;
opacity: 0;
overflow: hidden;
position: absolute;
background-color: #1ff8dc;
padding: 0px 7px;
display: flex;
}
.slidingVertical span:nth-child(2) {
animation-delay: 2.5s;
-ms-animation-delay: 2.5s;
-webkit-animation-delay: 2.5s;
}
.slidingVertical span:nth-child(3) {
animation-delay: 5s;
-ms-animation-delay: 5s;
-webkit-animation-delay: 5s;
}
/*topToBottom Animation*/
#-moz-keyframes topToBottom {
0% {
opacity: 0;
}
5% {
opacity: 0;
-moz-transform: translateY(-50px);
}
10% {
opacity: 1;
-moz-transform: translateY(0px);
}
25% {
opacity: 1;
-moz-transform: translateY(0px);
}
30% {
opacity: 0;
-moz-transform: translateY(50px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-webkit-keyframes topToBottom {
0% {
opacity: 0;
}
5% {
opacity: 0;
-webkit-transform: translateY(-50px);
}
10% {
opacity: 1;
-webkit-transform: translateY(0px);
}
25% {
opacity: 1;
-webkit-transform: translateY(0px);
}
30% {
opacity: 0;
-webkit-transform: translateY(50px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-ms-keyframes topToBottom {
0% {
opacity: 0;
}
5% {
opacity: 0;
-ms-transform: translateY(-50px);
}
10% {
opacity: 1;
-ms-transform: translateY(0px);
}
25% {
opacity: 1;
-ms-transform: translateY(0px);
}
30% {
opacity: 0;
-ms-transform: translateY(50px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<div class="sliding-statement">
<h1 class="sliding-sentence">
We are engineers, We
<div class="slidingVertical">
<span>Create</span>
<span>Build</span>
<span>Develop</span>
</div>
Solutions
</h1>
</div>
The CSS seems to be horizontally centering the text by the first letter. I'd like to make it be perfectly centered on the page, without breaking the animation. I added a gradient to show the exact horizontal center of the page.
.wrapper {
height: 100vh;
background: linear-gradient(to right, #1e5799 0%,#ffffff 50%,#7db9e8 100%);
}
.container {
text-align: center;
}
.vcenter {
position: relative;
top: calc(50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.container h2 {
background: red;
display: inline-block;
position: absolute;
opacity: 0;
overflow: visible;
-webkit-animation: rotateWord 12s linear infinite 0s;
-ms-animation: rotateWord 12s linear infinite 0s;
animation: rotateWord 12s linear infinite 0s;
margin: 0;
}
.container h2:nth-child(2) {
-webkit-animation: rotateWord 12s linear infinite 3s;
-ms-animation: rotateWord 12s linear infinite 3s;
animation: rotateWord 12s linear infinite 3s;
}
.container h2:nth-child(3) {
-webkit-animation: rotateWord 12s linear infinite 6s;
-ms-animation: rotateWord 12s linear infinite 6s;
animation: rotateWord 12s linear infinite 6s;
}
.container h2:nth-child(4) {
-webkit-animation: rotateWord 12s linear infinite 9s;
-ms-animation: rotateWord 12s linear infinite 9s;
animation: rotateWord 12s linear infinite 9s;
}
#-webkit-keyframes rotateWord {
0% {
opacity: 0;
}
2% {
opacity: 0;
-webkit-transform: translateY(-30px);
}
5% {
opacity: 1;
-webkit-transform: translateY(0px);
}
17% {
opacity: 1;
-webkit-transform: translateY(0px);
}
20% {
opacity: 0;
-webkit-transform: translateY(30px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-moz-keyframes rotateWord {
0% {
opacity: 0;
}
2% {
opacity: 0;
-ms-transform: translateY(-30px);
}
5% {
opacity: 1;
-ms-transform: translateY(0px);
}
17% {
opacity: 1;
-ms-transform: translateY(0px);
}
20% {
opacity: 0;
-ms-transform: translateY(30px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#keyframes rotateWord {
0% {
opacity: 0;
}
2% {
opacity: 0;
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
5% {
opacity: 1;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
17% {
opacity: 1;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
20% {
opacity: 0;
-webkit-transform: translateY(30px);
transform: translateY(30px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<div class="wrapper">
<div class="container vcenter">
<h2>HEY THERE THIS IS TEXT</h2>
<h2>DIFFERENT TEXT</h2>
<h2>THIS IS TEXT</h2>
<h2>DIFFERENT LENGTHS OF TEXT</h2>
</div>
</div>
Make sure to set the correct transform values in the #keyframes, also the middle div container can be removed to make it easier.
jsFiddle
body {
margin: 0;
}
.container {
height: 100vh;
text-align: center;
background: linear-gradient(to right, #1e5799 0%, #ffffff 50%, #7db9e8 100%);
}
.container h2 {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
opacity: 0;
margin: 0;
}
.container h2:nth-child(1) {
animation: rotateWord 12s linear infinite 0s;
}
.container h2:nth-child(2) {
animation: rotateWord 12s linear infinite 3s;
}
.container h2:nth-child(3) {
animation: rotateWord 12s linear infinite 6s;
}
.container h2:nth-child(4) {
animation: rotateWord 12s linear infinite 9s;
}
#keyframes rotateWord {
0% {
opacity: 0;
}
2% {
opacity: 0;
transform: translate(-50%, -30px);
}
5% {
opacity: 1;
transform: translate(-50%, 0px);
}
17% {
opacity: 1;
transform: translate(-50%, 0px);
}
20% {
opacity: 0;
transform: translate(-50%, 30px);
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<div class="container">
<h2>HEY THERE THIS IS TEXT</h2>
<h2>DIFFERENT TEXT</h2>
<h2>THIS IS TEXT</h2>
<h2>DIFFERENT LENGTHS OF TEXT</h2>
</div>
I'm working off of a really great CSS3 animated background tutorial that can be found here
The only problem is that it won't work. Unfortunately, the tutorial is just a blog post with code, and there's no specific name for it, so I've been having trouble finding support for my issue.
It uses simple html markup:
<ul class="cb-slideshow">
<li>
<span>Image 01</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 02</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 03</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 04</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 05</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 06</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 07</span>
<div>
<h3></h3>
</div>
</li>
<li>
<span>Image 08></span>
<div>
<h3></h3>
</div>
</li>
And then the rest is done in CSS3
.cb-slideshow,
.cb-slideshow:after {
position: fixed;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
z-index: 0;
}
.cb-slideshow:after {
content: '';
background: transparent url() repeat top left;
}
.cb-slideshow li span {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
color: transparent;
background-size: cover;
background-position: 50% 50%;
background-repeat: none;
opacity: 0;
z-index: 0;
animation: imageAnimation 40s linear infinite 0s;
}
.cb-slideshow li div {
z-index: 1000;
position: absolute;
bottom: 30px;
left: 0px;
width: 100%;
text-align: center;
opacity: 0;
color: #fff;
-webkit-animation: titleAnimation 40s linear infinite 0s;
-moz-animation: titleAnimation 40s linear infinite 0s;
-o-animation: titleAnimation 40s linear infinite 0s;
-ms-animation: titleAnimation 40s linear infinite 0s;
animation: titleAnimation 40s linear infinite 0s;
}
.cb-slideshow li div h3 {
font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
font-size: 240px;
padding: 0;
line-height: 200px;
}
.cb-slideshow li:nth-child(1) span {
background-image: url(../images/homepage/img01.jpg)
}
.cb-slideshow li:nth-child(2) span {
background-image: url(../images/homepage/img02.jpg);
animation-delay: 5s;
-webkit-animation-delay: 5s;
}
.cb-slideshow li:nth-child(3) span {
background-image: url(../images/homepage/img03.jpg);
animation-delay: 10s;
-webkit-animation-delay: 10s;
}
.cb-slideshow li:nth-child(4) span {
background-image: url(../images/homepage/img04.jpg);
animation-delay: 15s;
-webkit-animation-delay: 15s;
}
.cb-slideshow li:nth-child(5) span {
background-image: url(../images/homepage/img05.jpg);
animation-delay: 20s;
-webkit-animation-delay: 20s;
}
.cb-slideshow li:nth-child(6) span {
background-image: url(../images/homepage/img06.jpg);
animation-delay: 25s;
-webkit-animation-delay: 25s;
}
.cb-slideshow li:nth-child(7) span {
background-image: url(../images/homepage/img07.jpg);
animation-delay: 30s;
-webkit-animation-delay: 30s;
}
.cb-slideshow li:nth-child(8) span {
background-image: url(../images/homepage/img08.jpg);
animation-delay: 35s;
-webkit-animation-delay: 35s;
}
#keyframes imageAnimation {
0% { opacity: 0;
animation-timing-function: ease-in; }
8% { opacity: 1;
animation-timing-function: ease-out; }
17% { opacity: 1 }
25% { opacity: 0 }
100% { opacity: 0 }
}
There's even a backup in case the browser doesn't support CSS3 animations:
.no-cssanimations .cb-slideshow li span{
opacity: 1;
}
This is supposed to ensure that you don't end up with a blank page, which is what I have. I've re-checked my links, and almost entirely copied the demo, but it's not displaying on my page. Is anyone familiar with CSS3 and have any ideas as to what my issue could be?
Maybe the problem can be fixed with adding webkit and such to
#keyframes imageAnimation {
0% { opacity: 0;
animation-timing-function: ease-in; }
8% { opacity: 1;
animation-timing-function: ease-out; }
17% { opacity: 1 }
25% { opacity: 0 }
100% { opacity: 0 } so: #-webkit-keyframes imageAnimation {
0% { opacity: 0;
animation-timing-function: ease-in; }
8% { opacity: 1;
animation-timing-function: ease-out; }
17% { opacity: 1 }
25% { opacity: 0 }
100% { opacity: 0 } #-moz-keyframes imageAnimation {
0% { opacity: 0;
animation-timing-function: ease-in; }
8% { opacity: 1;
animation-timing-function: ease-out; }
17% { opacity: 1 }
25% { opacity: 0 }
100% { opacity: 0 } #-o-keyframes imageAnimation {
0% { opacity: 0;
animation-timing-function: ease-in; }
8% { opacity: 1;
animation-timing-function: ease-out; }
17% { opacity: 1 }
25% { opacity: 0 }
100% { opacity: 0 }
I'm trying to have an ellipsis animate, and was wondering if it was possible with CSS animations...
So it might be like
Loading...
Loading..
Loading.
Loading...
Loading..
And basically just continue like that. Any ideas?
Edit: like this: http://playground.magicrising.de/demo/ellipsis.html
How about a slightly modified version of #xec's answer: http://codepen.io/thetallweeks/pen/yybGra
CSS Animation that uses steps. See MDN docs
.loading:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
-webkit-animation: ellipsis steps(4, end) 900ms infinite;
animation: ellipsis steps(4, end) 900ms infinite;
content: "\2026";
/* ascii code for the ellipsis character */
width: 0px;
}
#keyframes ellipsis {
to {
width: 40px;
}
}
#-webkit-keyframes ellipsis {
to {
width: 40px;
}
}
<h1 class="loading">Loading</h1>
#xec's answer has more of a slide-in effect on the dots, while this allows the dots to appear instantly.
You could try to use the animation-delay property and time each ellipsis character. In this case I've put each ellipsis character in a <span class> so I can animate them separately.
I made a demo, which isn't perfect, but it shows at least what I mean :)
The code from my example:
HTML
Loading<span class="one">.</span><span class="two">.</span><span class="three">.</span>
CSS
.one {
opacity: 0;
-webkit-animation: dot 1.3s infinite;
-webkit-animation-delay: 0.0s;
animation: dot 1.3s infinite;
animation-delay: 0.0s;
}
.two {
opacity: 0;
-webkit-animation: dot 1.3s infinite;
-webkit-animation-delay: 0.2s;
animation: dot 1.3s infinite;
animation-delay: 0.2s;
}
.three {
opacity: 0;
-webkit-animation: dot 1.3s infinite;
-webkit-animation-delay: 0.3s;
animation: dot 1.3s infinite;
animation-delay: 0.3s;
}
#-webkit-keyframes dot {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes dot {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Even a more simple solution, works pretty well!
<style>
.loading::after {
display: inline-block;
animation: dotty steps(1,end) 1s infinite;
content: '';
}
#keyframes dotty {
0% { content: ''; }
25% { content: '.'; }
50% { content: '..'; }
75% { content: '...'; }
100% { content: ''; }
}
</style>
<div class="loading">Loading</div>
Just edited the content with animation instead of hiding some dots...
Demo here: https://jsfiddle.net/f6vhway2/1/
Edit:
Thanks to #BradCollins for pointing out that content is not an animatable property.
Currently, (2021) this works in Chrome/WebKit/Blink/Electron and Firefox and new version of Edge.
Short answer is "not really". However, you can play around with animating width and overflow hidden, and maybe get an effect that is "close enough". (code below tailored for firefox only, add vendor prefixes as needed).
html
<div class="loading">Loading</div>
css
.loading:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
-moz-animation: ellipsis 2s infinite;
content: "\2026"; /* ascii code for the ellipsis character */
}
#-moz-keyframes ellipsis {
from {
width: 2px;
}
to {
width: 15px;
}
}
demo: http://jsfiddle.net/MDzsR/1/
edit
It appears chrome has issues with animating the pseudo-element. An easy fix is to wrap the ellipsis in its own element. Check out http://jsfiddle.net/MDzsR/4/
A late addition but I found a way to do this which supports centered text.
<element>:after {
content: '\00a0\00a0\00a0';
animation: progress-ellipsis 5s infinite;
}
#keyframes progress-ellipsis {
0% {
content: '\00a0\00a0\00a0';
}
30% {
content: '.\00a0\00a0';
}
60% {
content: '..\00a0';
}
90% {
content: '...';
}
}
You can animate clip (or better clip-path if you don't need IE support)
div {
display: inline-block;
font-size: 1.4rem;
}
div:after {
position: absolute;
margin-left: .1rem;
content: ' ...';
animation: loading steps(4) 2s infinite;
clip: rect(auto, 0px, auto, auto);
}
#keyframes loading {
to {
clip: rect(auto, 20px, auto, auto);
}
}
<div>Loading</div>
Well Actually there is a pure CSS way of doing this.
I got the example from CSS Tricks, but made it also to be supported in Internet Explorer (I have tested it in 10+).
Check the Demo: http://jsfiddle.net/Roobyx/AT6v6/2/
HTML:
<h4 id="searching-ellipsis"> Searching
<span>.</span>
<span>.</span>
<span>.</span>
</h4>
CSS:
#-webkit-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-moz-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-webkit-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-moz-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-o-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#searching-ellipsis span {
-webkit-animation-name: opacity;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: infinite;
-moz-animation-name: opacity;
-moz-animation-duration: 1s;
-moz-animation-iteration-count: infinite;
-ms-animation-name: opacity;
-ms-animation-duration: 1s;
-ms-animation-iteration-count: infinite;
}
#searching-ellipsis span:nth-child(2) {
-webkit-animation-delay: 100ms;
-moz-animation-delay: 100ms;
-ms-animation-delay: 100ms;
-o-animation-delay: 100ms;
animation-delay: 100ms;
}
#searching-ellipsis span:nth-child(3) {
-webkit-animation-delay: 300ms;
-moz-animation-delay: 300ms;
-ms-animation-delay: 300ms;
-o-animation-delay: 300ms;
animation-delay: 300ms;
}
I found clip-path to be the cleanest, with the following benefits:
Does not use width, thus:
works independent of how wide the ellipsis is in whatever font is used.
Does not shift the layout (good for performance, and allows more text behind it without that moving around or reflow).
.loading-ellipsis:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis-animation steps(1,end) 2s infinite;
content: "\2026"; /* ascii code for the ellipsis character */
/* Enable this to see what is going on: */
/* background-color: red; */
}
#keyframes ellipsis-animation {
0% { clip-path: inset(0 100% 0 0); }
25% { clip-path: inset(0 66.6% 0 0); }
50% { clip-path: inset(0 33.3% 0 0); }
75% { clip-path: inset(0 0 0 0); }
}
<span class="loading-ellipsis">Loading</span> More text behind it that does not move
Credits go to #AaylaSecura's comment, and I improved that to use steps(1,end). This works because I end the animation at 75%, so that the last step shows the full expansion of the ellipsis (the third dot).
(There is an implicit 100% { clip-path: inset(0 0 0 0); } behind it that need not be written.)
Here is my solution with pure css https://jsfiddle.net/pduc6jx5/1/
explained: https://medium.com/#lastseeds/create-text-ellipsis-animation-with-pure-css-7f61acee69cc
scss
.dot1 {
animation: visibility 3s linear infinite;
}
#keyframes visibility {
0% {
opacity: 1;
}
65% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.dot2 {
animation: visibility2 3s linear infinite;
}
#keyframes visibility2 {
0% {
opacity: 0;
}
21% {
opacity: 0;
}
22% {
opacity: 1;
}
65% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.dot3 {
animation: visibility3 3s linear infinite;
}
#keyframes visibility3 {
0% {
opacity: 0;
}
43% {
opacity: 0;
}
44% {
opacity: 1;
}
65% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
html
Loading <span class="dot dot1">.</span><span class="dot dot2">.</span><span class="dot dot3">.</span>
I did exactly what #CodeBrauer very cleanly did above, but because my text was text-align: center (this works for right, too) and I didn't want the text to move over every time a period was added, I added "punctuation spaces":
<style>
.loading::after {
display: inline-block;
animation: dotty steps(1,end) 1s infinite;
content: '';
}
#keyframes dotty {
0% { content: '\2008\2008\2008'; }
25% { content: '.\2008\2008'; }
50% { content: '..\2008'; }
75% { content: '...'; }
100% { content: '\2008\2008\2008'; }
}
</style>
<div class="loading">Loading</div>