How to Apply CSS3 Transformations to Background Images

Contributing Editor

Scaling, skewing and rotating any element is possible with the CSS3 transform property. It’s supported in all modern browsers (with vendor prefixes) and degrades gracefully, e.g.


#myelement
{
	-webkit-transform: rotate(30deg);
	-moz-transform: rotate(30deg);
	-ms-transform: rotate(30deg);
	-o-transform: rotate(30deg);
	transform: rotate(30deg);
}

Great stuff. However, this rotates the whole element — it’s content, border and background image. What if you only want to rotate the background image? Or what if you want the background to remain fixed while the element is rotated?

Currently, there’s no W3C proposal for background-image transformations. It would be incredibly useful so I suspect one will appear eventually, but that doesn’t help developers who want to use similar effects today.

Fortunately, there is a solution. In essence, it’s a hack which applies the background image to a before or after pseudo element rather than the parent container. The pseudo element can then be transformed independently.

View the demonstration page…

Transforming the Background Only

The container element can have any styles applied but it must be set to position: relative since our pseudo element will be positioned within it. You should also set overflow: hidden unless you’re happy for the background to spill out beyond the container.


#myelement
{
	position: relative;
	overflow: hidden;
}

We can now create an absolutely-positioned pseudo element with a transformed background. The z-index is set -1 to ensure it appears below the container’s content.


#myelement:before
{
	content: "";
	position: absolute;
	width: 200%;
	height: 200%;
	top: -50%;
	left: -50%;
	z-index: -1;
	background: url(background.png) 0 0 repeat;
	-webkit-transform: rotate(30deg);
	-moz-transform: rotate(30deg);
	-ms-transform: rotate(30deg);
	-o-transform: rotate(30deg);
	transform: rotate(30deg);
}

Note you may need to adjust the pseudo element’s width, height and position. For example, if you’re using a repeated image, a rotated area must be larger than its container to fully cover the background:

background transform

Fixing the Background on a Transformed Element

All transforms on the parent container are applied to pseudo elements. Therefore, we need to undo that transformation, e.g. if the container is rotated by 30 degrees, the background must be rotated -30 degrees to return to a fixed position:


#myelement
{
	position: relative;
	overflow: hidden;
	-webkit-transform: rotate(30deg);
	-moz-transform: rotate(30deg);
	-ms-transform: rotate(30deg);
	-o-transform: rotate(30deg);
	transform: rotate(30deg);
}

#myelement:before
{
	content: "";
	position: absolute;
	width: 200%;
	height: 200%;
	top: -50%;
	left: -50%;
	z-index: -1;
	background: url(background.png) 0 0 repeat;
	-webkit-transform: rotate(-30deg);
	-moz-transform: rotate(-30deg);
	-ms-transform: rotate(-30deg);
	-o-transform: rotate(-30deg);
	transform: rotate(-30deg);
}

Again, you will need to adjust the size and position to ensure the background covers the parent container adequately.

Please view the demonstration page for examples. The full code is contained in the HTML source.

The effects work in IE9, Firefox, Chrome, Safari and Opera. IE8 will not show any transformations but the background appears.

IE6 and 7 do not support pseudo elements so the background disappears. However, if you want to support those browsers, you could apply a background image to the container then set it to “none” using an advanced selector or conditional CSS.

If you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Learn CSS3.

Comments on this article are closed. Have a question about CSS3? Why not ask it on our forums?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.mltgroup.com Minnesota Web Development

    Great tip! I can see a lot of uses for this. Do you know if that same transformation idea works for any element, such as a form?

    • http://www.optimalworks.net/ Craig Buckler

      There’s no reason why it wouldn’t work on a form element. Best to try it, though.

  • http://levelonewebdesign.com Thomas Jay

    Nice way to handle a neat effect with graceful degradation. It would probably be cool to use as a hover effect using CSS3 transitions too.

  • http://www.codarz360.com Codarz360

    This feature looks pretty awesome and it will save having to create images. I’ve been having a look at some of the other things it can do but this is by far one of the coolest. Thanks for the post and keep them coming man :)

  • http://www.w3spor.no/ W3Spor

    Thanks, very useful :-)

  • http://magixilluminate.com Thomas Hansen

    Smart trick, I don’t think transformations on pseudo elements will work in all browsers though …
    Still, wrote it down behind my ear … ;)

    • http://www.optimalworks.net/ Craig Buckler

      For it to work, the browser must support pseudo elements (most of ‘em) and transformations (most of the modern browsers). Sadly, Lynx is out.

  • Phil Doughty

    Cool effect. pseudo elements rock!
    Visually this is a kinda new technique even though pseudo elements are css2.
    There is still a lot that can be done with them. I don’t think we need to be afraid of using this kinda technique and should be making more use of pseudo’s :before & :after together with content: “”;

  • http://techgyo.com Sreejesh @techgyo

    Thanks its a useful tut, it can be used in many creative ways. But sadly It won’t work with Buggy IE i guess?

    • http://www.optimalworks.net/ Craig Buckler

      It’s fine in IE9. IE8/7/6 degrade gracefully too.

  • http://alexmwalker.mp/ Alex Walker

    Nice one, Craig.

    I actually spend some time trying to animate pseudo elements separately to their parent. Had some success with moz, but haven’t been able to wrestle webkit into it so far.

    • http://www.optimalworks.net/ Craig Buckler

      Thanks Alex. I noticed the same – Firefox animates a pseudo element as expected but Chrome appears to instantly switch to its final state. Let’s hope the webkit team are on it.

  • http://www.kingwebsites.co.uk/ John King

    I have used this technique but I couldn’t get iFramed content, such as embedded YouTube videos, to show on some browsers. I think it was FF that was playing up. Have you had any experience of this?