animated headlines
December 18, 2014 | 124 Feedbacks

Animated Headlines

A collection of animated headlines, with interchangeable words that replace one another through CSS transitions.
Browser support
  • ie
  • Chrome
  • Firefox
  • Safari
  • Opera

I recently stumbled upon the Year in Music 2014 website. Among some fancy effects, the animated headline captured my attention. So I decided to put together a collection of CSS effects for headlines with rotating words!

Creating the structure

The HTML structure is the same for every animation. We used a <section> element as container, just to give some margins and set a max-width. The headline is an <h1> tag – block element. Each word is wrapped into a <b> tag, all words inside the same <span> element – inline element.

The class .rotate-1 (added to the <h1> tag) is what determines the effect to apply. If you just want to use this nugget, this is how it works: you change the class, you change the effect. Piece of cake!

Some effects may require an additional class. For example: when each letter is animated separately, the class .letters must be added to the <h1> tag. Inside the index.html file you can check the names of the classes applied to every headline.

Adding style

Let’s see together how to create the Rotate 1 effect. The process is similar for every animation, feel free to surf through the source files (or, why not, try to create the animation all by yourself!).

First thing first: let’s apply the .rotate-1 class to the <h1> tag!

The idea is to create a 3D rotation: the visible word should disappear by rotating over the X axis, the new word should appear from the bottom and take the free spot, always rotating over the X axis.

effect preview

To work in a 3D space, we need to set a perspective value, otherwise animated elements will look flat. Remember: the Perspective property shouldn’t be applied to the element that will be animated (through a CSS Transition, Transformation or Animation), but to a parent element. In this case I applied the perspective property to .cd-words-wrapper:

With the Perspective property in place, we target the <b> elements (each word) and we set opacity: 0; and position: absolute;. This way we hide all the words and we remove them from the flow of the document, as if they don’t occupy a space anymore. Finally we use the .is-visible class applied to the first <b> element (first word) and we add opacity: 1; and position: relative;. This is how we make the first word visible.

Note that we are applying a transformation (rotateX(180deg)) to each word to turn it over. transform-origin value is set at the bottom (first value is X, second value is Y). It’s an important detail: as you can see from the .gif above or the demo, the origin of the rotation is not the center and we need to specify it in CSS. Then of course the rotation is set back to 0 if the .is-visible class is applied.

We need to trigger the animation: with the help of jQuery, we remove the class .is-visible from the first element and add it to the second, then we remove it from the second and add it to the third etc – to create a loop. Every time we remove the .is-visible class, we switch it with the .is-hidden one. Why we need 2 classes: in each class we define a different CSS animation. The .is-visible is to show a word, the .is-hidden to hide it, of course. See how the CSS changes with the addition of the animations:

All what remains to do is defining the keyframes for both animations. The reason why we chose Animations over Transitions is the extra power in defining intermediate events. This is how we create the “anticipation” effect. Working with keyframes is clearly working with motion concepts. You can step up your interactions by distributing them along a timeline.

Events handling

To trigger the headline animation, we defined the animateHeadline() function.

This is used to trigger the hideWord() function with a delay of 2.5s. This function removes the .is-visible class from the first word and adds it to the second while removing the .is-hidden class from the second and adding it to the first. The hideWord() is then triggered again (with the same delay) in order to create the loop.


One note: there are some effects which require to animate single letters separately (for example, the Type effect). For these animations, we added the .letters class to the <h1> and wrapped each letter inside an <i> element using the singleLetters() function.


Jan 2, 2015
  • Bug fixed - words overlapping before js is loaded
Dec 18, 2014
  • Resource released by CodyHouse

Sebastiano Guerriero

UI/UX designer, with a huge passion for Nutella. Co-Founder of CodyHouse. You can follow him on Twitter or Dribbble.

  • Michael Pehl

    Very inspiring… I like it. Thank you for being active and having awesome ideas :)

  • Luke Spoor

    Excellent! I use typed.js normally but this has so many more options! Goodbye typed.js!

  • Seito

    This could very well be your best nugget yet, genius!

  • Efren Castillo

    Thanks. Excellent.

  • Borteo

    Great job, as usual. Simple and neat.

    The type effect is awesome :D

  • L34ndr0

    very cool, thanks sir.

  • pixelbeat

    Thanks, very helpful!

  • Tom Hill

    Awesome job! This is by far my favourite tutorial site yet!

  • Αen

    What’s the browser compatibility like?

    • Sebastiano Guerriero

      Hi Aen, you can check the browser compatibility tab right below the introduction

  • fahim

    nice work

  • bhc2

    Great animation !!!

  • Marlana Muzny

    Great tutorial! Lots of explanation.

  • srikanth dhondi

    Nicely Done :)

  • JoTa Andrade


  • Tom Christian

    Awesome effect but how well would this work with search engines?

    • Sebastiano Guerriero

      Hi Tom, I don’t think this HTML structure should affect in any negative way SEO optimization. It’s just some inline elements inside a h1 block element.

  • Lucas Farchetto


  • alexeiramone

    Very nice!

  • ArTaBaZ

    Very nice , Thanks ;)

  • PaStaGa

    Awesome !

  • Manuel D. Bruña

    Sebastian, quisiera consultarte, hay forma de hacer un efecto de una esfera rotando, pero que sea plano o que respete un formato “flat”. la idea sería mostrar media esfera como un planeta al borde de la pantalla y que esta gire 45 como si se estuviera caminando sobre ella. Espero se entienda y tengas una idea de como trabajarlo. gracias!

  • Human.A


    First of all thank you very much for this awesome tutorial.
    I have created a wordpress shortcode from it.

    Now the problem is that if these animations are included in a very lightweight page they will start instantly and perfectly. Now if you put these in a rather heavier page, where it takes a second or two to load everything (css and js) in some these effects all the words appear (on top of each other) for a fraction of a second and then the animation starts.

    Is there someway to put a delay in the animations so that the first word appears on page load, like it’s a regular headline text and then after a delay (or timeout) the animations start. This is just to avoid the words to collide on each other for that fraction of the second on page load.

    I’m not a js expert, and tried many things with the css codes but code not do this. Could you please help?

    • Sebastiano Guerriero

      I’ll def look into this and will probably update the resource

      • Human.A

        Thanks for the update :)

  • Rhett

    Slick. Thanks for sharing!

  • bosshakan

    Thanks for sharing, very nice.

  • Daniele

    Very nice idea, thanks

  • PhunkieMunkie

    Awesome! Thank you for sharing =)

  • Daniel

    Hi Sebastiano ! :)
    Another stunning nugget like usually, keep it up !

    I have a question, I see that you use sass which I can use it only if I install node or apps like prepros. But if I’ll upload all the content of this download pack on a online server, with all css ans sass files, how it’ll works ? The sass, it’ll work instantly ? What I have to do to use sass on a online server ?

    A very good day. Thanks !

    • Siva

      SASS got nothing to do with the online server. SASS is used for better organization of CSS and SASS files has to be compiled into CSS files to be able to use it in server.

      • Daniel

        And then, the css files will be used on the server ?

        • Siva

          yes you have to upload css files on to the server but it will be rendered by the browser :)

          • Daniel

            Thank you so much !

  • Amir Off

    align=”left” seems not work, any idea on how to align the header to the left?

    • TheVirusKA

      try in the CSS:
      float: left;

      • Amir Off

        Works but messes up with the rest of the text underneath the header…

      • Amir Off


        I had to edit the CSS file:

        .cd-intro {

        width: 100%;

  • Wemblo Themes

    awesome :)

  • Guy Lepage

    Beautiful yet again guys! Keep up the great work! And thank you again.

  • Reyad Rahman

    Cool Effect

  • William Servenay

    Génial ! Merci pour le partage ;)

  • Tim Plumb

    Great write up Sebastiano.

    I love some of the effects although I’m not sure if I’d want to rely on jQuery just to do the class allocation. I just seems too heavy unless you are already using it on the page.

    I did a similar text animation effect last year on my own site without JavaScript but using keyframes and animation delays (and all of the vendor prefix versions) to cycle between words;

    • Sebastiano Guerriero

      Really well done Time ;) Sometimes we use jQuery to make the nuggets more easy-to-customize (trying to keep in mind all case scenarios). But def CSS has to be preferred when it can replace javascript

    • Allan

      Do you mind sharing with me how you went about just using CSS? I’ve been trying to figure it out but haven’t had any luck.

      • Tim Plumb

        Hi Allan,
        Unfortunately I don’t have the time to explain the concept in full but the bare bones of the effect is that each word in the animation cycle is given an animation of ‘rotateWord’. This would normally animate them all at once so we add a class to each word (word1, word2, word3 etc) which sets the delay on the animation using the animation-delay property;

        If you get the timings right each animation will start as the last one ends.

        Here’s the full CSS for the animations;

        I hope this helps.

  • loic

    Rotate 2 effect doesn’t properly work on firefox 34.0.5 osx. Seems like the letters don’t respond to rotateX.

    • Sebastiano Guerriero

      True. We are trying to find a way to fix this. Ironically it worked in the older FF version, but we’re getting issues with the last one :)

  • yatin

    Thank you. Great and very helpful

  • ungeruehrt

    Hi, as mentioned on twitter am I looking for a solution to deactivate the loop so that the animation stops after the first round. Would be great if you could help – and thanks for your work again. It looks great!

    • Claudia Romano

      The takeNext() function (in te .js file) takes care of choosing the next word (right now if the word is the last one, it takes the first) so you should modify it so that when you reach the last word, it stops the animation. Hope this helps!

      • BBICS

        So what is the exact code snippet to stop the animation when it reaches the last word?

        cc @ungeruehrt:disqus

  • sortch

    Hi Sebastiano! It isn’t working for me. He display’s the first animation but not the following one’s

    • Sebastiano Guerriero

      Did you make sure to include all the javascript as well?

      • sortch

        Only the modernizer

        • Sebastiano Guerriero

          You should make sure to include also the main.js then, otherwise it won’t work

          • sortch

            Still not working :(

  • paralellos

    I want to use it without the static text but when the rotating words don’t have the static text in front the want center. How can I make the center?

    For example the first h1 reads General Plumbing the Roofing, Drainage, Gas Fitting and finally Solar Hot Water. The first h1 is centred as it takes up the entire span width but the others all sit to the left when loaded.

    any ideas are welcome thanks :)

  • Selim Rana

    Thanks for awesome work :)

    Is it possible to add dynamic width for full word animation because when i use animated word in middle of any sentence with different length of word (example: Welcome, Hello) it’s keep big space o right side. i tried to turn off the condition: else if (!headline.hasClass(‘type’) ) {} but some animation not work correctly for it.

  • Aayush Kumar

    Can anybody help in applying different animation effects to each letter of a single word …
    plz help

  • Riton87

    hello, thats a quite useful script, but why choosing classes such brackets b and i that clashes with most basic html..? I managed to get rid of the boldness but its still italic.. And could you provide clear direction on how to stop animation after one loop? Thanks in advance, it could be very useful for non developpers.

    • Sebastiano Guerriero

      Hi there! we use a reset.css file to eliminate default style for



      About how to stop animation after one loop:

      The takeNext() function (in te .js file) takes care of choosing the next word (right now if the word is the last one, it takes the first) so you should modify it so that when you reach the last word, it stops the animation. Hope this helps!

      • Riton87

        ok, thanks for the reset trick! About the takenext function i already have seen this answer below, and i have absolutely no idea about how to change it to stop it. Maybe you could provide the line of code? I use another script meanwhile, but as soon as i know ill switch back to yours

  • Axel Lessio

    I’ve just discovered your site, you guys are awesome! Not only you offer free high-quality material, your articles are also great learning tools for designers and developers. And as a designer/developer I must say that the whole site here looks great and works even better, very well done! – Axel

    • Sebastiano Guerriero

      thanks a lot for your kind words Axel!

  • Zoli Honig

    Seb, you’re a freakin rockstar. Using this!

  • Giulia

    Hi Sebastiano,
    first of all thanks for sharing! it’s a useful code!
    Could you tell me how can I add another sliding world into the same sentence?
    Because I’ve tried simply to copy the 3 tag after the static span, but it doesn’t work:



    I’m sorry but I’m not able to modify your js file!

    • Alexey

      Hi, giulia! Please give me your contacts and i help you.

      • Giulia

        I’ve found a problem with the library i’m using in my website (jquery.fullPage.js ; scroll.js); it seems that this particular scroll (like pdf slide) interferes with “Animated Headline” code, because without that js-file it works!

        • Alexey

          Hello, Giulia. Can I see yours portfolio?

  • Oñay Sheard

    Hey, I the download link isn’t working. I tried on Firefox and Chrome on two separate connections.

    • Claudia Romano

      Thanks for the heads-up. Should work now!

      • bradleyjoyce

        still not working

      • Oñay Sheard

        Thank you, for fixing the link so quickly! I didn’t expect such a fast response. These resources are amazing, I’m learning a lot.

  • Lucas Ignacio Quevedo

    hello sir, what is the license of this script

  • itarea

    Hello, awesome work, it’s working perfect but I have one single problem: I am using this to a div class “-webkit-filter: drop-shadow(1px 0px 1px #d8d8d8) drop-shadow(-1px 0px 1px #d8d8d8);” and seems conflicts with the text animation, the problem is they dissapear when the next text of the animated container is loading. I found this problem on chrome, on firefox is working perfect. Do you have an ideea how to fix this? Thank you

    • Claudia Romano

      Hi, glad you like that! :)
      Do you have a live version?

  • Mike

    I’m a newby, building with Squarespace. I’m trying to adapt this code, but am not successful. I’ve added a code block with the html structure, and then have added the css in the css editor, but get a syntax error at “var animationDelay = 2500;” I guessed I needed to replace the “=” with a “:” but this didn’t do the trick. Any help would be lovely.

  • laari

    Hi guys, great resource!
    I’m using Rotate 2 effect and everything works. My question is: I need to add “article – space – word” space is not considered and I see the two words attached. I’ve tried adding some css properties but I can’t find a solution. Any ideas?

    • Claudia Romano

      Hi, that’s because a void element has width 0 (if you check the html in the console, you can see the element) for the space, so you can try giving it a min-width. You may want to target it adding a class in the js (replace the line


      so you can style the .cd-void element. Hope this helps!

      • laari

        Thanks Claudia. I’m really a newbie with js… so I tried to replace the string you told me

        if(word.parents(‘.rotate-2′).length > 0) letters[i] = ‘‘ + letters[i] + ‘‘;

        with the new one but I don’t know which value I need to add into parenthesis and it doesn’t work properly.

        • Claudia Romano

          Sorry, I didn’t notice the code was not properly shown
          if(word.parents(‘.rotate-2′).length > 0) letters[i] = ( letters[i] == ‘ ‘ ) ? ‘‘ + letters[i] + ‘‘ : ‘‘ + letters[i] + ‘‘;

          And then add a min-width to the element. That should work.

        • Claudia Romano

          Sorry didn’t notice the bug in the reply. Disqus doesn’t seem to like my code! ;)
          Anyway here it is. But make sure to replace all the element with (don’t know why disqus hides them!)


          And then add a min-width to the .cd-void class in the css.

  • Keyhan Gholami

    Hi. thanks for your rerource. :)

    I’m using Type effect in four slideshows. when I go to next slide, some words doesn’t show because the animation was started after document.ready and a time elapsed to go next slide. I want to know is there a way to start animating just before go to the next slide?
    In the other words, I want a way to start or stop(reset) animation whenever I want?

    • Douglas Morales

      Hey Keyhan,
      Did you ever find a solution for this issue? I’m currently working on a project similar to this, and could use some guidance on where to start.

      • Keyhan Gholami

        Hi Douglas,
        No, I could not find any solution about this issue.

      • Keyhan Gholami

        Hi @disqus_hwvKm9cB4t:disqus,
        I couldn’t find any solution about this issue… .
        Could you please guide me about this?

        • Claudia Romano

          Hi Keyhan,
          the animateHeadline() is the function that starts the animation. So in the initHeadline(), instead of executing the animateHeadline(), you may try binding it to your start event (eg slide selected). Hope this helps!

          • Keyhan Gholami

            Thank you dear @claudiarrromano:disqus,
            I try to do your solution. but I have some issues about it. First of all, I don’t know which jquery event is recommended to bind animateHeadline() in it. I try to bind animateHeadline() to document with load event:

            $(document).bind(“load”, animateHeadline($(“.cd-headline”)));

            But I couldn’t unbind it when I want (In my slider method).

            And after that, is there any way to bind animateHealine() outside of initHeadline() method?

            thanks to your answer.. .

    • Keyhan Gholami

      Hi @claudiarrromano:disqus . could you guide me about this issue?

  • Keyhan Gholami

    Anybody who could answer my question?

  • Ankit Seth

    Looks amazing just like your other resources. I want to use this effect on a wordpress site. Can you please guide me on how it can be done?

  • Mike I

    I have tried to use the sass files for a few of your plugins and there seem to be missing variables and mixins in all the ones I have tried. Am I missing a file or are these not meant to work with sass?

    • Claudia Romano

      Hi Mike, make sure to include also the partials folder!

      • Mike I

        Hi Claudia, Thanks so much for your response! I actually have all the partials files included and referenced. Do I need to reference Bourbon as well?

        • Claudia Romano

          Hi Mike, in the style.scss file you can find all the imports (bourbon + partials). You should make sure you included that one too.

  • Allenivesix

    Hello nice trick, but don’t work on mobile?

  • Andrew Pipes

    Nice one, CodyHouse. :) For those after a jQuery-less, React version of the JS for this (well, the type variant anyway, which is more involved), I adapted it here:

  • Jay Henry

    How can I play the animation once and stop on the last word?

    • vannquish

      I’m trying to do the same. Can anyone help?

  • Samson Egbedele

    Very good and easy to install BUT there seems to be one annoying space added…I already spent time trying to remove the space…the space never left, even after removing all padding and margins…see red portion on the attached

  • Rengar

    seems like

    .cd-words-wrapper { display: inline-block; position: relative; text-align: left; }

    this part of the code makes center aligning off when you resize your browser. It comes back to center when you refresh the page though.

  • ultradesign

    Stop on last word: Figured this out-

    In main.js

    Replace :

    function takeNext($word) {
    return (!$‘:last-child’)) ? $ : $word.parent().children().eq(1);


    function takeNext($word) {
    return (!$‘:last-child’)) ? $ : $word.parent().children().last($newWord);

    • mywebstuff.hq

      This simply throws a ReferenceError

  • Koussay Fridhi

    i’m trying to put a link inside every word but i can’t !! how to please

    • Neph

      You’ll need to bind that tag to a java function to link it.. example, using jQuery. Note that url is absolute!:


      /* css style if you want to make it look ‘clickable’ */ {
      cursor: pointer;

      // jQuery)
      document.location.href = $(this).attr(‘rel’);

  • rjessa

    This is so awesome. Thank you.
    I’m using it so that it types out whole sentences, I can’t seem to get it to break into multiple lines though. How would that be possible?
    Also, what would I need to do to have it type sentences that disappear after they have been read and the other appears either at the same position or below it?
    Help would be much appreciated.
    Many thanks.

  • Kate Lim

    Hey, any idea how I would go about making it go to the line below if it goes out of the page?
    I’m making mine type a sentence and when I view my page on mobile, the letters get cut off :(
    I’m thinking of something along the line of keeping track of how much width I’ve used with the words I’ve typed and if adding the next word is out of the boundary, go to next line….
    Any suggestions would be appreciated. Thanks

  • jack holden

    how would i do the typing one because its not working

  • MJ

    Hello, i would ask you about a problem. I’m using your “Clip” effect, on a website based on Foundation 6. When i set it to do the effect changing pizza with “tis is an example” , it puts the sentence in 2 row, also with a lot of space .. Ho can i use it without it breack my example sentence in 2 rows? Thankyou.

  • mnlgr

    Hey, thanks for this amazing work.

    This my code :

    les concerts à venir.
    l’actualité musicale de la semaine.
    l’entretien de la semaine
    le focus de la semaine

    And i’d love to have a different color for each , do you have an idea ?
    Thanks :)

  • GaryB

    Really nice effect. Has anybody had any success in animating whole sentences with white-space between the words? That way it could wrap the text animation responsively. If so, can you let me know how. Thanks.

  • Cody Whitworth

    You guys are absolutely amazing. The UI of the site, the free code you provide, everything. Thank you for doing what you do!

  • Shubham

    It doesnt work in angular js. Can anybody help

  • Lukáš Cibula

    hi, great job :D it works perfectly when you have text aligned to the left but is there any way to center it? I am using text string with different widths and it looks weird when the text is not centered. I’ve been trying to do it, but no luck so far :D can anybody help?

  • matthew gregg

    Any idea what effect this has on google SEO for your h1? The crawler can still read all the text but google has mentioned before that it devalues text hidden with css. Not sure if we have any search experts viewing this post…

    • Stephen Dench

      Do not use this on a H1 if you value SEO on that page….

      Just put it on a p tag element and have your H1 somewhere else as normal

  • Gajendrasinh Zala

    – From an idea to a brilliant product.
    – From an emerging product to a legacy product.

    – A vision into a business.
    – A business plan to a success.

    – An enterprise to its end users.
    – Potential users through social media.

    I m use push class for getting text

    by default left to right. but i need right to left move how can i do this

  • Aftar Fadilah

    Can someone tell me how to install the codes on blogger? because I’m absolutely can’t understand what is happening and what I’m doing on the codes.

    • Yasir Lateef

      It’s been 3 months now, but I can help you install the codes if you haven’t done it already. Btw, I’m Yasir and I’d love to help you out! Cheers!

  • llahnoraa

    Is this Animated Headline accessible to screenreader? Thank you.