31 Tailwind CSS Hero Sections
09 / 31

All 31 in 31 Tailwind CSS Hero Sections

  1. 01Centered Hero Section in Tailwind CSS with Serif Headline & Dual CTA
  2. 02Tailwind CSS Split Hero Section with Dashboard Mockup
  3. 03Tailwind CSS Animated Gradient Mesh Hero Section
  4. 04Glassmorphism Hero Section in Tailwind CSS with Aurora Background
  5. 05Tailwind CSS Developer Hero Section with Terminal Window
  6. 06Tailwind Hero Section with Animated Geometric Shapes Background
  7. 07Tailwind CSS Hero Section with Star Rating & Logo Cloud
  8. 08Tailwind CSS Animated Headline Hero with Staggered Word Reveal
  9. 09Before and After Image Comparison Slider Hero in Tailwind CSS
  10. 10Full-Screen Tailwind Hero with Animated Scroll Down Indicator
  11. 11Magazine Cover Hero Section in Tailwind CSS
  12. 12Asymmetric Typography Hero Section in Tailwind CSS
  13. 13Tailwind CSS Hero Section with Oversized Background Number
  14. 14Infinite Scrolling Marquee Hero Section in Tailwind CSS
  15. 15Tailwind CSS Hero Section with Image & Overlay Card
  16. 16Brutalist Hero Section in Tailwind CSS
  17. 17Vertical Text Hero Section in Tailwind CSS (Japanese Writing Mode)
  18. 18Kinetic Typography Hero in Tailwind CSS with Animated Letters
  19. 19Bento Grid Hero Section in Tailwind CSS
  20. 20Animated Gradient Text Hero Section in Tailwind CSS
  21. 21Tailwind CSS Product Hero with Floating Feature Badges
  22. 22Tailwind CSS Hero Section with Pricing Card
  23. 23Mobile App Landing Page Hero in Tailwind CSS with App Store Buttons
  24. 24Neon Glow Hero Section in Tailwind CSS (Cyberpunk)
  25. 25Parallax Mountain Landscape Hero in Tailwind CSS
  26. 26Isometric Illustration Hero Section in Tailwind CSS
  27. 273D Card Stack Hero in Tailwind CSS with Hover Fan-Out
  28. 28Animated Starfield Background Hero in Tailwind CSS
  29. 29Glitch Text Effect Hero Section in Tailwind CSS
  30. 30Animated Conic Gradient Ring Hero in Tailwind CSS
  31. 31Mouse-Tracking Liquid Glass Lens Hero in Tailwind CSS
Tailwind + JSMIT licensed

Before and After Image Comparison Slider Hero in Tailwind CSS

A native <input type=range> drives a single CSS custom property that wipes a clip-path between a scorched before landscape and a restored after one. Keyboard-accessible with a visible focus ring on the handle. Burnt orange, petrol blue and cream.

Live Demo
Plain CSSTailwind v4
Try it

Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49

Cruip · Affiliate link

Browse Cruip templates

The code

<section class="ths-09 grid w-full min-h-svh items-center gap-10 bg-ths09-bg px-5 py-12 font-ths09-sans text-ths09-ink sm:px-10 lg:grid-cols-[1.1fr_1fr] lg:gap-14" aria-label="Before and after comparison hero">
  <div data-ths09-stage style="--ths09-pos:50%" class="relative h-[min(68svh,560px)] min-h-[340px] overflow-hidden rounded-2xl border-4 border-ths09-ink shadow-[8px_8px_0_var(--color-ths09-rust)]">
    <div aria-hidden="true" class="absolute inset-0 bg-linear-to-b from-ths09-sky via-ths09-meadow to-ths09-field">
      <span class="absolute top-[16%] left-[70%] size-16 rounded-full bg-ths09-sun shadow-[0_0_60px_var(--color-ths09-sun)]"></span>
      <span class="absolute inset-x-0 bottom-[22%] h-[38%] bg-ths09-pine/70 [clip-path:polygon(0_70%,14%_30%,28%_62%,44%_18%,60%_58%,76%_26%,90%_52%,100%_34%,100%_100%,0_100%)]"></span>
      <span class="absolute inset-x-0 bottom-0 h-[36%] bg-ths09-pine [clip-path:polygon(0_40%,18%_10%,34%_46%,52%_0,70%_38%,86%_14%,100%_30%,100%_100%,0_100%)]"></span>
      <span class="absolute right-4 bottom-4 bg-ths09-ink px-2.5 py-1 font-ths09-mono text-[11px] font-bold tracking-[0.18em] text-ths09-bg">AFTER</span>
    </div>
    <div aria-hidden="true" class="absolute inset-0 bg-linear-to-b from-ths09-rust via-ths09-dune to-ths09-sand [clip-path:inset(0_calc(100%_-_var(--ths09-pos))_0_0)]">
      <span class="absolute top-[14%] left-[24%] size-14 rounded-full bg-ths09-bg shadow-[0_0_30px_rgb(247_236_217/0.5)]"></span>
      <span class="absolute inset-x-0 bottom-[22%] h-[38%] bg-ths09-clay/70 [clip-path:polygon(0_70%,14%_30%,28%_62%,44%_18%,60%_58%,76%_26%,90%_52%,100%_34%,100%_100%,0_100%)]"></span>
      <span class="absolute inset-x-0 bottom-0 h-[36%] bg-ths09-clay [clip-path:polygon(0_40%,18%_10%,34%_46%,52%_0,70%_38%,86%_14%,100%_30%,100%_100%,0_100%)]"></span>
      <span class="absolute bottom-4 left-4 bg-ths09-clay px-2.5 py-1 font-ths09-mono text-[11px] font-bold tracking-[0.18em] text-ths09-bg">BEFORE</span>
    </div>
    <input type="range" min="0" max="100" value="50" aria-label="Compare before and after" aria-valuetext="50 percent restored" class="peer absolute inset-0 z-30 m-0 size-full cursor-ew-resize opacity-0">
    <span aria-hidden="true" class="pointer-events-none absolute inset-y-0 left-(--ths09-pos) z-20 w-[3px] -translate-x-1/2 bg-ths09-bg shadow-[0_0_0_1px_var(--color-ths09-ink)] peer-focus-visible:[&>span]:ring-4 peer-focus-visible:[&>span]:ring-ths09-rust/60">
      <span class="absolute top-1/2 left-1/2 grid size-11 -translate-1/2 place-items-center rounded-full border-2 border-ths09-ink bg-ths09-bg text-sm font-bold text-ths09-ink shadow-lg">⇆</span>
    </span>
  </div>
  <div class="max-w-lg">
    <span class="font-ths09-mono text-[11px] font-bold tracking-[0.18em] text-ths09-rust">DRAG TO COMPARE</span>
    <h1 class="mt-4 font-ths09-serif text-[clamp(32px,4.6vw,52px)] leading-[1.06] font-bold tracking-[-0.01em] text-balance">Restoration, <em class="text-ths09-rust">one acre at a time.</em></h1>
    <p class="mt-5 text-base/relaxed text-ths09-body">We turn dust to forest in 18 months — proven on three continents.</p>
    <dl class="mt-7 grid grid-cols-3 gap-4 border-y border-ths09-ink/15 py-5">
      <div><dt class="text-xs text-ths09-body">Acres</dt><dd class="mt-1 font-ths09-serif text-2xl font-bold">41k</dd></div>
      <div><dt class="text-xs text-ths09-body">Trees</dt><dd class="mt-1 font-ths09-serif text-2xl font-bold">9.2M</dd></div>
      <div><dt class="text-xs text-ths09-body">Survival</dt><dd class="mt-1 font-ths09-serif text-2xl font-bold">87%</dd></div>
    </dl>
    <a href="#donate" class="mt-8 inline-flex min-h-12 items-center rounded-md bg-ths09-rust px-6 text-sm font-bold text-ths09-bg transition hover:bg-ths09-clay focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ths09-rust motion-reduce:transition-none">Plant a tree →</a>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-ths09-bg: #f7ecd9;
  --color-ths09-bg: oklch(0.947 0.028 81.5);
  --color-ths09-ink: #2c4a4f;
  --color-ths09-ink: oklch(0.388 0.037 209.1);
  --color-ths09-body: #3f5e4c;
  --color-ths09-body: oklch(0.452 0.047 158.4);
  --color-ths09-rust: #b5501f;
  --color-ths09-rust: oklch(0.553 0.144 43.3);
  --color-ths09-clay: #8a3614;
  --color-ths09-clay: oklch(0.445 0.123 40.3);
  --color-ths09-dune: #e8a36e;
  --color-ths09-dune: oklch(0.771 0.107 57.9);
  --color-ths09-sand: #f0b87a;
  --color-ths09-sand: oklch(0.82 0.102 68.4);
  --color-ths09-sky: #87b8a8;
  --color-ths09-sky: oklch(0.743 0.057 172.5);
  --color-ths09-meadow: #b9c08f;
  --color-ths09-meadow: oklch(0.79 0.067 114.5);
  --color-ths09-field: #d6c69a;
  --color-ths09-field: oklch(0.829 0.061 90.4);
  --color-ths09-pine: #3f6450;
  --color-ths09-pine: oklch(0.469 0.054 159.8);
  --color-ths09-sun: #f7d875;
  --color-ths09-sun: oklch(0.888 0.124 92.4);
  --font-ths09-serif: 'Playfair Display', Georgia, serif;
  --font-ths09-sans: 'Geist', system-ui, sans-serif;
  --font-ths09-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.ths-09 {
  width: 100%;
  min-height: 100svh;
}

[data-ths09-stage] {
  --ths09-pos: 50%;
}
(() => {
  document.querySelectorAll('[data-ths09-stage]').forEach((stage) => {
    if (stage.dataset.wired) return;
    stage.dataset.wired = '1';
    const range = stage.querySelector('input[type="range"]');
    const update = () => {
      stage.style.setProperty('--ths09-pos', range.value + '%');
      range.setAttribute('aria-valuetext', range.value + ' percent restored');
    };
    range.addEventListener('input', update);
    update();
  });
})();

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-ths09-bg: #f7ecd9;
  --color-ths09-bg: oklch(0.947 0.028 81.5);
  --color-ths09-ink: #2c4a4f;
  --color-ths09-ink: oklch(0.388 0.037 209.1);
  --color-ths09-body: #3f5e4c;
  --color-ths09-body: oklch(0.452 0.047 158.4);
  --color-ths09-rust: #b5501f;
  --color-ths09-rust: oklch(0.553 0.144 43.3);
  --color-ths09-clay: #8a3614;
  --color-ths09-clay: oklch(0.445 0.123 40.3);
  --color-ths09-dune: #e8a36e;
  --color-ths09-dune: oklch(0.771 0.107 57.9);
  --color-ths09-sand: #f0b87a;
  --color-ths09-sand: oklch(0.82 0.102 68.4);
  --color-ths09-sky: #87b8a8;
  --color-ths09-sky: oklch(0.743 0.057 172.5);
  --color-ths09-meadow: #b9c08f;
  --color-ths09-meadow: oklch(0.79 0.067 114.5);
  --color-ths09-field: #d6c69a;
  --color-ths09-field: oklch(0.829 0.061 90.4);
  --color-ths09-pine: #3f6450;
  --color-ths09-pine: oklch(0.469 0.054 159.8);
  --color-ths09-sun: #f7d875;
  --color-ths09-sun: oklch(0.888 0.124 92.4);
  --font-ths09-serif: 'Playfair Display', Georgia, serif;
  --font-ths09-sans: 'Geist', system-ui, sans-serif;
  --font-ths09-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.ths-09 {
  width: 100%;
  min-height: 100svh;
}

[data-ths09-stage] {
  --ths09-pos: 50%;
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;1,700&family=Geist:wght@400;500;600;700&family=JetBrains+Mono:wght@600;700&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • Three getElementById lookups and an inline clipPath string became one custom property; the script no longer knows how the wipe is drawn.
  • The repeating-gradient mountains became clip-path polygons with a near and far ridge, giving the scene depth.
  • UI upgrade from the CSS original: the invisible range had no focus indicator; peer-focus-visible: now rings the handle, and the handle grew to 44px.
  • UI upgrade: stage height is min(68svh,560px) so it no longer collapses to 360px on stacked layouts; proof stats and a Drag to compare cue added; ids replaced by a data hook so multiple sliders can coexist.
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 demo 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: Before and After Image Comparison Slider Hero in Tailwind CSS
Source: https://codefronts.com/layouts/tailwind-css-hero-sections/tailwind-before-after-image-comparison-slider-hero/

A native <input type=range> drives a single CSS custom property that wipes a clip-path between a scorched before landscape and a restored after one. Keyboard-accessible with a visible focus ring on the handle. Burnt orange, petrol blue and cream.
## HTML
```html
<section class="ths-09 grid w-full min-h-svh items-center gap-10 bg-ths09-bg px-5 py-12 font-ths09-sans text-ths09-ink sm:px-10 lg:grid-cols-[1.1fr_1fr] lg:gap-14" aria-label="Before and after comparison hero">
  <div data-ths09-stage style="--ths09-pos:50%" class="relative h-[min(68svh,560px)] min-h-[340px] overflow-hidden rounded-2xl border-4 border-ths09-ink shadow-[8px_8px_0_var(--color-ths09-rust)]">
    <div aria-hidden="true" class="absolute inset-0 bg-linear-to-b from-ths09-sky via-ths09-meadow to-ths09-field">
      <span class="absolute top-[16%] left-[70%] size-16 rounded-full bg-ths09-sun shadow-[0_0_60px_var(--color-ths09-sun)]"></span>
      <span class="absolute inset-x-0 bottom-[22%] h-[38%] bg-ths09-pine/70 [clip-path:polygon(0_70%,14%_30%,28%_62%,44%_18%,60%_58%,76%_26%,90%_52%,100%_34%,100%_100%,0_100%)]"></span>
      <span class="absolute inset-x-0 bottom-0 h-[36%] bg-ths09-pine [clip-path:polygon(0_40%,18%_10%,34%_46%,52%_0,70%_38%,86%_14%,100%_30%,100%_100%,0_100%)]"></span>
      <span class="absolute right-4 bottom-4 bg-ths09-ink px-2.5 py-1 font-ths09-mono text-[11px] font-bold tracking-[0.18em] text-ths09-bg">AFTER</span>
    </div>
    <div aria-hidden="true" class="absolute inset-0 bg-linear-to-b from-ths09-rust via-ths09-dune to-ths09-sand [clip-path:inset(0_calc(100%_-_var(--ths09-pos))_0_0)]">
      <span class="absolute top-[14%] left-[24%] size-14 rounded-full bg-ths09-bg shadow-[0_0_30px_rgb(247_236_217/0.5)]"></span>
      <span class="absolute inset-x-0 bottom-[22%] h-[38%] bg-ths09-clay/70 [clip-path:polygon(0_70%,14%_30%,28%_62%,44%_18%,60%_58%,76%_26%,90%_52%,100%_34%,100%_100%,0_100%)]"></span>
      <span class="absolute inset-x-0 bottom-0 h-[36%] bg-ths09-clay [clip-path:polygon(0_40%,18%_10%,34%_46%,52%_0,70%_38%,86%_14%,100%_30%,100%_100%,0_100%)]"></span>
      <span class="absolute bottom-4 left-4 bg-ths09-clay px-2.5 py-1 font-ths09-mono text-[11px] font-bold tracking-[0.18em] text-ths09-bg">BEFORE</span>
    </div>
    <input type="range" min="0" max="100" value="50" aria-label="Compare before and after" aria-valuetext="50 percent restored" class="peer absolute inset-0 z-30 m-0 size-full cursor-ew-resize opacity-0">
    <span aria-hidden="true" class="pointer-events-none absolute inset-y-0 left-(--ths09-pos) z-20 w-[3px] -translate-x-1/2 bg-ths09-bg shadow-[0_0_0_1px_var(--color-ths09-ink)] peer-focus-visible:[&>span]:ring-4 peer-focus-visible:[&>span]:ring-ths09-rust/60">
      <span class="absolute top-1/2 left-1/2 grid size-11 -translate-1/2 place-items-center rounded-full border-2 border-ths09-ink bg-ths09-bg text-sm font-bold text-ths09-ink shadow-lg">⇆</span>
    </span>
  </div>
  <div class="max-w-lg">
    <span class="font-ths09-mono text-[11px] font-bold tracking-[0.18em] text-ths09-rust">DRAG TO COMPARE</span>
    <h1 class="mt-4 font-ths09-serif text-[clamp(32px,4.6vw,52px)] leading-[1.06] font-bold tracking-[-0.01em] text-balance">Restoration, <em class="text-ths09-rust">one acre at a time.</em></h1>
    <p class="mt-5 text-base/relaxed text-ths09-body">We turn dust to forest in 18 months — proven on three continents.</p>
    <dl class="mt-7 grid grid-cols-3 gap-4 border-y border-ths09-ink/15 py-5">
      <div><dt class="text-xs text-ths09-body">Acres</dt><dd class="mt-1 font-ths09-serif text-2xl font-bold">41k</dd></div>
      <div><dt class="text-xs text-ths09-body">Trees</dt><dd class="mt-1 font-ths09-serif text-2xl font-bold">9.2M</dd></div>
      <div><dt class="text-xs text-ths09-body">Survival</dt><dd class="mt-1 font-ths09-serif text-2xl font-bold">87%</dd></div>
    </dl>
    <a href="#donate" class="mt-8 inline-flex min-h-12 items-center rounded-md bg-ths09-rust px-6 text-sm font-bold text-ths09-bg transition hover:bg-ths09-clay focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ths09-rust motion-reduce:transition-none">Plant a tree →</a>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-ths09-bg: #f7ecd9;
  --color-ths09-bg: oklch(0.947 0.028 81.5);
  --color-ths09-ink: #2c4a4f;
  --color-ths09-ink: oklch(0.388 0.037 209.1);
  --color-ths09-body: #3f5e4c;
  --color-ths09-body: oklch(0.452 0.047 158.4);
  --color-ths09-rust: #b5501f;
  --color-ths09-rust: oklch(0.553 0.144 43.3);
  --color-ths09-clay: #8a3614;
  --color-ths09-clay: oklch(0.445 0.123 40.3);
  --color-ths09-dune: #e8a36e;
  --color-ths09-dune: oklch(0.771 0.107 57.9);
  --color-ths09-sand: #f0b87a;
  --color-ths09-sand: oklch(0.82 0.102 68.4);
  --color-ths09-sky: #87b8a8;
  --color-ths09-sky: oklch(0.743 0.057 172.5);
  --color-ths09-meadow: #b9c08f;
  --color-ths09-meadow: oklch(0.79 0.067 114.5);
  --color-ths09-field: #d6c69a;
  --color-ths09-field: oklch(0.829 0.061 90.4);
  --color-ths09-pine: #3f6450;
  --color-ths09-pine: oklch(0.469 0.054 159.8);
  --color-ths09-sun: #f7d875;
  --color-ths09-sun: oklch(0.888 0.124 92.4);
  --font-ths09-serif: 'Playfair Display', Georgia, serif;
  --font-ths09-sans: 'Geist', system-ui, sans-serif;
  --font-ths09-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.ths-09 {
  width: 100%;
  min-height: 100svh;
}

[data-ths09-stage] {
  --ths09-pos: 50%;
}
```

## JavaScript
```js
(() => {
  document.querySelectorAll('[data-ths09-stage]').forEach((stage) => {
    if (stage.dataset.wired) return;
    stage.dataset.wired = '1';
    const range = stage.querySelector('input[type="range"]');
    const update = () => {
      stage.style.setProperty('--ths09-pos', range.value + '%');
      range.setAttribute('aria-valuetext', range.value + ' percent restored');
    };
    range.addEventListener('input', update);
    update();
  });
})();
```

How this works

One variable, two consumers. The script writes --ths09-pos on the stage and nothing else. The before layer clips itself with calc(100% - var(--ths09-pos)), the handle moves with left-(--ths09-pos). No inline clipPath strings, no class toggles.

Accessible by construction. The range input covers the stage at opacity-0 so drag, click, arrow keys and screen-reader stepping all work natively. Because it is a peer placed before the handle, peer-focus-visible:ring-4 lights the handle when the slider has keyboard focus.

Make it yours

  • Real photos: replace each scene's contents with an <img class=absolute inset-0 size-full object-cover>.
  • Vertical wipe: swap to inset(calc(100%-var(--ths09-pos))_0_0_0) and top-(--ths09-pos).
  • Start position: change value and the inline --ths09-pos together.

Gotchas — read before shipping

  • Subtraction in calc() needs spaces; inside a class write them as underscores: calc(100%_-_var(--ths09-pos)).
  • opacity-0 keeps the input focusable; invisible or hidden would remove it from the tab order.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

clip-path: inset() and range inputs are universal.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Theme tokensset in @theme, used by a utility

Arbitraryneeds bracket syntax

Search CodeFronts

Loading…