We were recently given a banner ad spot over on Codepen, a code prototype and community platform for developers. Between people’s banner blindness and the low click-through rates associated with banner advertising, we knew we had to do something a bit different to stand out.

Working with our Marketing team, we decided that promoting the responsive capabilities of our new email builder, Canvas, would be the most relevant topic for the Codepen community. Instead of designing a static banner ad, we decided to code the entire banner, animation and all, without using images.

The Banner

While you can view the fully coded version over on Codepen, below is an animated GIF to show the banner in action.

{title}

The Process

Before thinking about animation or sinking our teeth into the complexity of the task ahead, we started by tackling the messaging and design. Canvas is an intuitive drag and drop tool to design emails that work everywhere, so we wanted to reflect those qualities in the ad itself. The “works everywhere” aspect was the main point we wanted to get across, so showing an email being built and displayed in various devices was the concept we landed on.

Once that was sorted, we started designing the main animation frames using our own illustrative style. At this point, even though the designs weren’t polished, we jumped into code.

Re-creating key frames in HTML and CSS

When you look at it closely, the devices we designed are very similar. Each device has a border, a screen and an email containing both a header and content. In fact, all icons share the same HTML markup:

<div class="device">
    <div class="screen">
      <div class="email">
        <div class="header">
        </div>
        <div class="content">
        </div>
      </div>
    </div>
</div>

Some of those icons share the same CSS rules:

.device {
	position: absolute;
	bottom: 50%;
	left: 50%;
	background: #202123;
	box-sizing: border-box;
}

.device .screen {
	background: #D9DEE2;
	width: 100%;
	height: 100%;
	overflow: hidden;
}

Each device icon has its own property:

.device.desktop {
	min-width: 222px;
	min-height: 147px;
	border-radius: 5px;
	margin-bottom: -73px;
	margin-left: -111px;
	padding: 11px 12px 16px 11px;
}
.device.tablet {
	min-width: 88px;
	min-height: 130px;
	border-radius: 6px;
	margin-bottom: -65px;
	margin-left: -44px;
	padding: 11px 4px 13px 4px;
}

// Camera above the tablet's screen
.device.tablet:before {
	content: '';
	position: absolute;
	min-width: 2px;
	min-height: 2px;
	background: #72777D;
	left: 50%;
	top: 5px;
	margin-left: -1px;
}

// Tablet's home button
.device.tablet:after {
	content: '';
	position: absolute;
	min-width: 8px;
	min-height: 8px;
	background: #72777D;
	border-radius: 50%;
	left: 50%;
	bottom: 2px;
	margin-left: -4px;
}

.device.phone {
	min-width: 54px;
	min-height: 110px;
	border-radius: 3px;
	margin-bottom: -55px;
	margin-left: -27px;
	padding: 11px 3px 14px 3px;
}

// Speaker above the phone's screen
.device.phone:before {
	content: '';
	position: absolute;
	min-width: 10px;
	min-height: 2px;
	background: #72777D;
	left: 50%;
	top: 5px;
	margin-left: -5px;
}

// Phone's home button
.device.phone:after {
	content: '';
	position: absolute;
	min-width: 8px;
	min-height: 8px;
	background: #72777D;
	border-radius: 50%;
	left: 50%;
	bottom: 3px;
	margin-left: -4px;
}

Animating the frames

Instead of having static frames that abruptly jump from one to another, we really wanted to create a memorable experience by animating those frames. Since all devices share the same HTML markup but have different CSS properties, we could animate the way each device styling was applied by using the CSS transition property.

.device, .device:before, .device:after, .device .screen {
	transition: 0.1s all ease-in;
}

However, just using the transition property didn’t feel quite right. We wanted to make it look more natural by having the devices morphing into each other so we created our own morphing animation using the transform rule within the keyframes of the CSS animation property:

 {
	0% {
		transform: scale3d(.8, .8, .8);
	}
	20% {
		transform: scale3d(1.05, 1.05, 1.05);
	}
	40% {
		transform: scale3d(.95, .95, .95);
	}
	60% {
		transform: scale3d(1.01, 1.01, 1.01);
	}
	80% {
		transform: scale3d(.99, .99, .99);
	}
	100% {
		transform: scale3d(1, 1, 1);
	}
}

.device {
	// Animate using the morphingAnimation keyframes over 300ms after a delay of 100ms
	animation: morphingAnimation 300ms linear 100ms;
}

Timing the frames

The last step of the process was to find the right timing between the original key frames. We made the timing decision based on what mattered most and how it felt. In order to apply the right styling at the right time, we needed to add the class of the device we wanted to be displayed to the HTML element using JavaScript.

setTimeout(function() {
      device.removeClass('desktop').addClass('tablet');
}, 9500);

setTimeout(function() {
      device.removeClass('tablet').addClass('phone');
}, 11500);

In conclusion

Jumping straight into coding the ad definitely helped us figure out a few things early.

Designing and coding the ad in parallel helped us to understand what could and couldn’t be achieved and it meant we were able to deliver the final product earlier than expected without backtracking. However, we found that focusing on specific animations between devices made us forget about how the ad would work as a whole. The result of this was redundant code that was probably more complicated than it should have been.

Overall, we had a lot of fun working on this project. It was great to be able to experiment with the code and learn a few new things about how CSS animation works.

See the final ad

  • Chris

    Amazing work without images!

  • Lee

    The CSS animated banner looks seamless. Wow..great job guys…and thanks for the share!

  • Ryan

    This is really great, however I noticed that if you click the top right of the ad (where the restart button shows at the end) before the animation ends, it restarts the whole thing and tends to mess how things load in since they are still in transition. Maybe you could move the button out of frame until it is needed?

  • Steven Fabre

    Hi there all, thanks so much for the kind words.

    Ryan, thank you for pointing this out and suggesting a solution. It’s definitely something we’ve missed out. Fortunately, the fix has been done and it’s just a matter of time before the world can see it :)

  • Victor

    Thanks for publishing and sharing code here and on Codepen :-). Looks great!

  • Ambra

    Does it solve Outlook banner blindness? Can we code banners inside CM newsletters too?

  • Paul West

    Hi Ambra, right now the methods used here would be a little too much for Outlook to handle I’m afraid! Outlook does still have trouble displaying any kind of animation. Hopefully this can help out with other areas that you are working on :)

  • Saurav Rastogi

    Its really amazing… Its a cool idea

  • ATL

    What is the file size? There’s usually a 35k file size limit for most online ad placements.

  • Ros Hodgekiss

    Hi there ATL, as it’s code-only, the above ad comes in at a zippy 8.4kb.

    Note that file size limits are usually set by the advertiser; personally I’d recommend making sure that your ads are as speedy as possible. This is why using CSS animation over say, an animated GIF is an awesome choice, as it means less calls to external assets and much smaller payloads/load times.

  • Sergiu

    no more ugly white space on your colorful background. Huzzah for css!

  • Stephen

    Great work. I’m curious how this performs on browsers that don’t support CSS Animation? Have you just taken this route because 99% of your target audience will be using an appropriate browser? Or is this a feasible method for banner adverts in a wider, more general sense? Thanks

  • Ros Hodgekiss

    Hi there Stephen, happy to answer here :) The short answer is that we spoke to the CodePen team about their audience and found out that the number of site visitors with legacy browsers is practically zero. As predicted, the designers and developers who use their service tend to keep their apps up to date – and so far we have received no reports of browser issues.

    That said, you do raise the issue of creating adverts that can be safely displayed to other audiences. I dare say that if you’re catering to an audience with a significant percentage of legacy browser users, you would likely stick to good old fashioned animated GIFs, or perhaps even static images. Different horses for courses, as they say :)

  • Shohag Islam Sourav

    Nice css style, glad to get it here

Want to improve your email marketing? Subscribe to get tips on improving your email marketing delivered to your inbox.
X

Join 200,000 companies around the world that use Campaign Monitor to run email marketing campaigns that deliver results for their business.

Get started for free