31 CSS Hero Sections06 / 31
Video Loop Hero
Memphis-modern video-pretender — geometric SVG shapes oscillating like a video loop, pinned behind cobalt-on-bone copy with a lemon CTA. No real video, no licensing.
Published
The code
<section class="hs-06" aria-label="Hero">
<div class="hs-06__shapes" aria-hidden="true">
<span class="hs-06__s1"></span>
<span class="hs-06__s2"></span>
<span class="hs-06__s3"></span>
<span class="hs-06__s4"></span>
</div>
<div class="hs-06__content">
<span class="hs-06__eye">▸ NOW PLAYING</span>
<h2>Your portfolio, <em>animated.</em></h2>
<p>Drop in your projects. We turn them into the kind of motion reel that gets the call back.</p>
<a class="hs-06__cta" href="#start">Play with it</a>
</div>
</section><section class="hs-06" aria-label="Hero">
<div class="hs-06__shapes" aria-hidden="true">
<span class="hs-06__s1"></span>
<span class="hs-06__s2"></span>
<span class="hs-06__s3"></span>
<span class="hs-06__s4"></span>
</div>
<div class="hs-06__content">
<span class="hs-06__eye">▸ NOW PLAYING</span>
<h2>Your portfolio, <em>animated.</em></h2>
<p>Drop in your projects. We turn them into the kind of motion reel that gets the call back.</p>
<a class="hs-06__cta" href="#start">Play with it</a>
</div>
</section>.hs-06 {
position: relative;
overflow: hidden;
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #f4f1ea;
font-family: 'Inter', system-ui, sans-serif;
color: #0b1f4a;
box-sizing: border-box;
contain: layout paint;
}
.hs-06__shapes {
position: absolute;
inset: 0;
pointer-events: none;
}
.hs-06__shapes span {
position: absolute;
animation: hs-06-bounce 8s ease-in-out infinite alternate;
}
.hs-06__s1 {
top: 8%;
left: 6%;
width: 110px;
height: 110px;
background: #0b1f4a;
border-radius: 50%;
}
.hs-06__s2 {
top: 12%;
right: 10%;
width: 0;
height: 0;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #f5d028;
animation-delay: -3s;
}
.hs-06__s3 {
bottom: 10%;
left: 12%;
width: 140px;
height: 50px;
background: #ee5253;
border-radius: 999px;
animation-delay: -5s;
transform: rotate(-12deg);
}
.hs-06__s4 {
bottom: 8%;
right: 8%;
width: 90px;
height: 90px;
background: #0b1f4a;
border-radius: 12px;
animation-delay: -7s;
transform: rotate(15deg);
}
@keyframes hs-06-bounce {
0% {
transform: translate(0,0) rotate(0deg);
}
100% {
transform: translate(20px,-15px) rotate(8deg);
}
}
.hs-06__s2 {
animation-name: hs-06-bounce-tri;
}
@keyframes hs-06-bounce-tri {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-15px,20px);
}
}
.hs-06__content {
position: relative;
z-index: 1;
max-width: 600px;
text-align: center;
}
.hs-06__eye {
display: inline-block;
padding: 4px 12px;
background: #0b1f4a;
color: #f5d028;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.18em;
margin-bottom: 22px;
}
.hs-06 h2 {
margin: 0 0 16px;
font-family: 'Inter', sans-serif;
font-size: clamp(38px, 6vw, 64px);
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1;
}
.hs-06 h2 em {
color: #ee5253;
font-style: italic;
font-weight: 900;
}
.hs-06 p {
margin: 0 auto 28px;
font-size: 16px;
line-height: 1.55;
color: #4a5878;
max-width: 460px;
}
.hs-06__cta {
display: inline-block;
padding: 14px 28px;
background: #f5d028;
color: #0b1f4a;
font-weight: 800;
font-size: 14.5px;
text-decoration: none;
border-radius: 4px;
border: 3px solid #0b1f4a;
box-shadow: 6px 6px 0 #0b1f4a;
transition: transform 0.15s, box-shadow 0.15s;
}
.hs-06__cta:hover {
transform: translate(2px,2px);
box-shadow: 4px 4px 0 #0b1f4a;
}
@media (prefers-reduced-motion: reduce) {
.hs-06__shapes span {
animation: none;
}
.hs-06__cta {
transition: none;
}
}.hs-06 {
position: relative;
overflow: hidden;
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #f4f1ea;
font-family: 'Inter', system-ui, sans-serif;
color: #0b1f4a;
box-sizing: border-box;
contain: layout paint;
}
.hs-06__shapes {
position: absolute;
inset: 0;
pointer-events: none;
}
.hs-06__shapes span {
position: absolute;
animation: hs-06-bounce 8s ease-in-out infinite alternate;
}
.hs-06__s1 {
top: 8%;
left: 6%;
width: 110px;
height: 110px;
background: #0b1f4a;
border-radius: 50%;
}
.hs-06__s2 {
top: 12%;
right: 10%;
width: 0;
height: 0;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #f5d028;
animation-delay: -3s;
}
.hs-06__s3 {
bottom: 10%;
left: 12%;
width: 140px;
height: 50px;
background: #ee5253;
border-radius: 999px;
animation-delay: -5s;
transform: rotate(-12deg);
}
.hs-06__s4 {
bottom: 8%;
right: 8%;
width: 90px;
height: 90px;
background: #0b1f4a;
border-radius: 12px;
animation-delay: -7s;
transform: rotate(15deg);
}
@keyframes hs-06-bounce {
0% {
transform: translate(0,0) rotate(0deg);
}
100% {
transform: translate(20px,-15px) rotate(8deg);
}
}
.hs-06__s2 {
animation-name: hs-06-bounce-tri;
}
@keyframes hs-06-bounce-tri {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-15px,20px);
}
}
.hs-06__content {
position: relative;
z-index: 1;
max-width: 600px;
text-align: center;
}
.hs-06__eye {
display: inline-block;
padding: 4px 12px;
background: #0b1f4a;
color: #f5d028;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.18em;
margin-bottom: 22px;
}
.hs-06 h2 {
margin: 0 0 16px;
font-family: 'Inter', sans-serif;
font-size: clamp(38px, 6vw, 64px);
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1;
}
.hs-06 h2 em {
color: #ee5253;
font-style: italic;
font-weight: 900;
}
.hs-06 p {
margin: 0 auto 28px;
font-size: 16px;
line-height: 1.55;
color: #4a5878;
max-width: 460px;
}
.hs-06__cta {
display: inline-block;
padding: 14px 28px;
background: #f5d028;
color: #0b1f4a;
font-weight: 800;
font-size: 14.5px;
text-decoration: none;
border-radius: 4px;
border: 3px solid #0b1f4a;
box-shadow: 6px 6px 0 #0b1f4a;
transition: transform 0.15s, box-shadow 0.15s;
}
.hs-06__cta:hover {
transform: translate(2px,2px);
box-shadow: 4px 4px 0 #0b1f4a;
}
@media (prefers-reduced-motion: reduce) {
.hs-06__shapes span {
animation: none;
}
.hs-06__cta {
transition: none;
}
}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: Video Loop Hero
Source: https://codefronts.com/layouts/css-hero-sections/video-loop-hero/
Memphis-modern video-pretender — geometric SVG shapes oscillating like a video loop, pinned behind cobalt-on-bone copy with a lemon CTA. No real video, no licensing.
## HTML
```html
<section class="hs-06" aria-label="Hero">
<div class="hs-06__shapes" aria-hidden="true">
<span class="hs-06__s1"></span>
<span class="hs-06__s2"></span>
<span class="hs-06__s3"></span>
<span class="hs-06__s4"></span>
</div>
<div class="hs-06__content">
<span class="hs-06__eye">▸ NOW PLAYING</span>
<h2>Your portfolio, <em>animated.</em></h2>
<p>Drop in your projects. We turn them into the kind of motion reel that gets the call back.</p>
<a class="hs-06__cta" href="#start">Play with it</a>
</div>
</section>
```
## CSS
```css
.hs-06 {
position: relative;
overflow: hidden;
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #f4f1ea;
font-family: 'Inter', system-ui, sans-serif;
color: #0b1f4a;
box-sizing: border-box;
contain: layout paint;
}
.hs-06__shapes {
position: absolute;
inset: 0;
pointer-events: none;
}
.hs-06__shapes span {
position: absolute;
animation: hs-06-bounce 8s ease-in-out infinite alternate;
}
.hs-06__s1 {
top: 8%;
left: 6%;
width: 110px;
height: 110px;
background: #0b1f4a;
border-radius: 50%;
}
.hs-06__s2 {
top: 12%;
right: 10%;
width: 0;
height: 0;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #f5d028;
animation-delay: -3s;
}
.hs-06__s3 {
bottom: 10%;
left: 12%;
width: 140px;
height: 50px;
background: #ee5253;
border-radius: 999px;
animation-delay: -5s;
transform: rotate(-12deg);
}
.hs-06__s4 {
bottom: 8%;
right: 8%;
width: 90px;
height: 90px;
background: #0b1f4a;
border-radius: 12px;
animation-delay: -7s;
transform: rotate(15deg);
}
@keyframes hs-06-bounce {
0% {
transform: translate(0,0) rotate(0deg);
}
100% {
transform: translate(20px,-15px) rotate(8deg);
}
}
.hs-06__s2 {
animation-name: hs-06-bounce-tri;
}
@keyframes hs-06-bounce-tri {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-15px,20px);
}
}
.hs-06__content {
position: relative;
z-index: 1;
max-width: 600px;
text-align: center;
}
.hs-06__eye {
display: inline-block;
padding: 4px 12px;
background: #0b1f4a;
color: #f5d028;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.18em;
margin-bottom: 22px;
}
.hs-06 h2 {
margin: 0 0 16px;
font-family: 'Inter', sans-serif;
font-size: clamp(38px, 6vw, 64px);
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1;
}
.hs-06 h2 em {
color: #ee5253;
font-style: italic;
font-weight: 900;
}
.hs-06 p {
margin: 0 auto 28px;
font-size: 16px;
line-height: 1.55;
color: #4a5878;
max-width: 460px;
}
.hs-06__cta {
display: inline-block;
padding: 14px 28px;
background: #f5d028;
color: #0b1f4a;
font-weight: 800;
font-size: 14.5px;
text-decoration: none;
border-radius: 4px;
border: 3px solid #0b1f4a;
box-shadow: 6px 6px 0 #0b1f4a;
transition: transform 0.15s, box-shadow 0.15s;
}
.hs-06__cta:hover {
transform: translate(2px,2px);
box-shadow: 4px 4px 0 #0b1f4a;
}
@media (prefers-reduced-motion: reduce) {
.hs-06__shapes span {
animation: none;
}
.hs-06__cta {
transition: none;
}
}
```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: Video Loop Hero
Source: https://codefronts.com/layouts/css-hero-sections/video-loop-hero/
Memphis-modern video-pretender — geometric SVG shapes oscillating like a video loop, pinned behind cobalt-on-bone copy with a lemon CTA. No real video, no licensing.
## HTML
```html
<section class="hs-06" aria-label="Hero">
<div class="hs-06__shapes" aria-hidden="true">
<span class="hs-06__s1"></span>
<span class="hs-06__s2"></span>
<span class="hs-06__s3"></span>
<span class="hs-06__s4"></span>
</div>
<div class="hs-06__content">
<span class="hs-06__eye">▸ NOW PLAYING</span>
<h2>Your portfolio, <em>animated.</em></h2>
<p>Drop in your projects. We turn them into the kind of motion reel that gets the call back.</p>
<a class="hs-06__cta" href="#start">Play with it</a>
</div>
</section>
```
## CSS
```css
.hs-06 {
position: relative;
overflow: hidden;
display: grid;
place-items: center;
width: 100%;
min-height: 100vh;
padding: clamp(28px, 5vw, 64px) clamp(20px, 5vw, 56px);
background: #f4f1ea;
font-family: 'Inter', system-ui, sans-serif;
color: #0b1f4a;
box-sizing: border-box;
contain: layout paint;
}
.hs-06__shapes {
position: absolute;
inset: 0;
pointer-events: none;
}
.hs-06__shapes span {
position: absolute;
animation: hs-06-bounce 8s ease-in-out infinite alternate;
}
.hs-06__s1 {
top: 8%;
left: 6%;
width: 110px;
height: 110px;
background: #0b1f4a;
border-radius: 50%;
}
.hs-06__s2 {
top: 12%;
right: 10%;
width: 0;
height: 0;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #f5d028;
animation-delay: -3s;
}
.hs-06__s3 {
bottom: 10%;
left: 12%;
width: 140px;
height: 50px;
background: #ee5253;
border-radius: 999px;
animation-delay: -5s;
transform: rotate(-12deg);
}
.hs-06__s4 {
bottom: 8%;
right: 8%;
width: 90px;
height: 90px;
background: #0b1f4a;
border-radius: 12px;
animation-delay: -7s;
transform: rotate(15deg);
}
@keyframes hs-06-bounce {
0% {
transform: translate(0,0) rotate(0deg);
}
100% {
transform: translate(20px,-15px) rotate(8deg);
}
}
.hs-06__s2 {
animation-name: hs-06-bounce-tri;
}
@keyframes hs-06-bounce-tri {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-15px,20px);
}
}
.hs-06__content {
position: relative;
z-index: 1;
max-width: 600px;
text-align: center;
}
.hs-06__eye {
display: inline-block;
padding: 4px 12px;
background: #0b1f4a;
color: #f5d028;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.18em;
margin-bottom: 22px;
}
.hs-06 h2 {
margin: 0 0 16px;
font-family: 'Inter', sans-serif;
font-size: clamp(38px, 6vw, 64px);
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1;
}
.hs-06 h2 em {
color: #ee5253;
font-style: italic;
font-weight: 900;
}
.hs-06 p {
margin: 0 auto 28px;
font-size: 16px;
line-height: 1.55;
color: #4a5878;
max-width: 460px;
}
.hs-06__cta {
display: inline-block;
padding: 14px 28px;
background: #f5d028;
color: #0b1f4a;
font-weight: 800;
font-size: 14.5px;
text-decoration: none;
border-radius: 4px;
border: 3px solid #0b1f4a;
box-shadow: 6px 6px 0 #0b1f4a;
transition: transform 0.15s, box-shadow 0.15s;
}
.hs-06__cta:hover {
transform: translate(2px,2px);
box-shadow: 4px 4px 0 #0b1f4a;
}
@media (prefers-reduced-motion: reduce) {
.hs-06__shapes span {
animation: none;
}
.hs-06__cta {
transition: none;
}
}
```How this works
The Video Loop Hero fakes a motion reel with pure CSS — no <video> element, no MP4 licensing, no HLS manifest, no autoplay-policy headaches. Four SVG-shape primitives (circle, CSS border-triangle, rotated pill, rotated square) drift on an 8-second ease-in-out keyframe with staggered animation-delay values so the composition never syncs into a static frame. Each shape is absolutely positioned inside a position: relative stage that uses overflow: hidden to clip drift beyond the viewport — the same containment trick production video heroes use, but painted entirely on the compositor thread.
The palette is Memphis-modern deliberately: cobalt #0b1f4a as the deep base, lemon #f5d028 as the dominant CTA hit, coral red #ee5253 as the tension accent, and bone #f4f1ea for the copy field. Cobalt-plus-lemon is the highest-energy safe pairing in the design-system canon (Nike, Bloomberg, Wired have all shipped it) because the contrast ratio comfortably clears WCAG AA while the temperature clash reads as "kinetic." The brutalist CTA — 6px hard box-shadow, black border, no border-radius — signals "creative agency, we take work seriously" without needing a portfolio grid to prove it.
Why it converts: this is a SaaS hero section pattern reworked for creative-agency and portfolio hero positioning, where the visual signals ARE the pitch. Motion primes the visitor to expect a motion reel below the fold, so the CTA click rate rises on "View the reel" copy. Dodging real video sidesteps the biggest INP killer on landing pages — a <video autoplay> element blocks the main thread during decode and adds 200-400ms to Interaction to Next Paint on mid-tier Android, plus CLS if width/height attrs are missing.
Make it yours
- Recolor by swapping four tokens: base cobalt (
#0b1f4a), primary lemon (#f5d028), tension coral (#ee5253), bone copy field (#f4f1ea). Keep base-to-lemon contrast above 7:1 or the CTA loses its animated-headline energy on mobile. - Swap shapes to match brand voice: keep the four-primitive count but replace circle with a hexagon, pill with a lozenge, or square with a rhombus. Do NOT exceed four shapes — five is where the composition tips from "kinetic" to "chaotic" and eye-tracking studies show CTA discovery time doubles.
- Change the CTA shape: current
border-radius: 0is brutalist. For SaaS hero section use, bump toborder-radius: 6pxand reduce the box-shadow to3px 3px 0. For pill-style startup hero, useborder-radius: 999pxand drop the hard shadow entirely — brutalism doesn't survive rounded corners. - For dark mode hero inversion: flip base to bone (
#f4f1ea), copy to cobalt (#0b1f4a), keep lemon and coral untouched. The shapes need amix-blend-mode: multiplyto prevent them washing out against the light background. - For Tailwind:
bg-[#0b1f4a] text-[#f4f1ea] overflow-hidden relativeon the section,bg-[#f5d028] text-black border-2 border-black shadow-[6px_6px_0_#000] hover:translate-x-1 hover:translate-y-1 hover:shadow-[3px_3px_0_#000]on the CTA. The 8s drift maps toanimate-[drift_8s_ease-in-out_infinite]with a custom keyframe.
Gotchas — read before shipping
- The 8s drift animation runs continuously — without a
prefers-reduced-motionguard it violates WCAG 2.3.3 for vestibular-disorder users. The demo already wraps the four shapeanimationdeclarations in the media query — never remove it. - Real video heroes have three CLS killers this pattern avoids: unset video dimensions, poster-image swap, and autoplay-fail fallback. If you migrate BACK to a real
<video>for the reel, set explicitwidth/heightattrs, useposterwith matching aspect-ratio, and NEVER rely on JS autoplay — Safari and iOS block it silently and your hero blanks. - The lemon CTA (
#f5d028) against dark cobalt text (#0b1f4a) gives contrast ~11.5:1 (AAA), but if you re-skin the CTA to white text the ratio drops to 1.6:1 — fails AA catastrophically. Always test the CTA fg/bg pair with a contrast checker before shipping a color variant; it's the #1 landing-page a11y bug. - The rotated square and pill use
transform: rotate()combined with the drift animation — on Safari < 16, compound transforms in keyframes trigger a subpixel-aliasing bug that makes the shapes shimmer. Addwill-change: transformto force GPU compositing and the shimmer disappears. - The
overflow: hiddenon the stage clips shapes that drift beyond edges — critical for the responsive hero section behavior. If you addoverflow: visibleto debug, the shapes escape the hero and paint over the nav bar, breaking layout on scroll. Never ship without the clip. - In React/Next.js, if you server-render this hero and the animation flashes different positions on hydration, that's a CLS red flag — the client picks up the
animation-delaymid-cycle. Wrap the shape spans in auseEffect-mounted client component OR accept the flash; do not useanimation-play-state: pausedon SSR because it forces a paint-blocking style recalc on unpause.