I'm trying to animate a single word in the middle of a sentence using CSS and HTML. I'm want the word to animate downward and fade out, as a new word fades in from above. My problem is that the rest of the sentence after the animating word isn't spacing correctly. As you can see below, the animating word is overlapping the rest of the sentence.
Here's a screencast of the animation: https://www.dropbox.com/s/svjrbqug3gjsg2s/movie.mov?dl=0
And here's my code so far:
<html>
<head>
<link rel="stylesheet" type="text/css" href="rotate.css">
</head>
<section class="rw-wrapper">
<span>The</span>
<div class="rw-words rw-words-1">
<span>inspiration</span>
<span>accountability</span>
<span>results</span>
<span>community</span>
<span>experience</span>
<span>coaching</span>
</div>
<span>you're looking for.</span>
</section>
</html>
CSS:
.rw-wrapper{
width: 80%;
position: relative;
margin: 110px auto 0 auto;
font-family: 'Bree Serif';
padding: 10px;
}
.rw-words{
display: inline;
text-indent: 2px;
}
.rw-words-1 span{
position: absolute;
opacity: 0;
overflow: hidden;
color: #6b969d;
-webkit-animation: rotateWord 18s linear infinite 0s;
-ms-animation: rotateWord 18s linear infinite 0s;
animation: rotateWord 18s linear infinite 0s;
}
.rw-words-1 span:nth-child(2) {
-webkit-animation-delay: 3s;
-ms-animation-delay: 3s;
animation-delay: 3s;
color: #6b969d;
}
.rw-words-1 span:nth-child(3) {
-webkit-animation-delay: 6s;
-ms-animation-delay: 6s;
animation-delay: 6s;
color: #6b969d;
}
.rw-words-1 span:nth-child(4) {
-webkit-animation-delay: 9s;
-ms-animation-delay: 9s;
animation-delay: 9s;
color: #6b969d;
}
.rw-words-1 span:nth-child(5) {
-webkit-animation-delay: 12s;
-ms-animation-delay: 12s;
animation-delay: 12s;
color: #6b969d;
}
.rw-words-1 span:nth-child(6) {
-webkit-animation-delay: 15s;
-ms-animation-delay: 15s;
animation-delay: 15s;
color: #6b969d;
}
@-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; }
}
@-ms-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; }
}
@media screen and (max-width: 768px){
.rw-sentence { font-size: 18px; }
}
@media screen and (max-width: 320px){
.rw-sentence { font-size: 9px; }
}
How can I use CSS to get the rest of my sentence to space properly for the animating word?
You can do this in pure CSS by animating the max-width
of the individual spans. Here’s a CodePen, and here’s the CSS (prefixes removed for clarity. To get them back just click the little 'View Compiled' button on CodePen)
.rw-wrapper{
width: 80%;
position: relative;
margin: 110px auto 0 auto;
font-family: 'Bree Serif';
padding: 10px;
}
.rw-words{
display: inline-block;
text-indent: 2px;
}
.rw-words-1 span{
max-width: 0;
display: inline-block;
opacity: 0;
overflow: hidden;
color: #6b969d;
margin-left: -4px;
animation: rotateWord 18s linear infinite 0s;
}
.rw-words-1 span:nth-child(2) {
animation-delay: 3s;
color: #6b969d;
}
.rw-words-1 span:nth-child(3) {
animation-delay: 6s;
color: #6b969d;
}
.rw-words-1 span:nth-child(4) {
animation-delay: 9s;
color: #6b969d;
}
.rw-words-1 span:nth-child(5) {
animation-delay: 12s;
color: #6b969d;
}
.rw-words-1 span:nth-child(6) {
animation-delay: 15s;
color: #6b969d;
}
@keyframes rotateWord {
0% { opacity: 0; max-width: 0;}
2% { opacity: 0; max-width: 0; transform: translateY(-30px); }
5% { opacity: 1; max-width: 200px; transform: translateY(5px);}
17% { opacity: 1; max-width: 200px; transform: translateY(5px); }
20% { opacity: 0; max-width: 0; transform: translateY(30px); }
80% { opacity: 0; max-width: 0; }
100% { opacity: 0; max-width: 0; }
}
@media screen and (max-width: 768px){
.rw-sentence { font-size: 18px; }
}
@media screen and (max-width: 320px){
.rw-sentence { font-size: 9px; }
}
It’s a little bit hacky, but it works! No JS required.
I removed the position: absolute
and added max-width
to the animation. Presto!
Here's a solution that uses JavaScript:
Example Fiddle
Here's the code that runs it:
JavaScript
var spans = document.querySelectorAll('.rw-words span'),
maxwidth = 0,
words = document.querySelector('.rw-words');
for (var i=0,l=spans.length;i<l;i++){
console.log(i + ' width: ' + spans[i].offsetWidth)
maxwidth = spans[i].offsetWidth > maxwidth ? spans[i].offsetWidth : maxwidth;
}
words.style.width = maxwidth + 'px'
CSS
.rw-words{
display: inline-block;
vertical-align: top;
text-indent: 2px;
}
EDIT
Here's some much cleaner JavaScript that achieves the same thing:
var spans = [].slice.call(document.querySelectorAll('.rw-words span')),
words = document.querySelector('.rw-words'),
maxwidth = Math.max.apply(null, spans.map(function (item) {
return item.offsetWidth;
}));
words.style.width = maxwidth + 'px'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With