The New Hotness: Using CSS3 Visual Effects

Advertisement

Previously in this series on CSS3, we talked not only about how to create scalable and compelling buttons1 but about how to effectively use new CSS3 properties2 to speed up development and quickly create rich page elements. In this final article of the series, we’ll really get into it and use CSS3 visual effects to push the envelope.

Not everything in this article is practical, or even bug-free, but it’s a fun primer on what’s in the pipeline for Web design. To get the most from these examples, you’ll have to use Safari 4 or Chrome. (Firefox 3.5 can handle most of it, but not everything: WebKit is further along than Gecko in its tentative CSS support.) We’ll show you how to create impressive image galleries, build animated music players and overlay images like a pro. All set? Let’s rock.

Create A Polaroid Image Gallery

Polaroid image gallery3

We always try to stay pretty active with our Flickr feed4; our chief instigator Bryan does a great job of capturing the day-to-day and special events and even some of our old work. We wanted a great way to show off these photos, so we turned to CSS3 to create a compelling, fun image gallery. The Polaroid style is pretty common, but we wanted not only to make it dead-simple to create the gallery in the markup but also to add styles that would have required Javascript just a year or two ago.

The Polaroid Gallery Markup

First off, we created very simple markup for the gallery, something that would be easy to generate automatically using the Flickr API. The markup for the entire gallery looks like this:

<ul class="polaroids">
	<li>																				  
	   <a href="http://www.flickr.com/photos/zurbinc/3971679981/" title="Roeland!">	  
	   	<img src="image-01.jpg" width="250" height="200" alt="Roeland!" />
	   </a>																			  
	</li>																				  
	<li>																				  
	   <a href="http://www.flickr.com/photos/zurbinc/3985295842/" title="Discussion">	  
	   	<img src="image-02.jpg" width="250" height="200" alt="Discussion" />	
	   </a>																		 
	</li>																				  
</ul>

We’ll be using the title element in a minute.

The Base Style and Labels

Our next step was to create the simple Polaroid look. We placed our image inside an anchor with a white background and scaled the image container. This gave us space for the image labels, which we created using little-known CSS tricks: :after and content: attr.

ul.polaroids a:after {
	content: attr(title);
}

What we’re doing here is telling the browser that after it renders the given anchor content, add another piece of content. We then generate that piece of content with the content: attr(title) element, which pulls a specific attribute from the element, in this case the title attribute. Using alt would make more sense, but neither Safari nor Firefox has implemented it for the content element.

The snippet above tells the browser to take the title attribute and render it immediately after the content. Note that the title attribute will be rendered within the anchor, which is exactly what we want. We would have liked to have used the alt attribute, but Safari and Firefox do not support the use of content with it.

Our styling of the anchor element takes care of the formatting of the title attribute as well, and we’ve now placed the image title attribute below it so that we don’t have to replicate that content in the markup.

Scattering the Pictures

A handful of Polaroids would never be in a perfect grid; they’d be scattered over the table. We compromised by messing up the grid a little bit for each image: a little rotation here, some displacement there. However, we did not want to have to manage that scattering on a per-image basis, so we used another new pseudo-class: nth-child.

/* By default, we tilt all images by -2 degrees */
ul.polaroids a {
	-webkit-transform: rotate(-2deg);
	-moz-transform: rotate(-2deg);
}

/* Rotate all even images 2 degrees */ ul.polaroids li:nth-child(even) a { -webkit-transform: rotate(2deg); -moz-transform: rotate(2deg); } /* Don't rotate every third image, but offset its position */ ul.polaroids li:nth-child(3n) a { -webkit-transform: none; -moz-transform: none; position: relative; top: -5px; }

These are only a few of the declarations we used; we actually added them for everything up to 11n, but you get the idea. As you can see, nth-child supports a few different arguments, including even, odd and Xn (where X can be any integer). The even and odd declarations are self-explanatory. Xn takes every Xth element and applies a particular style; in this example, every 3rd. Combining this with odd, even and some more Xn declarations means that even though the style won’t really be random, it will appear random enough to the average user. You can see the entire set of styles on our demo page5.

We’re using a new CSS3 property here as well: the CSS transform (shown as -webkit- and -moz-transform). The transform property can take a number of arguments for different kinds of transformations; in this example, we’ll be using rotate and scale. You can see the complete (tentative) list in the Safari Visual Effects Guide6.

Some Final Animation

Our last touch was to give the image focus on hover; in this case, to enlarge and straighten out. We accomplish this using a -webkit-transition that is activated by the :hover pseudo-class. Check it out:

ul.polaroids a:hover {
	-webkit-transform: scale(1.25);
	-moz-transform: scale(1.25);
	-webkit-transition: -webkit-transform .15s linear;
	position: relative;
	z-index: 5;
}

What’s happening here is that we’re overriding the existing -webkit-transform to simply scale the image (this eliminates the rotation). The -webkit-transition tells Webkit-based browsers to animate the transform so that the move from one to another is smooth. -webkit-transition is actually extremely versatile, because it can just as easily support color, position (top, right, etc.) and most any other property.

That’s how we created our Polaroid gallery. Once you know these new tricks, putting them together is actually pretty easy, and the markup is dead simple.

Polaroid image gallery7

See the Live Demo »8

We’ve created a live demo page for this gallery in our Playground, a place for us ZURBians to create small side projects and samples of cool toys. We’ll be linking to the Playground examples throughout this article.


Sliding Vinyl Albums With CSS Gradients

Vinyl albums9

This example began as a simple experiment with CSS gradients and grew into a pretty detailed investigation not just of gradients but of new background properties and animation. We’ll show you how to create advanced gradients with no images and use layered backgrounds for some cool effects.

Writing the Markup

What we’ve created here is a simple unordered list of albums with slide-out album controls. You could use something like this to present your band’s albums or to showcase a series of podcasts or any other kind of audio (or potentially video) media. Each item in the list is an album, with some fairly simple markup:

<div class="album">
	<a href=""><img src="/playground/sliding-vinyl/muse-the-resistance.jpg" width="500" height="375" alt="Muse: The Resistance" /></a>
	<span class="vinyl">
		<div></div>
	</span>
	<ul class="actions">
		<li class="play-pause"><a href=""></a></li>
		<li class="info"><a href=""></a></li>
	</ul>
	<div>
		<h5>Muse</h5>
		<small>The Resistance</small>
	</div>
	<span class="gloss"></span>
</div>

It might look like a few extraneous elements are in there, but we’ll be using all of them to render our slide-out record and controller buttons.

Creating the Record

Record10 The real trick here was the album. We challenged ourselves to create the album without using any images at all (we ended up cheating a bit, but we’ll get to that). When it slides out, the album looks like the figure on the left: standard black vinyl with a slight shine to it and a couple of control buttons.

You’ll notice that the inside edge of the album is a little jagged, and that’s because the album isn’t an image but rather two layered gradients generated by the browser and set as the background of the same object. This required not only a bit of messing around with the new gradient objects in CSS3 but also another CSS3 trick: multiple backgrounds. Check out the CSS for the record:

ul.tunes li div.album span.vinyl div {
	display: block; 
	border: solid 1px black; 
	width: 112px; 
	height: 112px; 
	-webkit-border-radius: 59px; 
	-moz-border-radius: 59px; 
	-webkit-box-shadow: 0 0 6px rgba(0,0,0,.5); 
	-webkit-transition: all .25s linear; 
	background:
		-webkit-gradient(
			linear, left top, left bottom, 
			from(transparent),
			color-stop(0.1, transparent),
			color-stop(0.5, rgba(255,255,255,0.25)),
			color-stop(0.9, transparent), 
			to(transparent)),
		-webkit-gradient(
			radial, 56 56, 10, 56 56, 112, 
			from(transparent),
			color-stop(0.01, transparent),
			color-stop(0.021, rgba(0,0,0,1)),
			color-stop(0.09, rgba(0,0,0,1)),
			color-stop(0.1, rgba(28,28,28,1)),
			to(rgba(28,28,28,1)));
	border-top: 1px solid rgba(255,255,255,.25);
}

We’ve omitted some of the positioning and other boring CSS pieces (check out the live demo for the complete markup). We want to focus here on the pieces that are critical to creating the album visually: border-radius and -webkit-gradient.

The simplest part was creating a round object: by setting the border radius to exactly half of the height and width of the object, the browser masks the object to a perfect circle. Watch out, though: unlike in Photoshop, if the border radius is higher than half the object’s height or width, the browser might simply ignore the declaration. That said, rounding the object is the easy part; the tricky part is controlling the gradients.

Two gradients are at work on the object: one creates the album itself (complete with the hole in the middle), and the other casts a light across it. We’ll start with the shine:

ul.tunes li div.album span.vinyl div {
	...
	background:
		-webkit-gradient(
			linear, left top, left bottom, 
			from(transparent),
			color-stop(0.1, transparent),
			color-stop(0.5, rgba(255,255,255,0.25)),
			color-stop(0.9, transparent), 
			to(transparent)),
			...
}

The shine gradient is a linear gradient from the top-left to bottom-left. We start with transparent so that the gradient fades in, then we shift the gradient to white at the 50% mark (halfway across the album), with 25% opacity. We’re using RGBa colors because they allow us to control both the color and opacity in the same declaration.

The album itself is more complicated, and it suffers a bit from early implementation of the radial gradient.

ul.tunes li div.album span.vinyl div {
	...
	background:
		...,
		-webkit-gradient(
			radial, 56 56, 10, 56 56, 112, 
			from(transparent),
			color-stop(0.01, transparent),
			color-stop(0.021, rgba(0,0,0,1)),
			color-stop(0.09, rgba(0,0,0,1)),
			color-stop(0.1, rgba(28,28,28,1)),
			to(rgba(28,28,28,1)));
	...
}

Radial gradients are just as they sound, and just what you’d expect from gradients in Photoshop. They begin at the center of the object and track across the object in concentric circles. In our case, we wanted to start with transparency, then switch to a solid black, and end up with a very dark gray.

Perhaps the most difficult part of the gradient is declaring its size and position: radial, 56 56, 10, 56 56, 112. We have five pieces of data here: type, starting center, starting diameter, ending center and ending diameter. Here’s how they work:

  • Radial is, of course, where we define this as a circular gradient rather than straight (linear) gradient.
  • We begin at 56 56, which is exactly half the height and width of our 112-pixel-tall object. We want the gradient to end with the same center, so we repeat 56 56.
  • The gradient begins with a diameter of 10 pixel.
  • The ending center (56 56) ensures that this is a concentric gradient.
  • 112 is our final diameter, the same width as the object.

The radial implementation was still a bit rough around the edges, so we played around with these values and the color-stop elements to get the effect we wanted. In the future, a more polished implementation won’t be quite so trial and error.

Album cover with disc11 From there, similar to the linear gradient, we created a series of color-stops to go from transparent to black to dark gray. The result of these two backgrounds (separated by a comma—thanks, CSS3) is our shiny record. Again, you’ll notice the center is a bit rough, but we’re sure future implementations of this new element will be cleaner.

The button controls are simply rounded anchors (using border-radius), with a couple of image glyphs (we told you we cheated a bit). The final touch was to add the animation so that the album would roll out of the sleeve on hover.

Adding in the Final Animation

To achieve the rolling effect, we paired up a position shift and a rotation effect so that, as the object moves to the right, it rotates just the right amount to appear as if it’s rolling. Here’s what we did:

ul.tunes li div.album span.vinyl { 
	-webkit-transition: all .25s linear; 
}

ul.tunes li div.album:hover span.vinyl { 
	-webkit-transform: translateX(60px); 
}

ul.tunes li div.album:hover span.vinyl div { 
	-webkit-transform: rotate(120deg);
}

We’re using two transforms, translateX and rotate, on two objects. We use the translate instead of standard positioning because transforms don’t impact the DOM—from a layout perspective, the object never really moves, and so we don’t have to worry about floats going awry or objects pushing each other around. Transitions also work better on translation transforms than on actual position (left: 20px, etc.) changes.

Gradients have a ways to go, but there are already some cool uses for generated gradients. You can even control them at runtime using transitions or JavaScript, which opens up yet more possibilities.

Sliding vinyl12

See the Live Demo »13

We’ve created a live demo page for this gallery in our Playground, so you can see it in action and delve deeper into the source code. Enjoy!


Sweet Overlays With Border-Image

Border image14

This last part is perhaps the most practical. We use it in our feedback tool Notable2115 every day. The border-image property is new but has some really interesting applications. We’ll explain how it works and how we’re using it in our flagship application.

The Overlay Markup

Overlays in Notable have two parts: the frame and the actual glass overlay. The markup for the overlay is pretty simple, consisting of two sibling DIVs:

<div class="note" id="note1">
	<div class="border"></div>
	<div class="overlay"></div>
	<span class="black circle note">1<span class="wrap"></span></span>
</div>

When we created these overlays, we had a few goals:

  • They shouldn’t overly obscure the content beneath them.
  • They shouldn’t affect the hue of the content beneath them.
  • They must look awesome.

To that end, we devised an overlay that would appear as a glass overlay, with a slight shine and a nice, fairly bold frame. For the purposes of this article, we’ll focus on the frame, which we created using the new border-image property.

Using Border-Image

The new border-image property is a strange beast: very versatile, but takes a little getting used to. Here’s what the border-image declaration for our frame looks like in the CSS:

div.note div.border {
	border: 5px solid #feb515;
	-webkit-border-radius: 3px; 
	-moz-border-radius: 3px;
	-webkit-border-image: 
		url(/playground/awesome-overlays/border-image.png) 5 5 5 5 stretch;
	-moz-border-image: 
		url(/playground/awesome-overlays/border-image.png) 5 5 5 5 stretch;
}

Let’s get the easy stuff out of the way. The border element is both required and a fallback: older browsers will still render a usable border for the overlay, but border-image requires a defined border width. While we’ve been fairly unconcerned with backwards-compatibility in our articles, in this case we needed it (Notable has to work in more than just cutting-edge browsers). This is one of many examples of progressive enhancement (or graceful degradation, if you prefer): older browsers render something usable, just less pretty. The first progressive piece in here is the border-radius, which we’ve already discussed at length.

The border-image is what we’re interested in. Check out the figure to the right; notice the gradient on the frame that goes from top to bottom? It’s a simple touch, but adding it to an object that has to scale to many different sizes required that we use this new property. And we’re glad we did; learning how to use it opened up new possibilities in our coding repertoire. Let’s look at just the border-image code again:

url(/playground/awesome-overlays/border-image.png) 5 5 5 5 stretch;

The syntax is the same for WebKit and Gecko(Mox) browsers. The actual declaration is simple. What takes some effort is understanding how to create the image file itself.

Border image takes a single image and slices it into nine pieces, which it then stretches over the object. We’ve sketched a diagram to explain how this works, and we’ve blown up the actual border image file for you to compare. Check it out:

Border image diagram sketch

The browser takes the top-left corner and uses it for the top-left border, and then it stretches the top-middle to cover the entire top of the object, and so on around the image.

Border image diagram

We created an image with transparent center, because border-image will stretch the center quadrant across the entire object (which seems counterintuitive for a “border” image, but it does make the style a bit more versatile). You’ll notice that the actual gradient is present only in quadrants 4 and 6, because those are the only pieces that will be stretched enough for us to see a gradient. The browser actually does a good job of stretching the image as long as it’s not too complex, so artifacts aren’t really an issue.

The last pieces of the border-image declaration are the size and style: 5 5 5 5 stretch. The repeated 5s determine the size on each side of the object; because we wanted a 5-pixel border, we created an image that was 15 x 15. If we had used a smaller image, the browser would have had to scale the corners as well, and no doubt it would have looked messier. The last property, stretch, dictates how the browser actually handles the pieces of the image. A great (and amusing) intro to the different styles can be found at lrbabe16.

Putting It Together

Combining the frame with the glass overlay center (which is a semi-transparent PNG) gives us our frame. Using different border images, we actually created classes for our different colors (red, blue, etc.), while older browsers still get a usable frame without the gradient-edged niceties. This isn’t an incredibly complex example, but you can see how useful border-image can be, especially using an alpha-mapped image format such as PNG.

Overlay17

See the Live Demo »18

We’ve created a live demo page for this gallery in our Playground so that you can see it in action and delve deeper into the source code. You can also read up on why we created this overlay in our two-part Notable Behind the Scenes blog post: part 119 and part 220.


CSS 3 Is Totally Bad Ass

Right? We hope you’ve enjoyed this primer on what we can look forward to in the final CSS3 specification. Familiarize yourself with the properties and start using them—just be sure to account for browsers that, sadly, will never support all of these fun new tricks. You can see how we use CSS3 in our work for clients as well as in our own product, Notable2115. Found a super-awesome way to use these new properties? We’d love to hear about it in the comments!

References and Resources

(al)

Footnotes

  1. 1 http://www.smashingmagazine.com/2009/12/02/pushing-your-buttons-with-practical-css3/
  2. 2 http://www.smashingmagazine.com/2009/12/16/stronger-better-faster-design-with-css3/
  3. 3 http://www.zurb.com/playground/css3-polaroids
  4. 4 http://www.flickr.com/zurbinc
  5. 5 http://www.zurb.com/playground/css3-polaroids
  6. 6 http://developer.apple.com/safari/library/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Transforms/Transforms.html#//apple_ref/doc/uid/TP40008032-CH5-SW1
  7. 7 http://www.zurb.com/playground/css3-polaroids
  8. 8 http://www.zurb.com/playground/css3-polaroids
  9. 9 http://www.zurb.com/playground/sliding-vinyl
  10. 10 http://www.zurb.com/playground/sliding-vinyl
  11. 11 http://www.zurb.com/playground/sliding-vinyl
  12. 12 http://www.zurb.com/playground/sliding-vinyl
  13. 13 http://www.zurb.com/playground/sliding-vinyl
  14. 14 http://www.zurb.com/playground/awesome-overlays
  15. 15 http://www.notableapp.com
  16. 16 http://www.lrbabe.com/sdoms/borderImage/index.html#nogo
  17. 17 http://www.zurb.com/playground/awesome-overlays
  18. 18 http://www.zurb.com/playground/awesome-overlays
  19. 19 http://www.zurb.com/blog/302
  20. 20 http://www.zurb.com/article/304/behind-the-scenes-building-the-new-visual
  21. 21 http://www.notableapp.com
  22. 22 http://www.smashingmagazine.com/2009/12/02/pushing-your-buttons-with-practical-css3/
  23. 23 http://www.smashingmagazine.com/2009/12/16/stronger-better-faster-design-with-css3/
  24. 24 http://webkit.org/blog/138/css-animation/
  25. 25 http://www.css3.info/webkit-introduce-more-new-features/
  26. 26 http://developer.apple.com/safari/library/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Introduction/Introduction.html

↑ Back to top Tweet itShare on Facebook

ZURB is a close-knit team of interaction designers and strategists that help companies design better products & services through consulting, products, education, books, training and events. Since 1998 ZURB has helped over 75+ clients including: Facebook, eBay, NYSE, Yahoo, Zazzle, Playlist, Britney Spears, among others.

Advertisement
  1. 1

    neat examples, but I think they take “drawing” the record takes CSS too far. It would be much easier to the do the same with an SVG created in inkscape.

    The css transforms and translate look a lot like SMIL
    http://en.wikipedia.org/wiki/Synchronized_Multimedia_Integration_Language

    Perhaps CSS3 is picking up where SMIL support is lacking?

    0
  2. 102

    @Sandstream:
    Yeah well, at the same time, people at work are not supposed to browse the web, are they? :-/
    I guess your metaphor would be better with “To don’t care about IE6 is like telling an UPS employe that he/she can’t visit your drive-in cinema because their car is brown…”. Unless you’re in charge of the official drive-in cinema of UPS, I think it’s perfectly fine to forbid such cars to come in because they are too big.

    In other words: unless you’re publishing content/offering service dedicated to in-company use, I think it’s fine to say that you don’t have to care about IE6.

    Of course, I won’t say I don’t care *at all* and always check before putting newer versions online, but I don’t mind *at all* how the site looks like as long as the information is understandable.

    0
  3. 203

    Can you play the music in-screen on the the album covers?

    0
  4. 304

    Wow, some nifty tricks, border image is inspired!!

    0
  5. 405

    Håvar I. Henriksen

    February 1, 2010 3:54 pm

    Firefox 3.6 does support CSS3 gradients, but the syntax is somewhat different from Safari’s syntax since it uses W3C’s proposal for CSS3 gradients, while Safari uses WebKit’s proposal atm. But I guess Safari/WebKit would catch up with W3C’s proposal soon…
    https://developer.mozilla.org/en/Using_gradients

    0
  6. 506

    Håvar I. Henriksen

    February 1, 2010 3:59 pm

    What’s the point in supporting IE8? This article is all about the future, to show what HTML5 would bring of exiting new features. This article is for web-developers, which don’t use outdated browsers like Internet Explorer. (Yeah I guess someone would say that since IE8 doesn’t support this, than it shouldn’t be used, but that’s just bullshit, IE users would just have to get used to getting a degraded version of the web).
    I guess IE would catch up sometime, maybe IE10 or IE11 wil support HTML5, while IE9 will have limited support. Maybe IE9 finally would get a much higher score on the Acid3 test, and maybe pass it? Who knows…

    0
  7. 607

    Here a nifty little landing page I just finished using the new hotness of css3 and a bit of html 5. Loving the new capabilities with this stuff. http://preview.tinyurl.com/yalej8w

    0
  8. 708

    This the album one doesn’t work in the latest firefox for me… Anybody else?

    0
  9. 809

    Vinyl doesn’t work for me either in latest FF. Polaroid looks like a great technique tho and I’m looking for an opportunity to use it in drupal flickr galleries.

    0
  10. 910

    this!

    Many of the comments here are like “you use IE so gtfo”. I think this attitude is completely wrong. IE is the most-used browser so deal with it. That doesn’t mean I like it – but it’s my daily business so I’ve to adapt.
    The internet is not for “this browser or that browser” (remember the “optimized for IE and 1024×768″ messages??) – the internet is for everyone – without exclusion. At least that is what we (as web developers) have been working on – to tear down boundaries, to open up. Or haven’t we??

    Of course CSS3 will be a great improvement and I am really looking forward to it – when it’s finished. Until then…

    PS: CSS gradients do only work in FF since version 3.6
    http://www.mozilla.com/en-US/firefox/underthehood/

    0
  11. 1011

    Check out:
    http://www.forabeautifulweb.com

    They use this effect but use an image so that there is some movement for FF and other browsers that can’t implement the full effect.

    0
  12. 1112

    Awesome ..

    0
  13. 1213

    One of the awesomeness of css3 is @font-face font embedding on web page. By this css3 rule, we can embed any fonts into our web page. Which can be natively render from browser.

    I have write nice tutorial based on implementation of @font-face css3 technique on my special font techniques related blog – Font Villa.

    http://fontvilla.wordpress.com/2011/01/24/use-any-font-in-wordpress-or-any-website/

    Hope this would be helpful to modern web designers.

    1
  14. 1314

    Cool and inspiring!

    0
  15. 1415

    Michael Ecklund

    May 31, 2011 11:12 am

    Came across this website via Google search query “css 3 image effects”.

    Just wanted to say, the “Polaroid” blurb was EXACTLY what I was looking for on a project. I plan on using the “Record” blurb on a future project as well. I am very excited to begin using more CSS 3 on all future projects.

    Thank you very much for this post.

    -Mike Ecklund
    http://www.MichaelBrentEcklund.com

    P.S. I bookmarked this website! Keep up the awesome posts!

    0
  16. 1516

    Beautiful sexy singles, Meet hot girls best international horny matches.

    0
  17. 1617

    Unknown message

    0
  18. 1718

    срочно ищу активного реферала для участия в проекте. старт в марте. Заработок гарантирован.
    icq 228703685

    0
  19. 1819

    You can’t separate pease from freedom because no one can be at peace unless he has his freedom.

    0

↑ Back to top