A film slate with the scene and take written on it: the striped clapper lifts, snaps shut with a jolt, then eases open again. The stripes are repeating gradients and the stick hinges on its left end.
Also known as: movie clapper animation css, film slate text, action clapboard.
<div class="txt-clapperboard-text">
<span class="txt-clapperboard-text-stick" aria-hidden="true"></span>
<div class="txt-clapperboard-text-board">
<span class="txt-clapperboard-text-scene">SCENE 12</span>
<span class="txt-clapperboard-text-take">TAKE 3 · ROLL A</span>
</div>
</div>.txt-clapperboard-text {
--c: var(--txt-color, #3b82f6);
font-size: var(--txt-size, 32px);
font-family: system-ui, sans-serif;
font-weight: 700;
line-height: 1.2;
position: relative;
display: inline-block;
width: 6.6em;
padding-top: 1.8em; /* room for the open clapper */}
/* the clapper, hinged at its bottom left corner */
.txt-clapperboard-text-stick {
display: block;
height: 0.42em;
border-radius: 0.06em;
background: repeating-linear-gradient(60deg, #fff 0 0.32em, var(--c) 0.32em 0.64em);
box-shadow: inset 0 0 0 0.05em color-mix(in srgb, var(--c) 20%, #0c0e14);
transform-origin: 0 100%;
animation: txt-clapperboard-text-clap 2.6s infinite;
}
.txt-clapperboard-text-board {
display: grid;
gap: 0.2em;
padding: 0.62em 0.5em 0.5em;
border-radius: 0 0 0.12em 0.12em;
box-shadow: 0 0 0 0.05em color-mix(in srgb, var(--c) 20%, #0c0e14);
color: #fff;
background:
repeating-linear-gradient(-60deg, #fff 0 0.32em, var(--c) 0.32em 0.64em) 0 0 / 100% 0.42em no-repeat,
color-mix(in srgb, var(--c) 20%, #0c0e14);
animation: txt-clapperboard-text-jolt 2.6s infinite;
}
.txt-clapperboard-text-scene {
font-size: 0.95em;
font-weight: 800;
letter-spacing: 0.06em;
white-space: nowrap;
}
.txt-clapperboard-text-take {
font-size: 0.42em;
font-weight: 600;
letter-spacing: 0.2em;
opacity: 0.7;
}
@keyframes txt-clapperboard-text-clap {
0%, 26% { transform: rotate(-15deg); animation-timing-function: ease-in-out; }
38% { transform: rotate(-18deg); animation-timing-function: cubic-bezier(0.7, 0, 1, 0.6); }
45% { transform: rotate(0deg); animation-timing-function: ease-out; }
49% { transform: rotate(-2.5deg); animation-timing-function: ease-in; }
53%, 78% { transform: rotate(0deg); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
100% { transform: rotate(-15deg); }
}
/* the whole slate jolts when the clapper lands */
@keyframes txt-clapperboard-text-jolt {
0%, 44.5%, 56%, 100% { transform: none; }
46.5% { transform: translateY(0.05em); }
50% { transform: translateY(-0.02em); }
}
@media (prefers-reduced-motion: reduce) {
.txt-clapperboard-text, .txt-clapperboard-text *, .txt-clapperboard-text::before, .txt-clapperboard-text::after, .txt-clapperboard-text *::before, .txt-clapperboard-text *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--txt-color on the element or a parent.
Currently previewing #3b82f6.--txt-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 40px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.