Rotating Words with CSS Animations

Using CSS Animations we will change or rotate some parts of a sentence.

Rotating Words with CSS Animations

View demo Download source

In today’s tutorial we’ll create another typography effect. The idea is to have some kind of sentence and to rotate a part of it. We’ll be “exchanging” certain words of that sentence using CSS animations.

Please note: the result of this tutorial will only work as intended in browsers that support CSS animations.

So let’s start!

In the following, we’ll be going through demo 2.

The Markup

We’ll have a main wrapper with a h2 heading that contains first-level spans and two divisions for the rotating words:

<section class="rw-wrapper">
	<h2 class="rw-sentence">
		<span>Real poetry is like</span>
		<div class="rw-words rw-words-1">
			<span>breathtaking moments</span>
			<span>lovely sounds</span>
			<span>incredible magic</span>
			<span>unseen experiences</span>
			<span>happy feelings</span>
			<span>beautiful butterflies</span>
		<br />
		<span>with a silent touch of</span>
		<div class="rw-words rw-words-2">

Now, ignoring the garbage placeholder text, we want each span of the rw-word to appear at a time. For that we’ll be using CSS animations. We’ll create one animation for each division and each span will run it, just with different delays.
So, let’s look at the CSS.

The CSS3

First, we will style the main wrapper and center it on the page:

	width: 80%;
	position: relative;
	margin: 110px auto 0 auto;
	font-family: 'Bree Serif';
	padding: 10px;

We’ll add some text shadow to all the elements in the heading:

	margin: 0;
	text-align: left;
	text-shadow: 1px 1px 1px rgba(255,255,255,0.8);

And add some specific text styling to the spans:

.rw-sentence span{
	color: #444;
	white-space: nowrap;
	font-size: 200%;
	font-weight: normal;

The divisions will be displayed as inline elements, that will allow us to “insert” them into the sentence without breaking the flow:

	display: inline;
	text-indent: 10px;

Each span inside of a rw-words div will be positioned absolutely and we’ll hide any overflow:

.rw-words span{
	position: absolute;
	opacity: 0;
	overflow: hidden;
	width: 100%;
	color: #6b969d;

Now, we’ll run two animations. As mentioned previously, we’ll run the same animation for all the spans in one div, just with different delays:

.rw-words-1 span{
	animation: rotateWordsFirst 18s linear infinite 0s;
.rw-words-2 span{
	animation: rotateWordsSecond 18s linear infinite 0s;
.rw-words span:nth-child(2) { 
	animation-delay: 3s; 
	color: #6b889d;
.rw-words span:nth-child(3) { 
	animation-delay: 6s; 
	color: #6b739d;	
.rw-words span:nth-child(4) { 
	animation-delay: 9s; 
	color: #7a6b9d;
.rw-words span:nth-child(5) { 
	animation-delay: 12s; 
	color: #8d6b9d;
.rw-words span:nth-child(6) {  
	animation-delay: 15s; 
	color: #9b6b9d;

Our animations will run one cycle, meaning that each span will be shown once for three seconds, hence the delay value. The whole animation will run 6 (number of images) * 3 (appearance time) = 18 seconds.
We will need to set the right percentage for the opacity value (or whatever makes the span appear). Dividing 6 by 18 gives us 0.333… which would be 33% for our keyframe step. Everything that we want to happen to the span needs to happen before that. So, after tweaking and seeing what fits best, we come up with the following animation for the first words:

@keyframes rotateWordsFirst {
    0% { opacity: 1; animation-timing-function: ease-in; height: 0px; }
    8% { opacity: 1; height: 60px; }
    19% { opacity: 1; height: 60px; }
	25% { opacity: 0; height: 60px; }
    100% { opacity: 0; }

We’ll fade in the span and we’ll also animate its height.

The animation for the words in the second div will fade in and animate their width. We added a bit to the keyframe step percentages here, because we want these words to appear just a tiny bit later than the ones of the first word:

@keyframes rotateWordsSecond {
    0% { opacity: 1; animation-timing-function: ease-in; width: 0px; }
    10% { opacity: 0.3; width: 0px; }
	20% { opacity: 1; width: 100%; }
    27% { opacity: 0; width: 100%; }
    100% { opacity: 0; }

And that’s it folks! There are many possibilities for the animations, you can check out the other demos and see what can be applied!


  1. Demo 1: Animate down
  2. Demo 2: Animate height and width
  3. Demo 3: Fade in and “fall”
  4. Demo 4: Animate width and fly in
  5. Demo 5: Rotate in 3D and “sharpen”

I hope you enjoyed this tutorial and find it inspiring!

View demo Download source


Tagged with:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by


Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.