Retour au catalogue

Blog Hero Featured

Grande carte hero d'article avec overlay gradient, chips de tags, temps de lecture et auteur.

blogmedium Both Responsive a11y
boldeditorialuniversalagencysaasfullscreen
Theme

How to build a featured-article blog hero in React

A featured-article blog hero in React renders one large card with a full-bleed image, a bottom-anchored gradient overlay, and metadata chips, then lists secondary articles in a responsive grid below. Entrance animations run once on scroll via Framer Motion whileInView.

  • Stack: React + Framer Motion 11 + Lucide React, ~135 lines, zero extra dependencies.
  • Gradient overlay uses a CSS linear-gradient from var(--color-background) to transparent so it adapts to every theme.
  • Secondary articles use CSS auto-fill grid (minmax 320px) for fully fluid responsive behaviour.
  • Accessible: images carry empty alt (decorative); text content is never hidden by the overlay.
  • Supports both light and dark themes via CSS custom properties (themeMode: both).

Blog Hero Featured opens a blog or magazine page with one dominant article card that takes over the viewport, then hands off to a row of supporting articles below. The featured card layers a full-bleed image, a bottom-gradient that keeps text legible over any photo, and a metadata strip with author, date, read time and category chips, all entering once on scroll.

Anatomy

The component is structured in two blocks: a full-width featured card and an optional secondary article grid. The card contains a 2:1 aspect-ratio image container, an absolute-positioned gradient scrim fading from the background color upward, and a content layer pinned to the bottom with flex-wrapped chips, a clamp-scaled title, an excerpt paragraph and an author row. Secondary articles are horizontal flex cards with a 120x80px thumbnail, category label, title and an ArrowRight icon pushed to the far end.

How it works

Framer Motion's whileInView + viewport once:true handles all entrance animations without any manual scroll listener. The featured card fades up 24px (opacity 0 to 1) with a 0.7s custom ease [0.16, 1, 0.3, 1]. Each secondary article staggers with a 0.08s delay per index on top of a 0.1s base offset, creating a cascade. The gradient overlay is a single CSS gradient from var(--color-background) at 0% to transparent at 60%, so it reads correctly in every theme without a single JS line.

How to build it in React

  1. Create the featured card shell

    Wrap the card in a motion.a with initial opacity:0 y:24 and animate to opacity:1 y:0 via whileInView. Give it position:relative, borderRadius from your design token, overflow:hidden and a 2:1 aspect ratio container for the image.

    <motion.a
      initial={{ opacity: 0, y: 24 }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true }}
      transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1] }}
      style={{ position: "relative", borderRadius: "var(--radius-xl)", overflow: "hidden" }}
    >
  2. Add the gradient overlay

    Place an absolute div covering the full card with a linear-gradient from var(--color-background) at 0% to transparent at 60%. Because you use the theme background token the overlay works in both light and dark mode automatically.

    <div style={{
      position: "absolute",
      inset: 0,
      background: "linear-gradient(to top, var(--color-background) 0%, transparent 60%)"
    }} />
  3. Pin the metadata to the bottom

    Add a content div with position:absolute, bottom/left/right 0 and padding. Inside, render the category chip with an accent background, optional tag chips, the title with clamp(1.5rem, 3.5vw, 2.5rem) for fluid scaling, the excerpt, and the author row with Clock and User icons from Lucide React.

  4. Build the staggered secondary grid

    Render secondary articles in a CSS grid with gridTemplateColumns: repeat(auto-fill, minmax(320px, 1fr)). Each article is a motion.a with a stagger delay: 0.1 + index * 0.08. The flex layout inside puts a fixed-size thumbnail on the left and text content in the remaining space.

    transition={{ duration: 0.5, delay: 0.1 + i * 0.08, ease: [0.16, 1, 0.3, 1] }}

When to use it

Reach for this section as the opening block of any blog, news, or content platform where editorial hierarchy matters. It works well on SaaS product blogs, agency portfolios with case studies and media publications. Avoid it on homepages where the primary goal is product conversion rather than content discovery, and skip the secondary grid if you have fewer than two supporting articles to show.

Used by

  • Vercel, Full-bleed featured post card with gradient overlay and author metadata at the top of the blog index.
  • Stripe, Large hero post with image, category chip and read time above a grid of secondary articles.
  • Linear, Featured article card with bold typography overlaid on a cover image, consistent with the product aesthetic.
  • Loom, Hero blog post with full-width image and staggered secondary article cards below the fold.

FAQ

How does the gradient overlay stay readable in dark mode?

The gradient starts from var(--color-background), not a hardcoded color. When the theme switches, that token updates automatically, so the scrim always fades to the actual page background without any extra JavaScript.

Can I remove the secondary articles grid?

The secondaryArticles prop defaults to an empty array and the grid only renders when that array has at least one item, so you can safely omit the prop and the featured card stands alone.

How do I prevent the animation from replaying on every scroll?

The viewport: { once: true } flag on every whileInView motion element ensures the entrance animation fires exactly once when the element first enters the viewport, then stays in its final state.

Does the featured card title scale on mobile?

The title uses clamp(1.5rem, 3.5vw, 2.5rem), so it shrinks fluidly down to 24px on small screens without a media query. The excerpt is capped at 640px max-width so it never stretches uncomfortably on wide viewports.

"use client";

import { motion } from "framer-motion";
import { Clock, ArrowRight, User } from "lucide-react";

interface Author {
  name: string;
  avatar: string;
  role: string;
}

interface FeaturedArticle {
  title: string;
  excerpt: string;
  author: Author;
  date: string;
  category: string;
  readTime: string;
  image: string;
  tags: string[];
}

Code complet réservé à Pro

Code source intégral, export multi-framework et playground.

Passer en Pro, 9,99€/mois

Reviews

React Blog Hero with Featured Article Layout, Tutorial