Previously I’ve talked about common errors made in developing CSS 3D content. Today’s article will discuss another one, plus a bonus technique.

Smoothing The Edges of Transformed Elements

Rotating elements (especially images) in three dimensions using CSS can result in jagged edges that lack antialiasing, depending on the browser build and GPU. Right now, Firefox is particularly affected by this.

The CSS, shown without vendor prefixes to save space:

.church {
	perspective: 700px;
	padding: 2rem;
}
.church img {
	transform: rotateY(12deg);
}
Rotated element without smoothing applied, as viewed in Firefox

While I expect this visual treatment to improve in the near future, right now there is a simple fix: adding a 1 pixel thick transparent outline:

.church img {
	transform: rotateY(12deg);
	outline: 1px solid transparent;
}

The live result looks like this:

Rotated element with smoothing applied

Collapsed Containers Affect 3D Perspective

It’s a behaviour that’s confused me more than once: perspective doesn’t appear to be applied to images correctly, despite the fact that I’ve triple-checked the code. The issue is due to what I’ve called the “float flag” quirk: floated elements do not contribute to the height of their containers. (The same issue occurs with elements given position: fixed or absolute). As a result, the perspective vanishing point shifts.

For example, a simple image inside a <div>, with CSS 3D applied, but with the image floated. I’ve added a border to the <div> to show its area and shape:

A photograph the Taj Mahal at sunset
A floated 3D element
<div class="taj">
	<img src="taj-mahal-full.jpg" alt="A photograph the Taj Mahal at sunset"  style="width:300px">
</div>

The CSS:

.taj {
	perspective: 700px;
	border: 1px solid red;
}
.taj img {
	transform: rotateY(12deg);
	float: left;
	outline: 1px solid transparent;
}

With a floated element, the 3D vanishing point is “buried” in the collapsed div, changing the orientation of the image. Depending on circumstances, this shift can be subtle or bizarre. The solution, however, is always the same: ensure that the container reflects the actual size of the 3D elements inside it. There are a number of ways you could do this: adding a clearfix solution, overflow: hidden, extra padding, or some combination of the three.