backface-visibility
backface-visibility controls whether the back face of an element is visible when rotated or transformed in 3D space. Set to hidden, it makes the element disappear when turned away from the viewer—perfect for flipping cards where you don't want to see the mirrored back. Set to visible (default), the back face appears as a mirror image.
Understanding backfaces
CSS
/* By default, backface is visible */
.element {
backface-visibility: visible;
/* When rotated 180deg, you see the mirrored back */
}
/* Hide the back face */
.element-hidden {
backface-visibility: hidden;
/* When rotated 180deg, element disappears */
}
/* Backface only appears with 3D rotation */
.three-d-only {
transform: rotateY(180deg);
/* Front at 0deg, back at 180deg */
}
/* Two-sided element (both visible) */
.two-sided {
backface-visibility: visible;
transform: rotateY(180deg);
/* Shows mirrored text/content */
}
/* Single-sided element (flip effect) */
.card-front {
backface-visibility: hidden;
/* Hides when rotated away */
}
.card-back {
backface-visibility: hidden;
transform: rotateY(180deg);
/* Hides when not at 180deg */
}How backface-visibility works
Value | Behavior | Use Case |
|---|---|---|
visible (default) | Back face shows as mirror | Two-sided elements, debugging |
hidden | Back face invisible | Flip cards, one-sided 3D |
inherit | Inherits from parent | Cascading effect |
CSS
/* Flipping card - the classic use case */
.flip-container {
perspective: 1000px;
width: 300px;
height: 200px;
}
.flip-card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s;
}
.flip-container:hover .flip-card {
transform: rotateY(180deg);
}
.flip-front {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
/* Hides when rotated 180deg */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
}
.flip-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
/* Stays hidden until rotated 180deg */
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
transform: rotateY(180deg);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 18px;
}
/* Without backface-visibility: hidden */
.broken-flip {
/* You'd see both sides overlapping and mirrored */
/* Very confusing visual effect */
}Practical flipping patterns
CSS
/* Image flip reveal */
.image-flip {
perspective: 1000px;
width: 200px;
height: 200px;
cursor: pointer;
}
.image-flip-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
.image-flip:hover .image-flip-inner {
transform: rotateY(180deg);
}
.image-flip-front {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.image-flip-front img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 8px;
}
.image-flip-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
transform: rotateY(180deg);
background: #34495e;
color: white;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
border-radius: 8px;
}
/* Card deck flip */
.card {
perspective: 1000px;
width: 150px;
height: 200px;
}
.card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.3s;
transform-style: preserve-3d;
}
.card:hover .card-inner {
transform: rotateY(180deg);
}
.card-front {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
background: white;
border: 2px solid #3498db;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 64px;
}
.card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
background: #3498db;
border-radius: 8px;
transform: rotateY(180deg);
display: flex;
align-items: center;
justify-content: center;
color: white;
}
/* Y-axis flip (horizontal axis) */
.flip-y {
transform: rotateY(180deg);
backface-visibility: hidden;
}
/* X-axis flip (vertical axis) */
.flip-x {
transform: rotateX(180deg);
backface-visibility: hidden;
}
/* Z-axis rotation (in-place spin) */
.flip-z {
transform: rotateZ(180deg);
/* backface doesn't matter for Z rotation */
}Advanced backface patterns
CSS
/* 3D button with hidden back */
.button-3d {
perspective: 1000px;
padding: 12px 24px;
background: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: transform 0.3s;
transform-style: preserve-3d;
}
.button-3d:hover {
transform: rotateX(10deg) rotateY(5deg);
backface-visibility: hidden;
}
/* Cube faces with backface-visibility */
.cube {
perspective: 1000px;
width: 200px;
height: 200px;
position: relative;
transform-style: preserve-3d;
animation: rotate-cube 10s infinite linear;
}
.cube-face {
position: absolute;
width: 200px;
height: 200px;
backface-visibility: hidden;
/* Hides inner faces when rotated */
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
border: 2px solid #3498db;
}
.face-1 { transform: translateZ(100px); background: rgba(52, 152, 219, 0.9); }
.face-2 { transform: rotateY(180deg) translateZ(100px); background: rgba(46, 204, 113, 0.9); }
.face-3 { transform: rotateY(90deg) translateZ(100px); background: rgba(155, 89, 182, 0.9); }
.face-4 { transform: rotateY(-90deg) translateZ(100px); background: rgba(230, 126, 34, 0.9); }
.face-5 { transform: rotateX(90deg) translateZ(100px); background: rgba(231, 76, 60, 0.9); }
.face-6 { transform: rotateX(-90deg) translateZ(100px); background: rgba(52, 73, 94, 0.9); }
@keyframes rotate-cube {
from { transform: rotateX(0deg) rotateY(0deg); }
to { transform: rotateX(360deg) rotateY(360deg); }
}
/* Gallery with hidden back images */
.gallery-item {
perspective: 1000px;
width: 200px;
height: 200px;
}
.gallery-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.gallery-item:hover .gallery-inner {
transform: rotateY(180deg);
}
.gallery-image {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.gallery-info {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
transform: rotateY(180deg);
background: #2c3e50;
color: white;
padding: 20px;
box-sizing: border-box;
}Performance and browser considerations
CSS
/* backface-visibility is performant */
.performant {
backface-visibility: hidden;
/* Uses GPU acceleration, no performance penalty */
}
/* Use with will-change for animated 3D */
.optimized-flip {
will-change: transform;
transition: transform 0.6s;
backface-visibility: hidden;
}
/* Browser support is excellent */
.supported {
backface-visibility: hidden;
/* Works in all modern browsers */
}
/* Use vendor prefixes for older browsers */
.prefixed {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
}
/* Test support */
@supports (backface-visibility: hidden) {
.has-support {
backface-visibility: hidden;
transform: rotateY(180deg);
}
}
@supports not (backface-visibility: hidden) {
.fallback {
opacity: 0;
/* Fallback: hide with opacity instead */
}
}Note
`backface-visibility: hidden` hides the back face of an element when rotated in 3D, essential for flip card effects. Default is `visible`, showing a mirrored image of the back. When combined with `transform-style: preserve-3d` and 3D rotations (`rotateX()`, `rotateY()`), it creates convincing flip effects. Use on both front and back sides of flipping elements to ensure proper visibility at each angle.
Next
Individual transform properties: [Individual Transform Properties](/css/individual-transforms).