Apply CSS3 Transforms to Background Images

CSS transformations are really cool, but they don’t yet apply to background images. This article presents a neat workaround for those times when you really do want to rotate a background image, or to keep a background image fixed while its container element is rotate.

Scaling, skewing and rotating any element is possible with the CSS3 transform. It’s supported in all modern browsers without vendor prefixes. (I’ve added in the -webkit- just in case you want to support some older browsers.)

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

Great stuff. However, this rotates the whole element — its 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?
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.

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 to -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);
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:
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);
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);
transform: rotate(-30deg);
}

Again, you’ll need to adjust the size and position to ensure the background adequately covers the parent container.
The effects work in all major browsers and in Edge and Internet Explorer back to version 9. IE8 will not show any transformations but the background still appears.