figma guide
Designing flash sale and countdown timer UI in Figma: urgency, badges, and handoff
Design flash sale banners, PDP countdown timers, and promo urgency UI in Figma with sale states, timezone rules, and Dev Mode specs for PLP and checkout.
- Published
- Updated
- Jun 25, 2026
- Read time
- 6 min
- Level
- Beginner
Quick answer
Flash sale UI communicates time-bound pricing through countdown timers, sale badges, and promo banners tied to a real end timestamp. Show days : hours : minutes : seconds (or hours : minutes : seconds under 24h) on PDP and PLP cards, plus site-wide promo banners when the sale is active. When the timer hits zero, swap to regular price—never leave a frozen “00:00:00” on screen. Design before / active / ending soon / ended variants and document timezone (store local vs user local). Start from the Figma guides hub.
Who this is for
- Product designers running seasonal promos, lightning deals, or cart-level flash discounts.
- Design system teams standardizing sale badges across PLP, PDP, cart, and checkout.
- Engineers syncing server-side sale windows with client countdowns and cache invalidation.
Flash sale touchpoints
| Touchpoint | Component | Purpose |
|---|---|---|
| Site banner | FlashSaleBanner | Sale name + global end time |
| PLP card | Sale badge + mini timer | Scan urgency in grid |
| PDP buy box | Full countdown + strikethrough price | Conversion at decision point |
| Cart line item | ”Deal ends in …” | Prevent checkout delay surprises |
| Checkout | Price lock notice | Optional if cart holds sale price |
| Post-sale | Ended state + regular price | No ghost discounts |
Verdict: every surface that shows a sale price needs either a timer or static “Ends [date]” copy—pick one system-wide so shoppers are not confused.
CountdownTimer anatomy
| Part | Spec | Notes |
|---|---|---|
| Label | ”Deal ends in” / “Sale ends tonight” | Short; avoid ALL CAPS shouting |
| Digits | DD : HH : MM : SS or HH : MM : SS | Monospace tabular nums |
| Units | Optional sublabels d/h/m/s | Helps accessibility |
| Urgency color | Token from semantic color system | Often sale-urgent, not raw red |
| Icon | Lightning bolt optional | Use sparingly on PLP badges |
CountdownTimer
├── Variant: phase=upcoming | active | ending_soon | ended
├── Variant: format=full | compact | text_only
├── Variant: placement=pdp | plp_badge | banner | cart
├── Property: endTimestamp=ISO8601 (annotation)
└── Layers:
├── Label
├── DigitGroup (days, hours, mins, secs)
├── Separator (:)
└── EndedMessage ("Sale ended")
Use component properties for phase rather than duplicating frames per product.
Sale phase states
| Phase | Condition | UI treatment |
|---|---|---|
| Upcoming | Before startAt | ”Starts in …” or hidden until live |
| Active | Between start and end | Full countdown + sale price |
| Ending soon | Last 1–4 hours (configurable) | Accent border or pulse on badge |
| Ended | After endAt | Remove timer; show compare-at price only |
| Extended | Marketing extends sale | Update timestamp; avoid “extended again” fatigue |
Prototype with variant swap at ended state—never show sale price without an active phase variant.
Layout comparison
| Placement | Best for | Design notes |
|---|---|---|
| PDP above price | High-consideration items | Full digit groups; link to promo terms |
| PLP corner badge | Grid scanning | Compact HH:MM or “Ends today” |
| Sticky buy bar | Mobile long PDP | Slim single-line timer |
| Hero banner | Site-wide flash event | Countdown + CTA to sale category |
| Cart summary | Checkout anxiety reduction | Text-only “Price held until …” |
On mobile PLP, a text-only “Ends in 2h” badge often beats four digit boxes at 160px card width.
Price and badge sync
| Element | Sale active | Sale ended |
|---|---|---|
| Current price | Discounted | Regular |
| Compare-at | Strikethrough MSRP | Hidden or same as current |
| Badge | ”Sale” / “-30%” / “Flash” | Removed |
| Timer | Running | Hidden |
| Coupon field | May stack or exclude—document rules | Standard promos only |
| Cart total | Recalculates at end | Alert if price changes |
Align badge colors with status chips—sale is not the same token as error or success.
Timezone and accuracy rules
| Rule | Handoff note |
|---|---|
| Source of truth | Server endAt UTC; client converts |
| Display timezone | Store policy: “All times ET” vs user local |
| Clock skew | Refresh from API every N minutes; tab visibility refetch |
| Ended handling | Soft refresh PLP prices without full page reload |
| Accessibility | <time datetime="…"> equivalent in spec |
| Locale | RTL digit order unchanged; label translated |
Document in Dev Mode: “Timer drift > 60s triggers resync.”
Interaction with other promo UI
| Scenario | Behavior |
|---|---|
| Stacking coupon + flash | Show breakdown in cart; timer still applies to base sale |
| Gift card + flash | Usually allowed; note in promo terms frame |
| Member-only early access | Separate phase=members_early variant |
| Waitlist / notify me | Timer irrelevant; hide sale UI |
| Multi-currency | Countdown universal; price localized |
Avoid two competing countdowns on the same PDP—merge into one primary timer.
Handoff checklist
| Item | Dev Mode annotation |
|---|---|
startAt / endAt | ISO8601 from CMS or commerce API |
| Phase transitions | Poll or WebSocket for live events |
| Ended fallback | Component variant phase=ended |
| PLP cache | TTL ≤ shortest remaining sale window |
| Analytics | flash_timer_view, flash_atc_before_end, sale_expired_at_checkout |
| a11y | Announce phase change politely, not every second |
| Reduced motion | Static “Ends Dec 24, 11:59 PM ET” instead of ticking digits |
| Legal | Link to promo terms modal |
Use Dev Mode checklist and dark mode tokens if sale banners appear on dark headers.
Common mistakes
| Mistake | Why it hurts | Fix |
|---|---|---|
| Client-only timer | Wrong end time across timezones | Server authoritative timestamps |
| Frozen 00:00:00 | Looks broken | Swap to ended variant immediately |
| Sale badge without end date | False urgency | Always pair badge with time bound |
| Different sale prices PLP vs PDP | Abandonment | Single variant price feed |
| Aggressive red everywhere | Alarm fatigue | Semantic sale tokens, one accent |
| Timer after sale in cart | Checkout disputes | Recalculate + alert banner |
| Countdown in email mockups only | N/A for Figma UI kit | Scope to live storefront components |
Recommended workflow
- Define sale tokens in color system (
sale,sale-urgent,sale-ended). - Build
CountdownTimerwith phase variants and compact/full formats. - Add
SaleBadgefor PLP cards linking to sameendAtproperty. - Integrate into PDP buy box above price block; mirror on sticky bar if used.
- Design site
FlashSaleBannerwith link to sale category or search filters. - Spec ended + extension flows and cart price-change alert.
- Prototype active → ending soon → ended on one product frame.
- Document timezone policy and API refresh cadence for engineering.
FAQ
Show seconds on PLP cards?
Usually no—use hours/minutes or “Ends today” to reduce visual noise. Full seconds belong on PDP or cart.
Fake perpetual countdown?
Avoid it—regulatory and trust risk. Use evergreen “Limited stock” only when inventory-backed.
Multiple overlapping sales?
One primary timer per SKU. Secondary promos use static badges without competing clocks.
Lightning deal vs site-wide flash?
Lightning = SKU-scoped short window; site flash = category or catalog. Same component, different scope property in handoff.
Next steps
- Design price tags and pricing UI in Figma — sale vs regular price display
- Design badges and chips in Figma — PLP sale corner badges
- Design inline alerts and banners in Figma — site-wide promo banners
- Design product listing grids in Figma — card-level urgency
- Design coupons and promo codes UI in Figma — stacking rules with flash sales
§ Keep reading