Comments:"Animating the New Parse About Page"
URL:http://blog.parse.com/2013/01/10/animating-the-new-parse-about-page/
One of our last projects of 2012 was to give our About page a fresh new look. The day we started working on its redesign, we knew we wanted it to really express what Parse is about, and that we wanted it to be beautiful and enjoyable to go through.
Because we received such great feedback on our previous Cloud Modules animated icon tutorial, today I’m offering you some insight on how we built the new about page top animation using some of the newest CSS3 features. We’ll be using SASS/Compass for more clarity in the code.
Let’s start by creating the HTML for this animation.
<div class="container"><div class="background"><div class="devices_gray"><div class="bg"></div></div><div class="devices_colorful"><div class="bg"></div></div></div><div class="cloud">Parse</div></div>
Here we have a container
div, that will essentially be used to create the dark background and position it correctly in the page. Its SCSS code is pretty simple. We just add a radial gradient that starts at the top center of the div, and a background color as a backup for non-compatible browsers. The clearfix
mixin is provided by Compass and basically adds an overflow: hidden
to the class.
.container{ width: 1080px; height: 1080px; background-color: #1d1d1d; @include background-image(radial-gradient(center top, circle, color-stops(rgba(#686868, 0.8), rgba(#1d1d1d, 0.6) 500px))); @include clearfix; }
Our container
div has 2 children:
background
is the div that will contain the moving devices.background
also has 2 children that we’ll use to create 2 layers of devices: one for the gray ones, and one for the colored ones.cloud
will contain a transparent PNG with the shape of the cloud, a white stroke, an inner dark shadow, some glare and our Parse logo.
Now let’s dive into the interesting part: the moving devices. To prevent our page from taking very long to load, and to be able to only show the colored devices inside the Cloud shape, we’re using one of the lastest WebKit features called -webkit-mask
. Unfortunately, this feature is not supported by IE or Firefox, but since we’re lucky enough to have more than 90% of our users using a WebKit browser, we’ve decided to offer them the best experience possible, while we still have a fallback image for incompatible browsers.
First of all, let’s give .devices_gray
, .devices_gray .bg
and .devices_colorful .bg
the right positioning and size.
.devices_gray, .devices_gray .bg, .devices_colorful .bg { width: 2600px; height: 1200px; position: absolute; top: 0px; left: 0px; }
Now let’s work on making our devices_gray
do what we want: show gray devices. To do that, we will give the inner bg
div a gray color, and use -webkit-mask-image
to use our devices.png file as a mask.
.devices_gray { -webkit-mask-image: -webkit-gradient(linear, left 80%, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); z-index: 1; .bg { left: -1500px; top: 0px; background: #252525; opacity: 0.4; -webkit-mask-image: url(/images/about/devices.png); } }
Notice that we’ve used z-index
to make sure devices_gray
and its gray devices will end up behind the colored ones, but most importantly, that we used a -webkit-gradient
that goes from dark to transparent as a mask to this div, so that our devices_gray
div smoothly disappears at the bottom. This is a great trick to know about if you want to play with opacity and gradients in WebKit.
Now let’s work on the devices_colorful
div.
.devices_colorful { -webkit-mask-image: url(/images/about/cloud_mask.png); width: 473px; height: 308px; position: absolute; left: 270px; top: 170px; z-index: 2; .bg { left: - 270px - 1500px; top: - 170px; @include background-image(linear-gradient(left, #FECC62 0%, #FECC62 5%, #FEA862 10%, #FE4762 15%, #FE47D8 20%, #E069FB 25%, #B285FB 30%, #65C1FB 35%, #FECC62 40%, #FECC62 45%, #FEA862 50%, #FE4762 55%, #FE47D8 60%, #E069FB 65%, #B285FB 70%, #65C1FB 75%, #FECC62 80%, #FECC62 85%, #FEA862 90%, #FE4762 95%, #FECC62 100%)); -webkit-mask-image: url(/images/about/devices.png); } }
Here we’re re-using our devices.png file as a mask on top of a rainbow gradient for the bg
inner div.
For devices_colorful
, we’re again using -webkit-mask-image
and a transparent PNG that has exactly the shape of the Parse cloud. By doing this, and applying it to devices_colorful
, we’re making sure that only the part that is contained in that cloud shape will be visible. This is how we get the effect where the colored devices are only visible inside the cloud.
What we need to do now is to animate our devices. To do that, we basically have two options:
- Animate the masks, which is great if, for example, we want the colored devices to move on top of a fixed gradient or image, or if we want them to infinitely move in the same direction. Unfortunately, this operation is very expensive in terms of CPU usage, and will make our animation very slow.
- Animate the two
bg
divs themselves horizontally. This is the method we’re going to use, since translating a div is something WebKit can easily handle.
.devices_colorful .bg, .devices_gray .bg { @include animation(devicesBackground, 30s, 0s, ease-in-out, infinite, alternate); }
Here, we add to both our bg
divs an animation called devicesBackground
, with a 30s duration, that will start immediately, with an ease-in-out
easing function, that will run infinitely and in both directions (left to right and right to left).
Since Compass doesn’t offer a good animation
mixin, I’m happy to share ours with you.
@mixin animation($name: fadeIn, $duration: 1s, $delay: 0s, $function: ease, $iterations: infinite, $mode: both) { @each $prefix in webkit, moz, ms { #{""}-#{$prefix}-animation: $name $duration $delay $function $iterations $mode; } animation: $name $duration $delay $function $iterations $mode; }
Now all we need to do is to declare this devicesBackground
animation to make it do what we want.
// We only declare the WebKit keyframes here since our animation is only WebKit-compatible @-webkit-keyframes devicesBackground { 0% { -webkit-transform: translate3d(0px, 0px, 0); } 100% { -webkit-transform: translate3d(1300px, 0, 0); } }
Perfect. We now have the gray and colored devices gracefully moving together. The last thing we need to do now is to add our Cloud transparent PNG on top of it and we’ll be done.
.cloud { background: url(/images/about/cloud.png) no-repeat; width: 473px; height: 308px; position: absolute; left: 270px; top: 170px; z-index: 3; font-family: 'Raleway', 'Helvetica Neue', Helvetica, arial, sans-serif; font-size: 65px; text-align: center; line-height: 350px; color: white; text-shadow: rgba(black, 0.7) 0px 2px 7px; font-weight: 400; }
That’s it! We now have a gorgeous CSS3 animation for the new Parse About page.
And here’s our final SCSS code.
@-webkit-keyframes devicesBackground { 0% { -webkit-transform: translate3d(0px, 0px, 0); } 100% { -webkit-transform: translate3d(1300px, 0, 0); } } $container_width: 1080px; $container_height: 1080px; $left_positionning : -1500px; $cloud_left: 270px; $cloud_top: 170px; .container{ width: $container_width; height: $container_height; background-color: #1d1d1d; @include background-image(radial-gradient(center top, circle, color-stops(rgba(#686868, 0.8), rgba(#1d1d1d, 0.6) 500px))); @include clearfix; .devices_gray, .devices_gray .bg, .devices_colorful .bg { width: 2600px; height: 1200px; position: absolute; top: 0px; left: 0px; } .devices_gray { -webkit-mask-image: -webkit-gradient(linear, left 80%, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); z-index: 1; .bg { left: $left_positionning; top: 0px; background: #252525; opacity: 0.4; -webkit-mask-image: url(/images/about/devices.png); } } .devices_colorful { -webkit-mask-image: url(/images/about/cloud_mask.png); width: 473px; height: 308px; position: absolute; left: $cloud_left; top: $cloud_top; z-index: 2; .bg { left: - $cloud_left + $left_positionning; top: - $cloud_top; @include background-image(linear-gradient(left, #FECC62 0%, #FECC62 5%, #FEA862 10%, #FE4762 15%, #FE47D8 20%, #E069FB 25%, #B285FB 30%, #65C1FB 35%, #FECC62 40%, #FECC62 45%, #FEA862 50%, #FE4762 55%, #FE47D8 60%, #E069FB 65%, #B285FB 70%, #65C1FB 75%, #FECC62 80%, #FECC62 85%, #FEA862 90%, #FE4762 95%, #FECC62 100%)); -webkit-mask-image: url(/images/about/devices.png); } } .devices_colorful .bg, .devices_gray .bg { @include animation(devicesBackground, 30s, 0s, ease-in-out, infinite, alternate); } .cloud { background: url(/images/about/cloud.png) no-repeat; width: 473px; height: 308px; position: absolute; left: $cloud_left; top: $cloud_top; z-index: 3; font-family: 'Raleway', 'Helvetica Neue', Helvetica, arial, sans-serif; font-size: 65px; text-align: center; line-height: 350px; color: white; text-shadow: rgba(black, 0.7) 0px 2px 7px; font-weight: 400; } }