Card
A box that groups a photo, a title, a few facts and maybe an action about one thing, like a product, a restaurant or an article. Learn the types, the one-link-per-card pattern, and the grid, price and tap bugs testers find.
Open any shopping, food delivery or news app and you’ll see a wall of little boxes: a photo, a name, a price, a heart. Each box is a card. You scroll past hundreds of them a day without thinking about it.
For a tester, every card is a tiny screen of its own. It mixes data (names, prices, ratings), images that can be missing, badges like “Sold out”, and several things you can tap. That mix is where the bugs live.
What is a card?
A card is a container that groups everything about one item and is usually a doorway to more detail. Tap the card and you land on the product, restaurant or article page.
You’ll usually see cards used for:
- Collections of similar things: products in a shop, restaurants in a delivery app, hotels in a travel app.
- Feeds: news articles, workouts, social posts, recommendations.
- Summaries: “Your run today”, “This month’s spending”, an upcoming flight.
Cards almost never appear alone. They sit in lists, grids and carousels, so a lot of card testing is really testing how many cards behave together.
Anatomy
- 1
Container
The surface that groups everything about one item. Its edge comes from a shadow (elevated), a fill color (filled) or a border (outlined).
- 2
Media
A photo, illustration or map. Needs a fixed aspect ratio and a fallback when the image is missing or slow.
- 3
Badge / overlay
Short status on top of the media: "-20%", "Sold out", "New", "Closed". Must stay readable on any photo.
- 4
Title
The name of the item. Usually also the link to the detail page. Long titles wrap or truncate in a controlled way.
- 5
Supporting text & metadata
Rating, cuisine, delivery time, price, author, date. Short facts that help users choose without opening the card.
- 6
Actions (optional)
Secondary actions like Save or Add to cart. Separate, clearly sized targets that do not also open the card.
How it differs from similar components
| Component | What it holds | Typical use |
|---|---|---|
| Card | Rich, mixed content about one item (media, text, actions) | Products, restaurants, articles, summaries |
| List row | One line or two of text, maybe an icon | Settings, contacts, emails |
| Tile | Mostly an image or icon with a short label | Photo galleries, app launchers, categories |
| Banner | A message across the full width | Promotions, warnings, “You’re offline” |
| ModalModalA window that appears on top of the page and blocks the content behind it until it is closed.Open in glossary → | Content that blocks the screen | Decisions, forms, confirmations |
Dev note
Material Design (Android) has an official card component in three styles: elevated, filled and outlined. iOS has no system “card” control. Apps build cards from views, often in the style of the App Store’s Today tab. On the web, it’s just a styled div or article, so every site invents its own. Teams may also say tile or content card.
Designs & variants
Material’s three card types differ only in how the card’s edge is drawn: a shadow, a fill color or a border. The rest are content patterns you’ll meet in real products. Switch the demo screens to dark mode as you look.
Switch the demo screens to dark mode and see which card edges survive.
Morning run
Today · 6.2 km · 31:40
Your fastest 5 km this month. Keep the streak going!
Elevated card
Material 3A low shadow lifts the card off the background. In dark mode Material uses a lighter surface instead, because shadows barely show on black.
Test for: the edge disappearing in dark mode, shadows clipped by a scroll container.
Morning run
Today · 6.2 km · 31:40
Your fastest 5 km this month. Keep the streak going!
Filled card
Material 3A tinted background and no shadow. Calm and compact, good for grouped content like settings or summaries.
Test for: enough contrast between card, background and the text on it.
Morning run
Today · 6.2 km · 31:40
Your fastest 5 km this month. Keep the streak going!
Outlined card
Material 3A thin border, no shadow. Easy to scan in lists and grids where many cards sit side by side.
Test for: a 1 px border that vanishes on some screens or in dark mode.
Weekend guide
5 easy hikes near Zürich
Large media card
iOSiOS has no single "card" control. Apps build them, often like the App Store's Today tab: big image, text on top, rounded corners.
Test for: text over a photo staying readable, Dynamic Type pushing text out of the image.
Product card
Web & appsImage, name, rating, price, badges and actions. The most bug-prone card of all, because so much data meets in a small box.
Test for: the heart opening the product, sale prices, Sold out, long names.
Napoli Pizza Corner
4.5 (860) · Pizza · €
25–35 min €2.49
Napoli Pizza Corner
4.5 (860) · Pizza · €
25–35 min €2.49
Restaurant card
Food deliveryA wide 16:9 photo with rating, cuisine, delivery time and fee. Status like "Closed" or "Free delivery" sits on the image.
Test for: closed restaurants still orderable, fees and times matching the detail page.
Tech Daily
Why your phone battery drains faster in the cold, and what actually helps
2 h ago · 6 min read
Tech Daily
Why your phone battery drains faster in the cold, and what actually helps
2 h ago · 6 min read
Article card
News & contentHorizontal: text on the left, a small thumbnail on the right. Headlines are clamped to two or three lines.
Test for: headline truncation, wrong or missing thumbnails, stale "2 h ago" times.
Images: ratio, cropping and missing photos
Images cause more card bugs than anything else. Things to know:
- Fix the aspect ratio. Product grids usually use 1:1 or 4:5, restaurant and article cards 16:9 or 4:3. If every photo keeps its own shape, the grid jumps around and the layout shifts while images load.
- Crop, don’t squash. Photos should be cropped to fit, never stretched. A stretched shoe looks like a canoe.
Dev note
On the web that’sobject-fit: cover. - Plan for missing images. A photo can be missing, slow or broken. A good card reserves the space and shows a neutral placeholder. A bad one shows a broken-image icon, a file name, or collapses to half its height.
- Text on photos (like a “Closed” label or a headline) needs a dark overlay so it stays readable on light and busy images.
Prices, badges and status
Product and restaurant cards repeat data from the detail page, so they can disagree with it.
- Sale price: the new price is lower and highlighted, the old price is higher and struck through, and the “-25%” badge matches the math: (119 − 89) / 119 ≈ 25%.
- Sold out / Closed: the badge, the button and the detail page must all agree. “Sold out” with a working Add to cart is a classic bug.
- Currency and format: “€89.00” on the card but “89,00 €” on the detail page is a localizationLocalizationAdapting an app to a language and region, including translations, dates, currency and layout.Open in glossary → inconsistency.
Loading: skeletons
While data loads, good apps show skeleton cards: grey shapes with the same size and layout as the real cards. The page doesn’t jump when content arrives, and users see that something is happening.
A skeleton that’s a different size from the real card, or one that never goes away when there’s no data, is a bug. More on that in Empty & error states.
Whole-card tap vs action buttons
This is the most important card behavior to test. Users expect tapping anywhere on the card to open the item. But many cards also have their own buttons: a heart, Add to cart, a menu. Now the card has nested tap targets, and three things can go wrong:
- One tap, two actions. You tap the heart, and the product page opens too, because the tap “bubbles up” from the heart to the card.
- Screen reader noise. If the whole card is one link, a screen reader reads every word in it as one long link. If every part is its own link, users hear the same destination three times.
- Invalid markup (web). A
<button>inside an<a>is not allowed in HTML, and browsers and screen readers handle it unpredictably.
The fix most design systems recommend is one link per card: only the title is a real link, but its clickable area is stretched over the whole card. The secondary buttons sit on top of it as separate targets. Try all three versions:
Trail Rain Jacket
4.6 (182)€89.00, wasTap the heart, the photo, the title and Add to cart. Try Tab too.
The entire card is one big clickable element with the heart and Add to cart inside it. A tap on the heart also "bubbles up" to the card, so the product page opens too. In HTML, a button inside a link is even invalid.
What happened on tap
- Nothing yet…
Screen reader, swiping through the card · 3 stops
- 1."Trail Rain Jacket, 4.6 stars, 182 reviews, €89.00, €119.00, -25%, Add to cart, link"
- 2."button" (the heart has no label)
- 3."Add to cart, button"
When to use it
Cards are a good choice when:
- Items have different kinds of content (photo, title, price, rating) that belong together.
- Users browse and compare, like scrolling restaurants or products.
- Each item leads to a detail page.
- The layout needs to reflow: a grid of cards can show 1 column on a phone and 4 on a desktop.
Good and bad uses
Browsing products
Photos, prices and badges help users compare at a glance.
A plain list of settings
One label per box wastes space. A simple list with dividers is easier to scan.
Also avoid cards when the content is a table (comparing many numbers side by side), when there’s only one item, or when users need to read long text. A card is a preview, not the article itself.
Common bugs
| # | Bug | What you see | Typical severity |
|---|---|---|---|
| 1 | Action also opens the card | Tapping the heart, Add to cart or ⋮ also navigates to the detail page | Medium–High |
| 2 | Long text breaks the layout | Names overlap the price, push the button out, or are cut mid-word without ”…” | Medium |
| 3 | Missing image not handled | Broken-image icon, file name or alt text visible, card collapses | Medium |
| 4 | Wrong or inconsistent price | Old price lower than new, wrong % badge, card and detail page disagree | High |
| 5 | Status ignored | “Sold out” or “Closed” card still lets you order | High |
| 6 | Uneven grid | Cards in one row have different heights, buttons don’t line up | Low |
| 7 | Layout shift while loading | Images pop in and push content down, skeleton has a different size | Low–Medium |
| 8 | Wrong card opens | Tapping card 3 opens product 4, often after filtering or scrolling | High |
| 9 | Invisible in dark mode | Card edge or text disappears; shadow doesn’t show on black | Medium |
| 10 | Screen reader noise | Every fragment read separately, duplicate links, unlabeled “button” | High (for affected users) |
Stress-test it
A card that looks perfect with the designer’s sample data often falls apart with real data. Long product names are already on. Now remove the clamp, then turn off equal heights, remove a photo, turn off the fixed ratio and switch to 3 columns, and watch the grid get ragged:
Columns
Find the bug
This outdoor shop’s product grid has six bugs. Explore it like a tester:
- Tap the heart on a few products.
- Compare the cards with each other, and with the product pages.
- Try to buy something that’s sold out.
- Turn on VoiceOver and swipe through the first two cards.
🐞 Bug hunt: Product grid
This demo has 6 hidden bugs. Explore it like a tester, then check your findings.
Hiking gear
Trail Rain Jacket
4.6 (182)
€89.00€119.00
Summit Backpack 30 L
4.8 (96)
€74.50
Add to cartRidge Mid Gore-Tex Waterproof Hiking Boots, Wide Fit
4.4 (311)
€139.00
Add to cartDome Tent 2P
4.7 (58)
€249.00€199.00
Peak GPS Watch
4.5 (141)
€249.00
Add to cartAlpine Fleece
4.2 (77)
€59.99
Add to cartDevice settings
In bag: nothing yet
- 1
Hint: Tap the heart on any card.
- 2
Hint: Look at the hiking boots card.
- 3
Hint: Look at the backpack.
- 4
Hint: Read the tent's prices carefully, then open it.
- 5
Hint: Tap Add to cart on the boots, then check the bag.
- 6
Hint: Turn on VoiceOver and swipe through the first card.
How to test it
Checklist
Card test checklist
0 of 13 checked
Example test cases
TC-CARD-001Tapping a card opens the matching detail pagepositivehigh
Steps
- Open the Hiking gear category
- Note the name and price on the 3rd card
- Tap the card on an empty area below the price
Expected result
The detail page of that exact product opens, with the same name and price as on the card.
TC-CARD-002Favorite button does not open the productnegativehigh
Steps
- Open the Hiking gear category
- Tap the heart on the first card
- Tap the heart on the second card
Expected result
Both hearts become filled and the user stays on the grid the whole time. No navigation happens.
TC-CARD-003Sale price is displayed correctlypositivehigh
Preconditions
- "Trail Rain Jacket" is on sale: €89.00, was €119.00
Steps
- Find the Trail Rain Jacket card
- Open its detail page
Expected result
Card shows €89.00 highlighted, €119.00 struck through, badge "-25%". Detail page shows the same prices.
TC-CARD-004Sold out product cannot be added from the cardnegativehigh
Preconditions
- "Ridge Hiking Boots" has stock = 0
Steps
- Find the boots card
- Try to tap Add to cart
Expected result
The card shows "Sold out", the button is disabled (or replaced), and the bag count does not change.
TC-CARD-005Very long product nameedgemedium
Steps
- Open the category on the narrowest supported phone
- Find the product
Test data
Name: "Ridge Mid Gore-Tex Waterproof Hiking Boots for Rocky Trails, Wide Fit" (69 characters)
Expected result
The name is clamped to 2 lines with "…" and does not overlap the rating, price or button. The full name is on the detail page.
TC-CARD-006Product without an imageedgemedium
Preconditions
- A product exists with no image (or the image URL returns 404)
Steps
- Open the category containing it
Expected result
The card keeps its normal height and shows a neutral placeholder. No broken-image icon, file name or empty gap.
TC-CARD-007Grid while loading on a slow networkedgelow
Preconditions
- Network throttled (e.g. "3G" in DevTools, or a slow profile on the device)
Steps
- Open the category
- Watch the screen until all images have loaded
Expected result
Skeleton cards of the same size appear first. Nothing jumps when real cards and images arrive.
TC-CARD-008Screen reader reads a card as one clear unitpositivemedium
Preconditions
- VoiceOver (iOS) or TalkBack (Android) is on
Steps
- Swipe to the first product card
- Keep swiping through it
Expected result
You hear the product name as a link once, the price as "€89.00, was €119.00", then "Save Trail Rain Jacket to favorites, button" and "Add to cart, button". No file names, no unlabeled buttons, no repeated links.
Tip: click a test case to expand it.
Accessibility
- One link per card. Make the title the link, and extend its clickable area over the card. Don’t wrap the entire card, buttons and all, in one link.
- Label icon buttons. The heart needs a name like “Save Trail Rain Jacket to favorites” and a pressed/selected state. Just “button” or “heart” is useless in a list of 40 hearts.
- Decorative images get empty alt textAlt textA text description of an image that screen readers read aloud.Open in glossary →. If the title already names the product, the photo should be skipped (
alt=""), not read as “IMG_4021.jpg”. If the image adds information (a color, a map), describe it. - Prices read as one phrase. Struck-through text isn’t announced as “old price” by most screen readers, so add hidden text like “was €119.00”.
- Group the card. On iOS and Android, related text can be grouped so the screen reader reads “Trail Rain Jacket, 4.6 stars, €89.00” in one stop instead of six.
- Touch targetsTouch targetThe area of the screen that responds to a tap, which should be large enough for a finger.Open in glossary →: buttons on cards need at least 44×44 pt (iOS) / 48×48 dp (Android), with enough space between them so a tap on the heart doesn’t hit the card.
- Contrast: text on photos and badges needs 4.5:1. In dark modeDark modeA display setting that uses light text on dark backgrounds.Open in glossary →, the card edge must still be visible (a lighter surface or a border, since shadows don’t show on black).
- Keyboard (web): each card should be one Tab stop plus its buttons, in a logical focus orderFocus orderThe order in which the Tab key moves through interactive elements.Open in glossary →, with a visible focus ring around the whole card.
Mobile vs web
- No native card component, so behavior varies by app.
Dev note
Cards are built with SwiftUI views orUICollectionViewcells. - Tapping often shows a highlight or press animation; long-press may open a context menu with a preview. Test both.
- Test with Dynamic Type at the largest sizes: does the card grow, or does text get cut?
- VoiceOver: check that card content is grouped and the image isn’t read as a file name.
- Material 3 Card component: elevated, filled or outlined. Cards in a grid often reflow by window size classWindow size classAndroid's width buckets (compact, medium, expanded) used to choose a layout.Open in glossary → on tablets and foldables.
- Pressed cards show a ripple. A ripple on the whole card when you tap the heart is a hint that both got the tap.
- Test with font scale and display size changes, and with TalkBack.
- Rotate the device: do columns change correctly, and does the scroll position survive?
- Cards are custom HTML, usually an
articlewith a link inside. Inspect the markup in DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary →: look for<button>inside<a>or several links to the same URL. - Check hover states and that the cursor is a pointer over the whole card.
- Use responsive mode (Responsive design testing) to check 1, 2, 3 and 4 columns, and that cards never overflow the viewport.
- Watch for layout shift while images load (Lighthouse reports it as CLS), and check images are lazy-loadedLazy loadingLoading images or content only when the user scrolls near them.Open in glossary → below the fold.
- Middle-click / Cmd+click on a card should open it in a new tab, which only works if it’s a real link.
Check your understanding
Quick quiz
0/5 answered · 0 correct
1.You tap the heart on a product card. The heart fills AND the product page opens. What is the most likely cause?
2.A card shows "€249.00" highlighted, "€199.00" struck through and "-20%". What do you report?
3.What is the recommended way to make a whole card tappable without breaking its buttons?
4.A product has no photo. What should the card show?
5.Which test data is MOST likely to reveal a card layout bug?
Key takeaways
- A card groups media, title, supporting text, metadata and actions about one item, and usually opens a detail page.
- Test every tap target separately: the card itself, the heart, the button, the menu. One tap must do one thing.
- Use the one link per card pattern as your expected behavior for screen readers and keyboards.
- Feed cards real, ugly data: long names, missing images, sale prices, sold-out items, and compare them with the detail page.
- Check the grid as a whole: equal heights, fixed image ratios, skeletons while loading, dark mode and every screen width.
Finished this page?Nice work, this page is complete!
Mark it as done to track your progress. It's saved in this browser, no account needed.
Its review cards are now in Bites ⚡