Menu Search
Jump to the content X X
Smashing Conf Barcelona 2016

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

The New Hotness: Using CSS3 Visual Effects

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.

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.

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 Link

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 Link

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 Link

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 Link

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 Link

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 Link

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 Link

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 Link

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 Link

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 Link

Border image14

This last part is perhaps the most practical. We use it in our feedback tool Notable1915 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 Link

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 Link

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 Link

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 Link

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 1 and part 2.


CSS 3 Is Totally Bad Ass Link

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, Notable1915. Found a super-awesome way to use these new properties? We’d love to hear about it in the comments!

References and Resources Link

(al)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2009/12/02/pushing-your-buttons-with-practical-css3/
  2. 2 https://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.notableapp.com
  20. 20 https://www.smashingmagazine.com/2009/12/02/pushing-your-buttons-with-practical-css3/
  21. 21 https://www.smashingmagazine.com/2009/12/16/stronger-better-faster-design-with-css3/
  22. 22 http://webkit.org/blog/138/css-animation/
  23. 23 http://www.css3.info/webkit-introduce-more-new-features/
  24. 24 http://developer.apple.com/safari/library/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Introduction/Introduction.html
SmashingConf Barcelona 2016

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

Advertisement

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.

  1. 1

    Nice stuff :)

    -1
  2. 2

    Marcin Szewczyk

    January 25, 2010 5:51 am

    Nice and Great! But on my core duo processor, effects in css3 are very slow…

    0
  3. 3

    I LOVE THIS !!!! CSS3 is awesomeness

    0
  4. 4

    Very nice tipps and infos about the things we are still waiting for since years. HTML5 in cooperation with CSS3 will definitely become The Future of Webdesign!

    -1
  5. 5

    superrrr!

    0
  6. 6

    Awesome!!!! Cheers for CSS3 and HTML5! Going to redesign my blog using CSS3, HTML5 and jQuery 1.4 :)

    0
  7. 7

    I just love this. More of this kind of tuts!

    Too bad CSS3 isn’t supported that well across all browsers and still a lot of ppl using stone age technology like IE.

    0
  8. 8

    Is there a javascript way to make it work on IE6/7 and other browsers that does not support native CSS3?

    0
  9. 9

    Nice, but browsers still strikes against xhtml 5 and css3.
    Sliding Vinyl Albums works only in Safari in my case.

    0
  10. 10

    Christopher Jack

    January 25, 2010 6:37 am

    this article is just awesome! Learn a lot! thanks :D

    1
  11. 11

    Great article, loved the vinil!
    Now we just have to wait for css3 to be compatible with all browser… ¬¬

    0
  12. 12

    Nice article. I look forward to incorporating some of these into some of my own Web sites.

    0
  13. 13

    Some great tricks there to learn, CSS3 and HTML5 is the way ahead, i just wish Microsoft would get on with catching up and just die completely.

    0
  14. 14

    Edward Palomo

    January 25, 2010 6:54 am

    yeah! css3 is totally bad ass! enjoyed this article!

    0
  15. 15

    That all-css vinyl is a stroke of genius. Too bad it only works in Chrome/Safari (I wish Mozilla would hurry up with css3 support already).

    I’ve been working on an iphone-only site and it is so liberating to know that I can use CSS3 without having to worry about how things would look in other browsers, one of my most satisfying projects to date :)

    0
  16. 16

    Don’t work in IE8 so what’s the point…

    0
  17. 17

    Yes, it’s good, but please, don’t use only -moz- and -webkit- CSS 3 properites, also include real CSS 3 properties, such as “border-radius:5px”.

    Why? Because new Opera 10.50 also supports many of them (border-radius, border-image, multiple backgrounds, etc.) and maybe somewhere in the future there will be a browser, which will support them (maybe IE9?), so be nice ;-).

    If you will use only -moz- and -webkit- properties, many coders/designers will learn to use them and they will never use real (and valid!) properties of CSS 3.

    (sorry for my bad english, hope you understand me…)

    0
  18. 18

    CSS3 IS TOTALLY BAD ASS! AMAZING!!

    can’t wait til it’s browser compatible (yawn)

    0
  19. 19

    I love CSS3!

    …and your postings too, ZURB!

    0
  20. 20

    Jonathan Smiley

    January 25, 2010 7:20 am

    Good point Smasty – there are still a few properties though where the final spec is up in the air, for example box-shadow will likely be deprecated in favor of drop-shadow. Good tip though and we’ll definitely bear that in mind going forward. Thanks!

    0

↑ Back to top