newsletter iconSign up for our monthly CodeGeek newsletter to receive news about our blog, new projects, web development, and upcoming events.
You can also add us to your RSS feed!

  • Name * Required
  • Data Transfer * Required
    By checking this box, I understand that I consent to send my name, email and company (optional) to CodeGeek for the purposes of adding me to their email newsletter. CodeGeek uses MailChimp as their email service provider and I consent to having my information transmitted to MailChimp for these purposes.
  • This field is for validation purposes and should be left unchanged.

Overlapping 2D and 3D Elements in Mobile Safari

Overlapping 2D and 3D elements in a mobile image

This may seem like an arcane subject, but if you are using 3D transforms in CSS, understanding it could save you some headaches. In our case, we were working on a client site with the following heading:

Retired Libations (Correct)

The heading was marked up as an h3, and “RETIRED” was wrapped in a span with a flip class to flip the word upside down using a 3D transform:

.flip {
    display: inline-block;
    position: relative;
    top: -8px;
    -webkit-transform: rotateX(180deg);
    -moz-transform: rotateX(180deg);
    -ms-transform: rotateX(180deg);
    -o-transform: rotateX(180deg);
    transform: rotateX(180deg);

This approach worked perfectly in most browsers, but in Safari on the iPhone, the word “RETIRED” disappeared. No amount of coaxing with z-index properties would bring it back. What was going on here? (We weren’t indulging in any libations, we swear!)

Libations (Retired is missing)

It turns out that Safari on iOS handles 3D-transformed elements a bit differently than regular elements. All 3D-transformed elements are grouped and rendered together. The 3D rendering space is entirely separate from the plane used for regular 2D page elements.

2D and 3D rendering layers

The word “RETIRED” jumped behind the h3 element when Safari applied the 180-degree rotation we specified. The width of the h3 remained the same, so it covered over the 3D space where “RETIRED” ended up. Because the 3D rendering space was placed behind the 2D rendering plane, z-index was of no help. The 3D-transformed element would always fall behind the 2D element.

Fortunately, we found a solution. By applying a 3D transform to the entire h3 element, we placed both the h3 and the span in the 3D rendering group. The transform didn’t actually have to move or change the h3 element; transform: translate3d(0px, 0px, 0px); was sufficient. Because the 2D plane was now empty, everything in the 3D space was visible, and both words appeared.

Everything is in the 3d rendering space

Now the word “RETIRED” appeared as expected on the iPhone and iPad. All other browsers were unaffected. Success!