Most flip card tutorials stop once the card turns on hover. That part is easy, and it’s also where the trouble starts, because a hover-only flip leaves touch screens and keyboards with no way to reach the back face.

The turn itself comes down to perspective on the container, transform-style: preserve-3d on the inner wrapper, backface-visibility: hidden on both faces, and a rotateY(180deg) transform that a trigger fires.

Getting the card accessible takes more effort than getting it to rotate. Vispero’s September 2025 write-up on accessible versions of the pattern reports that no ARIA state attribute fits a card that turns. Screen reader users who tried demos built on aria-pressed and aria-expanded found them confusing.

What Is a CSS Flip Card?

The front usually carries an image or a headline, and the back carries the detail, like a bio, a price, a definition or a spec. Point at the card (or tap it, or press a key, depending on how it’s wired) and it turns over in 3D to show the other side. CSS transforms and a transition do all of it, with no animation library involved.

Structurally there’s a container that sets the card size and holds the perspective. Inside it sits a wrapper, and the wrapper is the element that actually rotates. The front face is what you see at rest. The back face is pre-rotated 180 degrees, so it stays hidden until the flip.

W3Schools names these .flip-card, .flip-card-inner, .flip-card-front and .flip-card-back, and a Leyaa guide uses the same scheme. Other tutorials pick their own class names.

The whole structure is plain HTML. Four elements, no script, no required images.

This isn’t a fade or a slide between two panels, either. MDN notes that backface-visibility has no effect on 2D transforms, which means a flat rotate with no perspective can’t give you the two-sided look.

How to Build a CSS Flip Card Step by Step

Work through these in order. Skipping one tends to fail without any error, which makes it annoying to debug.

  1. Give .flip-card a width, a height and perspective: 1000px.
  2. Give .flip-card-inner position: relative, transition: transform 0.6s and transform-style: preserve-3d.
  3. Set both faces to position: absolute, full width and height, with backface-visibility: hidden.
  4. Add transform: rotateY(180deg) to .flip-card-back.
  5. Rotate the wrapper to rotateY(180deg) inside a trigger rule such as .flip-card:hover .flip-card-inner.

Markup first.

<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">Front</div>
<div class="flip-card-back">Back</div>
</div>
</div>

And the styles.

Where is web design headed next?

Discover the latest web design statistics: industry growth, design trends, technology adoption, and insights defining the future of the web.

Explore the Data →
.flip-card {
width: 300px;
height: 200px;
perspective: 1000px;
}

.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}

.flip-card:hover .flip-card-inner {
transform: rotateY(180deg);
}

.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden; /* Safari */
backface-visibility: hidden;
}

.flip-card-back {
transform: rotateY(180deg);
}

The perspective property goes on the container, not on the wrapper that rotates. The fullPage card flip guide points out that setting it on the inner wrapper has no effect on that wrapper’s own rotation.

Skip step 2 and both faces collapse into one plane. The fullPage guide and a Leyaa guide both flag this failure. The container also needs a defined width and height, since Metro UI’s flip card docs list that as a requirement.

That -webkit- line is a Safari leftover. W3Schools still ships it in its flip card example as of October 2026.

Which Perspective, Duration and Axis Values Work Best?

See the Pen
CSS 3D Flip Cards
by Welling Guzman (@wellingguzman)
on CodePen.

Start with a perspective around 3 to 4 times the card width, a transition between 0.3s and 0.8s, and rotateY for a side-to-side turn. The tutorials that state exact values all land inside those ranges.

Here’s what the published ones actually use, as read in October 2026.

  • W3Schools sets perspective at 1000px with a 0.8s transition on a card that’s 300 by 200 pixels.
  • The DEV Community tutorial goes with perspective 600px and a 0.4s transition (0.3s on the hover rule), on a card 150 by 150 pixels.
  • The fullPage card flip guide calls about 800px a sweet spot and suggests 300 to 500px for a dramatic rotation.
  • Metro UI’s flip card defaults to an animation speed of 0.3s.

Divide each perspective by its card width and a pattern shows up: 3.3 for W3Schools, 4 for the DEV Community tutorial. Two data points make a starting range, not a law.

MDN covers which way the effect runs. A large perspective value gives a small transformation, and a small value gives a big one.

Horizontal or vertical flip

For a horizontal flip, put rotateY(180deg) on the wrapper and pre-rotate the back face by the same rotateY(180deg). A vertical flip swaps both rotations to rotateX(180deg), and Daily Dev Tips publishes a vertical variant next to its horizontal one. Use a negative angle such as rotateY(-180deg) and the card turns the other way, which the fullPage guide does.

Keep the back face pre-rotation on the same axis as the trigger rotation. Mix them and the back text reads mirrored.

Easing and duration

Duration sets how long the turn takes, and the timing function sets how the speed changes along the way. A CSS transition generator lets you preview both before you commit values to the stylesheet.

MDN’s keyword options for transition-timing-function include ease, ease-in, ease-out, ease-in-out and linear.

Treehouse describes ease-in-out as starting and stopping gradually, which suits a card that settles into place. Stay at or under 0.8s, since that’s the longest value among the sources above and anything slower drags.

Hover, Focus, Click or Checkbox: Which Trigger Fits?

See the Pen
Card flip 2
by Aakash Thakur (@Sky-123)
on CodePen.

Pick the trigger by the weakest input device your visitors use. A class toggle on a real button covers mouse, touch and keyboard, while a hover-only flip fails on touch screens.

TriggerTouch screensKeyboardNeeds JavaScript
:hoverUnreliableNoNo
:focus-withinBrowser dependentYes, with tabindexNo
Checkbox hackYes, tap the labelYes, if the input stays focusableNo
Class toggleYesYes, on a buttonYes

Hover is the simplest of the CSS hover effects to wire up, a single rule on the container.

The Calgary design system warns against relying on hover alone, and the fullPage guide notes that the :hover selector does not work on touch devices. A June 2021 CSS-IRL article adds a wrinkle. Some Android versions emulate hover on a long press, so (hover: hover) alone can evaluate true on a phone. Pair it with (pointer: fine).

Focus is the next option. The :focus-within pseudo-class matches an element when it or any descendant has focus, and MDN lists it as available across browsers since January 2020. A div isn’t focusable by default, so the card needs tabindex="0" (Quackit’s 3D card flip example does this).

W3C’s Understanding document for WCAG 2.2 criterion 1.4.13 states that content triggered by pointer hover should also be triggerable by keyboard focus.

The checkbox hack flips the card on tap with no script at all. Wrap the card in a label tied to a hidden checkbox, then use a :checked sibling selector to rotate it. FreeFrontend lists several pure CSS cards and decks built this way.

Hide the input visually, not with display: none, or it drops out of the tab order.

With a class toggle, a few lines of JavaScript add a .flipped class on click, and the CSS rule mirrors the hover rule. The fullPage guide recommends this route when click-to-flip does not work with CSS alone.

So hover only makes sense when the back face holds nothing a visitor needs. For anything that matters, use a class toggle on a button. If scripts are off the table, focus-within or the checkbox hack will do.

How to Make a CSS Flip Card Accessible

No single attribute makes a flip card accessible. A keyboard has to be able to trigger it, a screen reader has to know which face is showing, the inactive face shouldn’t be read aloud, and visitors who ask for less motion shouldn’t get the rotation.

Keyboard and focus

The City of Calgary design system tells teams to give each interactive card role="button" or role="group", add tabindex="0", and make Enter and Space flip it.

James Edwards, writing for Vispero in September 2025, takes a different line. He says never to put role="button" on the card or its face containers, because it flattens every heading and link inside into plain text for assistive technology. A real button inside the card is the better route. A focusable div with a button role looks simpler, but it hides the content the card exists to show.

Sources also split on state. A Colorlib template released in September 2026 exposes the flip through a toggle button with aria-pressed, while Vispero found that ARIA state attributes such as aria-pressed and aria-expanded do not describe a card that is never pressed or expanded. Regular screen reader users who tested demos built on them found them confusing.

Vispero’s fix is a button whose label alternates between “Flip to back” and “Flip to front”, plus a description of the face now showing. iOS VoiceOver does not support dynamic description updates, so a static aria-describedby stays as the fallback.

Screen readers and the hidden face

Give the inactive face display: none, which removes it from the accessibility tree. Vispero does this and so does the Colorlib template. backface-visibility: hidden only controls painting, so it can’t do that job alone.

Vispero also swaps the visible face at the 90 degree point of the rotation, when neither face can be seen.

That last trick means only one face exists at a time, so the faces need no absolute positioning, no fixed height and no matching size. The price is a JavaScript class that watches the rotation with requestAnimationFrame() and getComputedStyle().

Reduced motion

MDN names scaling and panning of large objects as vestibular motion triggers, and a rotating card is a large object in motion.

A media query on prefers-reduced-motion lets those visitors skip the rotation while everyone else keeps it.

@media (prefers-reduced-motion: reduce) {
.flip-card-inner {
transition: none;
}
}

That snippet is the snap approach. The flip still happens, instantly, and Quackit’s 3D card flip example works this way. Crossfading swaps the faces into each other instead of rotating, which is what the Colorlib template does. Gating puts the rotation rules only inside (prefers-reduced-motion: no-preference), so a plain face swap is the default, and Vispero builds it this way.

Gating is the safest of the three, because a browser that cannot evaluate the query never plays the rotation.

How to Lay Out Flip Cards in a Responsive Grid

See the Pen
Flip Card
by Andy McFee (@andymcfee)
on CodePen.

A CSS grid with repeat(auto-fit, minmax(240px, 1fr)) columns does most of the work. Each card gets its height from its width through aspect-ratio, and the columns reflow on their own as the viewport narrows.

.flip-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 1.5rem;
}

.flip-card {
aspect-ratio: 3 / 2;
perspective: 1000px;
}

The faces are absolutely positioned, so the card needs a height the grid can read. The aspect ratio supplies one from the column width, and a fixed height works too.

No breakpoint decides the column count here, which makes it the lowest-effort route to responsive design for a card collection.

A CSS grid generator is handy for sketching the column rhythm before the cards go in.

Vispero’s review of flip card implementations says absolute positioning with fixed sizes stops the content from responding to larger fonts or text spacing, so one or both faces overflow the container. The City of Calgary design system caps rotating cards at 4 per row, because crowded layouts hurt focus and mobile usability.

Perspective units matter too. A pixel value suits one card width, and grid columns stretch. Vispero sets perspective: 64rem, which follows font size instead of column width.

Measure the longest back face before choosing the ratio. If it needs more room than the ratio allows, shorten the copy or change the pattern.

Do CSS Flip Cards Work in Every Browser?

See the Pen
Cross-Browser Flip Card
by Rodrigo Hernando (@rhernando)
on CodePen.

Chrome, Edge, Firefox and Safari all run a flip card without extra code. Can I use lists Internet Explorer 10 and 11 and Opera Mini as the gaps.

PropertyMDN Baseline statusJob in the card
perspectiveWidely available; across browsers since September 2015Depth on the container
transform-styleWidely available; across browsers since September 2015Keeps both faces in 3D
backface-visibilityWidely available; across browsers since March 2022Hides the reversed face

Two Can I use entries disagree on the surface. The 3D transforms entry lists IE 10 and 11 as partial support, while the entry for transform-style: preserve-3d lists both as unsupported.

A flip card depends on preserve-3d, so partial support in IE still means a broken card.

Treat the IE gap as a decision, not a bug. Cross-browser compatibility testing on the browsers you actually ship to tells you whether a fallback is worth building, such as swapping faces with plain display rules.

MDN’s compatibility notes also record that the perspective property did not function properly on iOS 13.

Since the unprefixed property has Baseline status, projects that target current browsers can drop -webkit-backface-visibility. Keep it only for older Safari.

Why Is a CSS Flip Card Not Working?

See the Pen
Magic Flip Cards 2: How Absolute Positioning Fails
by Smashing Magazine (@smashingmag)
on CodePen.

Nearly every failure traces back to a broken 3D context. Usually the wrapper is flattened by another property, a nested element is missing preserve-3d, or a stacking context traps the faces.

SymptomCauseFix
Faces flat although preserve-3d is setWrapper has overflow other than visible or clip, opacity below 1, a filter, or isolation: isolateMove those properties to the container or a face
Faces flat after adding a wrappertransform-style is not inheritedSet preserve-3d on every non-leaf element above the faces
z-index ignored between cardsperspective and preserve-3d each create a stacking contextRaise the container, not its children
Back text spills out of the cardFixed height with absolutely positioned facesScroll inside the face with overflow-y: auto, never on the wrapper
Text looks soft in SafariInside a scaled parent, a 3D-rotated sibling makes text render as a scaled bitmapNo confirmed CSS fix

The first three rows come from MDN’s documentation of transform-style and perspective. The overflow row follows from the first, since the faces are leaf elements and the wrapper is not.

The Safari row rests on a WebKit Bugzilla report (278043, August 2024, Safari Technology Preview 199 on macOS 14.6). It lists the bug as new and notes that Chrome and Firefox render the same page sharply.

When a flip card is the wrong choice

  • Information visitors need sits on the back face, and keyboard and screen reader users cannot reach it (the City of Calgary design system advises against this).
  • The back content varies in length or has to survive text zoom, where an accordion reveals the same detail in normal flow.

If most visitors need the back face, put its content on the front.

CSS Flip Cards Examples To Check Out

Swanky Business Card with Flip Vibes

See the Pen
Business Card
by Nicholas Dobie (@nrdobie)
on CodePen.

Flip it Like 3D with jQuery & CSS3

Customizable Flip Cards with HTML, CSS, & JS

See the Pen
Flip Card
by 101 Computing (@101Computing)
on CodePen.

3D Business Card Vibes Online

See the Pen
Business Card
by Lubos (@mrlubos)
on CodePen.

Makeup Palettes: Flip Edition

See the Pen
CSS Grid: Makeup Palettes
by Olivia Ng (@oliviale)
on CodePen.

Tilt, Then Flip. It’s a CSS thing

See the Pen
Tilt and flip playing cards
by Manjit Karve (@manjitkarve)
on CodePen.

Just Another Flipping Card

See the Pen
Flipping card
by Sergey Nikishkin (@nikishkin)
on CodePen.

Rotate with CSS, Fill with JS

See the Pen
CSS Flip Card (content with JS)
by Diego Bruno Rodrigues (@DiegoBR)
on CodePen.

Keeping it Pure with CSS

See the Pen
Pure CSS Flip Card
by Aron (@aron-tw)
on CodePen.

Get Your Flip-Ready Download Cards

See the Pen
Download Cards
by Evan Wieland (@EvanWieland)
on CodePen.

Flip. Flip. And Flip Again

See the Pen
Card Flip
by Charles Ojukwu (@cojdev)
on CodePen.

Business Card: The Digital Frontier

See the Pen
CSS Business Card
by Keith Pickering (@keithpickering)
on CodePen.

Holiday Cards with a CSS Fold

See the Pen
Holiday Feature Folding Cards [Pure CSS]
by Madalena (@Maza-designDev)
on CodePen.

Figcaption’s Flipping Wonder

See the Pen
Lazy Loading Fig+Figcaption & Flipping Card
by Alex Paul (@alex_paul)
on CodePen.

Bare-Bones Flip Card

See the Pen
Simple flip card CSS
by TOMAZKI (@Podgro)
on CodePen.

Say Hello to Login, Flip-Style

See the Pen
Login/Sign Up Flip Card
by Evan Clemens (@evanclemens)
on CodePen.

Swipin’ Flip Card Fun

See the Pen
CSS: Flip Card con deslizamiento
by Marco (@marco3w)
on CodePen.

Gamers, Flip Out With Player Cards!

See the Pen
Player Flip Cards
by Nick Nikolov (@necks)
on CodePen.

Twist, Turn, and Go 3D

See the Pen
3D card flip rotate
by Paulo Figueiredo (@palofigueiredo)
on CodePen.

Spacey 3D Flips

See the Pen
3D Flip Card Effect
by Samet Erpik (@samerpik)
on CodePen.

Socialize with Flipping Style

See the Pen
Social Flip Cards
by Charlotte Dann (@pouretrebelle)
on CodePen.

Magic’s First Card Trick

See the Pen
Magic Flip Cards 1: The Standard Implementation
by Smashing Magazine (@smashingmag)
on CodePen.

Profile Cards in 3D

See the Pen
3D Profile Flip Card
by Nick Hempsey (@nickhempsey)
on CodePen.

F. A. Rodrigues’s Flippin’ Marvel

See the Pen
Flip Cards
by F. A. Rodrigues (@farodrigues)
on CodePen.

Menu Flips with Style

See the Pen
Lynda.com Style Flip-card Menu
by Aaron Snowberger (@jekkilekki)
on CodePen.

Clicky Buttons on a Flip-Card? Why Not!

See the Pen
Flip-card with js buttons
by Björn Rosenberg (@Bjornros)
on CodePen.

Let’s Go Halfsies with 3D Flip

See the Pen
Half flip cards 3d
by David Foliti (@marlenesco)
on CodePen.

Fancy Schmancy 3D Hover Magic

See the Pen
Fancy 3D flip card (on hover – CSS)
by Travis Williamson (@travisw)
on CodePen.

Card That’s Got The Moves

See the Pen
Flipping Card
by Mario (@mariosmaselli)
on CodePen.

Flip-Flopping Fun

See the Pen
Flip-Flop
by Arif Safiullah (@prantor19)
on CodePen.

React-ing with a Flippable Vibe

See the Pen
React Flipping Card with Tutorial
by Alex Devero (@alexdevero)
on CodePen.

Wanna Play? With Flippable Cards?

See the Pen
Flippable Playing Cards
by smpnjn (@smpnjn)
on CodePen.

Flipping Out with 3D CSS

See the Pen
CSS 3D Flipping Card Hover Effect
by FrankieDoodie (@FrankieDoodie)
on CodePen.

Delight in Every Flip

See the Pen
Flipping Card – Delightful Version
by Amazing Rando (@amazingrando)
on CodePen.

CSS Flip Card FAQ

Can I build a CSS flip card with Tailwind CSS?

Yes. Tailwind CSS 4 covers every property the card needs. transform-3d sets preserve-3d, perspective-* sets depth, rotate-y-* turns the faces, and backface-hidden hides the reversed side. Earlier versions lack these 3D utilities.

Does Bootstrap include a flip card component?

See the Pen
Flipping Card Bootstrap.
by Nishant Guleria (@nishant88)
on CodePen.

No. Bootstrap’s card component is a content container with headers, footers and images, and its documentation describes no flip behavior.

Add the rotation with custom CSS on top of the card markup, and use Bootstrap’s grid to wrap the cards in columns.

Is the GSAP Flip plugin the same as a CSS flip card?

Only the name is shared. The GSAP Flip plugin records an element’s state, lets the DOM change, then animates the difference, which suits layout transitions in grid and flexbox.

A rotating card built with GSAP still tweens a rotation.

How do I put an image on the front and text on the back?

See the Pen
Figure Flip Card
by Brad Bodine (@bbodine1)
on CodePen.

Place the img inside the front face and the heading and text inside the back face. W3Schools’ flip card example does exactly this, with an avatar in front and a name and title behind it.

Size the image to the face with object-fit: cover.

How do I make the card spin a full 360 degrees?

Change the trigger rotation from 180deg to 360deg. A DEV Community tutorial notes this suits single-sided buttons, because a two-faced card finishes the turn showing its front again and the back face appears only mid-spin.

Which content suits a CSS flip card?

See the Pen
Card Flip Jquery
by bycreator (@bycreator)
on CodePen.

Anything where the front identifies something and the back adds optional detail. Team member photos with a bio behind them are the classic case. Product images with specs work too, and so do flashcards that put a term on the front and its meaning on the back. Quackit and Colorlib both show these patterns.

Can a CSS flip card flip on its own with keyframes?

Yes, an animation built from CSS keyframes can rotate the inner wrapper on a timer.

The City of Calgary design system advises against it, because motion that starts without user interaction is unpredictable and disorienting.

How to Test a CSS Flip Card Before Launch

Testing comes down to whether the back face stays reachable under every input and setting your visitors use. That means mouse, keyboard, touch, a screen reader and reduced motion.

Run the checks in order of how many visitors a failure blocks.

  • Tab to the card and press Enter and Space.
  • On a touch screen, tap once to flip and once to return.
  • Confirm a screen reader announces one face at a time.
  • Switch the operating system’s reduced motion setting on and flip again.

Reach comes before announcement and motion, since an unreachable back face is lost to a whole group of visitors however polished the animation is.

The cost is four passes per card pattern, and a grid only pays it once because every card shares the pattern.

Pages with more interactive components than cards can run the same passes through a web accessibility checklist.

Bogdan Sandu
Latest posts by Bogdan Sandu (see all)