31 CSS Hero Sections21 / 31

Pure CSSMIT licensed

Product Shot Hero

Apple-keynote product shot — a CSS-painted device front-and-centre with floating feature badges that pulse around it. Ice blue + chrome silver on warm white.

Published

Live Demo
Try it

The code

<section class="hs-21" aria-label="Hero">
  <div class="hs-21__stage">
    <div class="hs-21__device" aria-hidden="true">
      <div class="hs-21__screen"></div>
      <div class="hs-21__cam"></div>
    </div>
    <span class="hs-21__pulse hs-21__p1"><strong>· chip</strong>16-core neural</span>
    <span class="hs-21__pulse hs-21__p2"><strong>· battery</strong>22 hours</span>
    <span class="hs-21__pulse hs-21__p3"><strong>· weight</strong>1.24 kg</span>
  </div>
  <div class="hs-21__copy">
    <h2>The lightest pro<br />laptop we've ever <em>shipped.</em></h2>
    <a class="hs-21__cta" href="#buy">From $1,499 →</a>
  </div>
</section>
.hs-21 {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  width: 100%;
  min-height: 100vh;
  padding: clamp(28px, 5vw, 56px);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
  background: radial-gradient(circle at 30% 30%, #d8e8f0 0%, transparent 50%), radial-gradient(circle at 80% 70%, #e8eef2 0%, transparent 50%), #f8fafc;
  font-family: 'Inter', system-ui, sans-serif;
  color: #1a2840;
  box-sizing: border-box;
}

.hs-21__stage {
  position: relative;
  height: 100%;
  min-height: 320px;
  display: grid;
  place-items: center;
}

.hs-21__device {
  width: 320px;
  height: 200px;
  background: linear-gradient(160deg, #b8c8d8 0%, #8090a8 50%, #607080 100%);
  border-radius: 14px;
  position: relative;
  box-shadow: 0 22px 60px rgba(96,112,128,0.4), inset 0 1px 0 rgba(255,255,255,0.5), inset 0 -2px 0 rgba(0,0,0,0.18);
}

.hs-21__screen {
  position: absolute;
  inset: 8px;
  background: linear-gradient(135deg, #1a2840 0%, #0a1428 100%);
  border-radius: 7px;
  box-shadow: inset 0 0 0 2px #0a1428;
}

.hs-21__cam {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #1a2840;
}

.hs-21__pulse {
  position: absolute;
  background: #fff;
  border: 1px solid #d0d8e0;
  padding: 8px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  color: #1a2840;
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  box-shadow: 0 8px 22px rgba(96,112,128,0.18);
  animation: hs-21-bob 4s ease-in-out infinite;
}

.hs-21__pulse strong {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: #6b85a5;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.hs-21__p1 {
  top: 10%;
  left: 4%;
  animation-delay: 0s;
}

.hs-21__p2 {
  top: 35%;
  right: 0;
  animation-delay: -1.3s;
}

.hs-21__p3 {
  bottom: 12%;
  left: 12%;
  animation-delay: -2.6s;
}

@keyframes hs-21-bob {
  0%,
    100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-6px);
  }
}

.hs-21__copy {
  padding: 12px 0;
}

.hs-21 h2 {
  margin: 0 0 22px;
  font-size: clamp(30px, 4.5vw, 48px);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: #1a2840;
}

.hs-21 h2 em {
  background: linear-gradient(90deg, #6b85a5, #b8c8d8);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-style: italic;
  font-weight: 800;
}

.hs-21__cta {
  display: inline-block;
  padding: 13px 24px;
  background: #1a2840;
  color: #f8fafc;
  border-radius: 999px;
  text-decoration: none;
  font-weight: 600;
  font-size: 14.5px;
  transition: transform 0.15s;
}

.hs-21__cta:hover {
  transform: translateY(-1px);
}

@media (max-width: 720px) {
  .hs-21 {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hs-21__pulse {
    animation: none;
  }

  .hs-21__cta {
    transition: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Hero Section from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Product Shot Hero
Source: https://codefronts.com/layouts/css-hero-sections/product-shot-hero/

Apple-keynote product shot — a CSS-painted device front-and-centre with floating feature badges that pulse around it. Ice blue + chrome silver on warm white.
## HTML
```html
<section class="hs-21" aria-label="Hero">
  <div class="hs-21__stage">
    <div class="hs-21__device" aria-hidden="true">
      <div class="hs-21__screen"></div>
      <div class="hs-21__cam"></div>
    </div>
    <span class="hs-21__pulse hs-21__p1"><strong>· chip</strong>16-core neural</span>
    <span class="hs-21__pulse hs-21__p2"><strong>· battery</strong>22 hours</span>
    <span class="hs-21__pulse hs-21__p3"><strong>· weight</strong>1.24 kg</span>
  </div>
  <div class="hs-21__copy">
    <h2>The lightest pro<br />laptop we've ever <em>shipped.</em></h2>
    <a class="hs-21__cta" href="#buy">From $1,499 →</a>
  </div>
</section>
```
## CSS
```css
.hs-21 {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  width: 100%;
  min-height: 100vh;
  padding: clamp(28px, 5vw, 56px);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
  background: radial-gradient(circle at 30% 30%, #d8e8f0 0%, transparent 50%), radial-gradient(circle at 80% 70%, #e8eef2 0%, transparent 50%), #f8fafc;
  font-family: 'Inter', system-ui, sans-serif;
  color: #1a2840;
  box-sizing: border-box;
}

.hs-21__stage {
  position: relative;
  height: 100%;
  min-height: 320px;
  display: grid;
  place-items: center;
}

.hs-21__device {
  width: 320px;
  height: 200px;
  background: linear-gradient(160deg, #b8c8d8 0%, #8090a8 50%, #607080 100%);
  border-radius: 14px;
  position: relative;
  box-shadow: 0 22px 60px rgba(96,112,128,0.4), inset 0 1px 0 rgba(255,255,255,0.5), inset 0 -2px 0 rgba(0,0,0,0.18);
}

.hs-21__screen {
  position: absolute;
  inset: 8px;
  background: linear-gradient(135deg, #1a2840 0%, #0a1428 100%);
  border-radius: 7px;
  box-shadow: inset 0 0 0 2px #0a1428;
}

.hs-21__cam {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #1a2840;
}

.hs-21__pulse {
  position: absolute;
  background: #fff;
  border: 1px solid #d0d8e0;
  padding: 8px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  color: #1a2840;
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  box-shadow: 0 8px 22px rgba(96,112,128,0.18);
  animation: hs-21-bob 4s ease-in-out infinite;
}

.hs-21__pulse strong {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: #6b85a5;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.hs-21__p1 {
  top: 10%;
  left: 4%;
  animation-delay: 0s;
}

.hs-21__p2 {
  top: 35%;
  right: 0;
  animation-delay: -1.3s;
}

.hs-21__p3 {
  bottom: 12%;
  left: 12%;
  animation-delay: -2.6s;
}

@keyframes hs-21-bob {
  0%,
    100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-6px);
  }
}

.hs-21__copy {
  padding: 12px 0;
}

.hs-21 h2 {
  margin: 0 0 22px;
  font-size: clamp(30px, 4.5vw, 48px);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: #1a2840;
}

.hs-21 h2 em {
  background: linear-gradient(90deg, #6b85a5, #b8c8d8);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-style: italic;
  font-weight: 800;
}

.hs-21__cta {
  display: inline-block;
  padding: 13px 24px;
  background: #1a2840;
  color: #f8fafc;
  border-radius: 999px;
  text-decoration: none;
  font-weight: 600;
  font-size: 14.5px;
  transition: transform 0.15s;
}

.hs-21__cta:hover {
  transform: translateY(-1px);
}

@media (max-width: 720px) {
  .hs-21 {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hs-21__pulse {
    animation: none;
  }

  .hs-21__cta {
    transition: none;
  }
}
```

How this works

The product hero section is a two-column CSS grid — grid-template-columns: 1.2fr 1fr — with the painted device stage on the left and the copy block on the right, collapsed to a single column below 720px for responsive hero section behaviour. The .hs-21__stage container uses position: relative plus display: grid; place-items: center so the CSS-painted laptop sits centred while the three .hs-21__pulse feature badges anchor absolutely at top: 10%; left: 4%, top: 35%; right: 0, and bottom: 12%; left: 12%. Each badge floats on a shared hs-21-bob keyframe (4s ease-in-out, translateY 0 → -6px → 0) with staggered animation-delay values of 0s, -1.3s, and -2.6s so no two badges peak together — the eye reads motion, not a synchronised bounce.

The palette is Apple-keynote chrome: two soft radial gradients (#d8e8f0 at 30% 30%, #e8eef2 at 80% 70%) painted over a warm-white #f8fafc base, so the stage feels lit rather than filled. The device body uses a diagonal linear-gradient #b8c8d8 → #8090a8 → #607080 with paired inset shadows (rgba(255,255,255,0.5) top, rgba(0,0,0,0.18) bottom) that fake brushed-aluminium bevel in pure CSS. Inter drives the sans-serif body; JetBrains Mono 10px labels the badge micro-copy in the exact tech-spec register buyers expect. The <em> in the h2 uses background-clip: text with a chrome gradient #6b85a5 → #b8c8d8 — the same visual language as a spec-page reveal.

Why it converts: object-forward product hero section framing triggers fusiform-recognition dwell, and NN-group eye-tracking shows above-the-fold dwell doubles when a rendered product replaces a stock lifestyle shot. The single pill CTA From $1,499 → puts price transparency in the hero — a Baymard-validated pattern for landing-page hero conversion rate optimization — while the three floating spec badges pre-answer the top objections (chip, battery, weight) before the fold breaks.

Make it yours

  • Recolor to your brand by swapping four values: the warm-white base #f8fafc, the two radial-gradient tints (#d8e8f0, #e8eef2), and the deep-navy accent #1a2840 used on the h2, the CTA fill, and the screen. Keep the chrome gradient #b8c8d8 → #607080 intact — that is the device.
  • Swap the device silhouette: change .hs-21__device width/height/border-radius to reshape it (420px × 260px, radius 20px reads as a tablet; 200px × 320px, radius 28px reads as a phone; 320px × 180px, radius 6px reads as a hardware box). The chrome gradient carries any silhouette.
  • Change the CTA shape: border-radius: 999px is the Apple/keynote pill. Drop to border-radius: 8px for a Stripe-style rectangle, or 0 for brutalist. If you switch to a rectangle, add box-shadow: 0 2px 0 #0a1428 so the button keeps visual weight — pills don't need it, rectangles do.
  • For dark mode: invert to background: #0a1428 with radial tints of rgba(216,232,240,0.08) and rgba(232,238,242,0.06), flip body text to #f8fafc, and swap the CTA to background: #f8fafc; color: #0a1428. The chrome device gradient stays — brushed aluminium reads on either canvas.
  • For Tailwind: bg-slate-50 grid grid-cols-[1.2fr_1fr] min-h-[480px] on the section, text-[#1a2840] text-5xl font-bold tracking-tight leading-[1.05] on the h2, bg-[#1a2840] text-slate-50 rounded-full px-6 py-3 hover:-translate-y-px on the CTA. In React/Next, wrap the stage in a component and map the three badges from an array so you can A/B-test which specs earn the pulse.

Gotchas — read before shipping

  • The three hs-21-bob animations run indefinitely on transform: translateY, which is composited — but three infinite animations still keep the GPU awake. On battery-powered devices this shows up as a measurable idle-power draw. Consider pausing them via IntersectionObserver once the hero scrolls out of view, or gate them behind @media (min-width: 720px) so mobile skips the animation entirely for a cleaner INP profile.
  • The badge positions use percentage-based absolute placement inside .hs-21__stage. If your min-height: 320px is honoured but the stage grows taller than intended (a long h2 wraps and the grid row stretches), the badges drift off the device. Lock the stage height with height: 320px in production or the pulses lose their orbit.
  • The chrome <em> uses -webkit-background-clip: text; color: transparent. In Windows High Contrast Mode the italicised word vanishes entirely — Forced Colors overrides color: transparent to system foreground but the gradient stays, producing invisible text. Add @media (forced-colors: active) { .hs-21__h2 em { color: CanvasText; background: none; } } to keep WCAG 1.4.3 contrast intact.
  • The CTA hover uses transform: translateY(-1px) — cheap and composited — but the 0.15s transition duration is on the edge of WCAG 2.3.3 (Animation from Interactions). It's fine here because the movement is 1px, but if you scale it up to 3-4px, wrap it in @media (prefers-reduced-motion: no-preference) rather than only guarding the reduced case.
  • Watch CLS on the badges: they're painted with font-size: 12.5px and depend on Inter loading. If Inter arrives after first paint the badge widths reflow, and the shadow (0 8px 22px) causes visible layout thrash. Preload Inter with <link rel="preload" as="font" crossorigin> or set font-display: optional on the badge selector so system-ui holds the position.
  • In React/Vue/Next, be careful with SSR + the animation-delay: -1.3s negative values. Some CSS-in-JS pipelines strip leading minus signs when serialising numeric-looking strings; verify the compiled output in devtools. If the delays are dropped, all three badges bob in unison and the hero looks like a bug, not a feature.

Techniques used in this demo

Search CodeFronts

Loading…