Fullscreen Image Hero
A full-screen photo hero with a headline that rises line by line, plus an intro and two sweep-on-hover buttons. React and Tailwind CSS, no dependencies.
FullscreenImageHero.tsx
// Full-screen photo hero: the headline rises line by line bottom left,
// intro and buttons sit bottom right (stacked below on phones).
// Pure Tailwind, no dependencies. Works with Tailwind v3 and v4.
type Props = {
heading?: string[];
intro?: string;
image?: string;
imageAlt?: string;
primary?: { label: string; href: string };
secondary?: { label: string; href: string };
};
export default function FullscreenImageHero({
heading = ["The sea, as it", "should be"],
intro = "Hand-picked superyachts, exceptional crews and itineraries written for one. Charter for a week, or find the yacht you will keep for a lifetime.",
image = "https://images.unsplash.com/photo-1528154291023-a6525fabe5b4?w=2400&q=80&auto=format&fit=crop",
imageAlt = "A white yacht alone on deep blue water, seen from above",
primary = { label: "Explore the fleet", href: "#" },
secondary = { label: "Plan a voyage", href: "#" },
}: Props) {
return (
<section className="relative isolate flex h-dvh min-h-[40rem] flex-col justify-end overflow-hidden bg-[#060b10] font-['Helvetica_Neue',Helvetica,Arial,sans-serif] text-white antialiased">
<style>{`
@keyframes hero-rise { from { transform: translateY(110%) } to { transform: translateY(0) } }
@keyframes hero-settle { from { transform: scale(1.14) } to { transform: scale(1) } }
@keyframes hero-fade { from { opacity: 0; transform: translateY(1rem) } to { opacity: 1; transform: translateY(0) } }
`}</style>
<img
src={image}
alt={imageAlt}
className="absolute inset-0 -z-10 h-full w-full object-cover motion-safe:animate-[hero-settle_3.2s_cubic-bezier(0.22,1,0.36,1)_both]"
/>
<div className="absolute inset-0 -z-10 bg-gradient-to-b from-[#060b10]/45 via-[#060b10]/10 to-[#060b10]/75" />
<div className="mx-auto grid w-full max-w-[100rem] gap-10 px-4 pb-14 md:px-8 md:pb-20 lg:grid-cols-12 lg:items-end lg:gap-8 lg:px-12">
<h1 className="text-[clamp(2.75rem,6.2vw,6.5rem)] font-normal leading-[0.95] tracking-[-0.04em] lg:col-span-7">
{heading.map((line, i) => (
<span key={i} className="-mb-[0.08em] block overflow-hidden pb-[0.08em]">
<span
className="block motion-safe:animate-[hero-rise_1.4s_cubic-bezier(0.22,1,0.36,1)_both]"
style={{ animationDelay: `${0.2 + i * 0.1}s` }}
>
{line}
</span>
</span>
))}
</h1>
<div
className="flex flex-col items-start gap-8 motion-safe:animate-[hero-fade_1.4s_cubic-bezier(0.22,1,0.36,1)_both] lg:col-span-4 lg:col-start-9"
style={{ animationDelay: "0.8s" }}
>
<p className="max-w-md text-base leading-relaxed text-white/85 md:text-lg">{intro}</p>
<div className="flex flex-wrap gap-3">
<a
href={primary.href}
className="group relative isolate inline-flex h-14 items-center gap-4 overflow-hidden bg-white px-8 text-xs font-medium uppercase tracking-[0.08em] text-[#0d1114] transition-colors duration-700 hover:text-white"
>
<span className="absolute inset-0 -z-10 origin-bottom scale-y-0 bg-[#111c25] transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:scale-y-100" />
{primary.label}
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.1} aria-hidden className="h-4 w-4 transition-transform duration-700 group-hover:translate-x-1">
<path d="M3 12h17M14 6l6 6-6 6" />
</svg>
</a>
<a
href={secondary.href}
className="group relative isolate inline-flex h-14 items-center overflow-hidden border border-white/40 px-8 text-xs font-medium uppercase tracking-[0.08em] text-white transition-colors duration-700 hover:border-white hover:text-[#0d1114]"
>
<span className="absolute inset-0 -z-10 origin-bottom scale-y-0 bg-white transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:scale-y-100" />
{secondary.label}
</a>
</div>
</div>
</div>
</section>
);
}
How to use it
- Make sure your Next.js or React project has Tailwind CSS set up.
- Create
components/FullscreenImageHero.tsxand paste the code. - Import it into a page and replace the placeholder text and images with your own.
More free components
All hero sections →
Ready for a faster site that's easier to edit?
Book a free 30-minute call. We'll review your current site and send a fixed-price plan. No pressure, no pitch.
Book Free Call No commitment required


