Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate a single word in a sentence with CSS

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.

enter image description here

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?

like image 512
hgwhittle Avatar asked May 21 '15 18:05

hgwhittle


2 Answers

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!

like image 63
Timothy Miller Avatar answered Nov 15 '22 01:11

Timothy Miller


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'
like image 34
Josh Burgess Avatar answered Nov 14 '22 23:11

Josh Burgess