jQuery CSS3 Animated Headlines

by Ali Dadmand

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<section class="cd-intro">
    	<h1 class="cd-headline rotate-1">
			<span>My favourite food is</span>
			<span class="cd-words-wrapper">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline letters type">
			<span>My favourite food is</span> 
			<span class="cd-words-wrapper waiting">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline letters rotate-2">
			<span>My favourite food is</span> 
			<span class="cd-words-wrapper">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline loading-bar">
			<span>My favourite food is</span>
			<span class="cd-words-wrapper">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline slide">
			<span>My favourite food is</span>
			<span class="cd-words-wrapper">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline clip is-full-width">
			<span>My favourite food is</span>
			<span class="cd-words-wrapper">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline zoom">
			<span>My favourite food is</span>
			<span class="cd-words-wrapper">
				<b class="is-visible">pizza</b>
				<b>sushi</b>
				<b>steak</b>
			</span>
		</h1>

</section>
<!-- cd-intro -->
<section class="cd-intro">
    	<h1 class="cd-headline letters...

CSS

*, *::after, *::before {
     -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
     box-sizing: border-box;
 }
 html * {
     -webkit-font-smoothing: antialiased;
     -moz-osx-font-smoothing: grayscale;
 }
 html {
     font-size: 62.5%;
 }
 body {
     font-size: 1.6rem;
     font-family:"Source Sans Pro", sans-serif;
     color: #aebcb9;
     background-color: #0d0d0d;
 }
 a {
     text-decoration: none;
 }
 .cd-title {
     position: relative;
     height: 160px;
     line-height: 230px;
     text-align: center;
 }
 .cd-title h1 {
     font-size: 2.4rem;
     font-weight: 700;
 }
 @media only screen and (min-width: 768px) {
     .cd-title {
         line-height: 250px;
     }
 }
 @media only screen and (min-width: 1170px) {
     .cd-title {
         height: 200px;
         line-height: 300px;
     }
     .cd-title h1 {
         font-size: 3rem;
     }
 }
 .cd-intro {
     width: 90%;
     max-width: 768px;
     text-align: center;
 }
 .cd-intro {
     margin: 4em auto;
 }
 @media only screen and (min-width: 768px) {
     .cd-intro {
         margin: 5em auto;
     }
 }
 @media only screen and (min-width: 1170px) {
     .cd-intro {
         margin: 6em auto;
     }
 }
 .cd-headline {
     font-size: 3rem;
     line-height: 1.2;
 }
 @media only screen and (min-width: 768px) {
     .cd-headline {
         font-size: 4.4rem;
         font-weight: 300;
     }
 }
 @media only screen and (min-width: 1170px) {
     .cd-headline {
         font-size: 6rem;
     }
 }
 .cd-words-wrapper {
     display: inline-block;
     position: relative;
     text-align: left;
 }
 .cd-words-wrapper b {
     display: inline-block;
     position: absolute;
     white-space: nowrap;
     left: 0;
     top: 0;
 }
 .cd-words-wrapper b.is-visible {
     position: relative;
 }
 .no-js .cd-words-wrapper b {
     opacity: 0;
 }
 .no-js .cd-words-wrapper b.is-visible {
     opacity: 1;
 }
 /* -------------------------------- 

xrotate-1 

-------------------------------- */
...

JavaScript

jQuery(document).ready(function ($) {
    //set animation timing
    var animationDelay = 2500,
        //loading bar effect
        barAnimationDelay = 3800,
        barWaiting = barAnimationDelay - 3000, //3000 is the duration of the transition on the loading bar - set in the scss/css file
        //letters effect
        lettersDelay = 50,
        //type effect
        typeLettersDelay = 150,
        selectionDuration = 500,
        typeAnimationDelay = selectionDuration + 800,
        //clip effect 
        revealDuration = 600,
        revealAnimationDelay = 1500;

    initHeadline();


    function initHeadline() {
        //insert <i> element for each letter of a changing word
        singleLetters($('.cd-headline.letters').find('b'));
        //initialise headline animation
        animateHeadline($('.cd-headline'));
    }

    function singleLetters($words) {
        $words.each(function () {
            var word = $(this),
                letters = word.text().split(''),
                selected = word.hasClass('is-visible');
            for (i in letters) {
                if (word.parents('.rotate-2').length > 0) letters[i] = '<em>' + letters[i] + '</em>';
                letters[i] = (selected) ? '<i class="in">' + letters[i] + '</i>' : '<i>' + letters[i] + '</i>';
            }
            var newLetters = letters.join('');
            word.html(newLetters);
        });
    }

    function animateHeadline($headlines) {
        var duration = animationDelay;
        $headlines.each(function () {
            var headline = $(this);

            if (headline.hasClass('loading-bar')) {
                duration = barAnimationDelay;
                setTimeout(function () {
                    headline.find('.cd-words-wrapper').addClass('is-loading')
                }, barWaiting);
            } else if (headline.hasClass('clip')) {
                var spanWrapper = headline.find('.cd-words-wrapper'),
                    newWidth = spanWrapper.width() +...