05글자 분할 슬라이드
글자가 하나씩 차례로 위로 빠져나가고 같은 글자가 아래에서 올라와 자리를 메웁니다. 지연 시간만 글자 번호에 비례해 주면 물결처럼 번집니다.
쓰임글자가 짧은 링크형 버튼에서 밑줄이나 색 변화 말고 다른 신호를 주고 싶을 때
글자별 지연translate: 0 -50%clip

<main class="stage">
<button class="split is-demo" type="button" aria-label="자세히 보기"><span class="split__in" aria-hidden="true"></span></button>
</main>@use "../../../../site/static/demo-tokens" as *;
// 변형은 이 세 줄만 바꾼다
$duration: $dur-loop;
$easing: $ease-spring;
$stagger: 70ms;
@include stage($stage-orange);
.split {
border: 0;
cursor: pointer;
padding: $sp-3 $sp-6;
border-radius: $r-control;
background: $subject-cream;
color: $stage-orange;
font-family: inherit;
font-size: clamp(18px, 6vw, 26px);
font-weight: 800;
}
.split__in { display: inline-flex; }
// 창(1.25em)은 고정이고 그 안의 두 겹이 굴러간다
.split__ch {
display: inline-block;
overflow: hidden;
height: 1.25em;
line-height: 1.25;
}
.split__ch b { display: block; }
.split__ch i { display: block; font-style: normal; }
.split.is-demo .split__ch b {
animation: split-roll $duration $easing infinite;
animation-delay: calc(var(--i) * #{$stagger});
}
// 두 겹이라 -50% 가 정확히 한 줄. 0 으로 돌아와 끝나므로 되감기가 안 보인다
@keyframes split-roll {
0%, 12% { translate: 0 0; }
42%, 68% { translate: 0 -50%; }
100% { translate: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
.split.is-demo .split__ch b { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ff4d1f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.split {
border: 0;
cursor: pointer;
padding: 12px 24px;
border-radius: 12px;
background: #fff7e6;
color: #ff4d1f;
font-family: inherit;
font-size: clamp(18px, 6vw, 26px);
font-weight: 800;
}
.split__in {
display: inline-flex;
}
.split__ch {
display: inline-block;
overflow: hidden;
height: 1.25em;
line-height: 1.25;
}
.split__ch b {
display: block;
}
.split__ch i {
display: block;
font-style: normal;
}
.split.is-demo .split__ch b {
animation: split-roll 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
animation-delay: calc(var(--i) * 70ms);
}
@keyframes split-roll {
0%, 12% {
translate: 0 0;
}
42%, 68% {
translate: 0 -50%;
}
100% {
translate: 0 0;
}
}
@media (prefers-reduced-motion: reduce) {
.split.is-demo .split__ch b {
animation: none;
}
}// 실제 동작: aria-label 의 글자를 하나씩 이중으로 쌓고, 글자 번호(--i)를 지연 시간으로 쓴다.
var split = document.querySelector('.split');
var box = split.querySelector('.split__in');
var text = split.getAttribute('aria-label');
for (var i = 0; i < text.length; i++) {
var cell = document.createElement('span');
var roll = document.createElement('b');
cell.className = 'split__ch';
cell.style.setProperty('--i', i);
for (var k = 0; k < 2; k++) {
var face = document.createElement('i');
face.textContent = text[i] === ' ' ? ' ' : text[i];
roll.appendChild(face);
}
cell.appendChild(roll);
box.appendChild(cell);
}import type { CSSProperties } from "react";
import styles from "./SplitTextButton.module.scss";
export type SplitTextButtonProps = {
label?: string;
duration?: number;
easing?: string;
stagger?: number;
};
type CellVars = CSSProperties & { "--i"?: number };
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--stagger"?: string };
export default function SplitTextButton({
label = "See details",
duration = 2000,
easing = "cubic-bezier(.2,.8,.2,1)",
stagger = 70,
}: SplitTextButtonProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--stagger": `${stagger}ms` };
const chars = label.split("");
return (
<button type="button" className={styles.split} style={vars} aria-label={label}>
<span className={styles.inner} aria-hidden="true">
{chars.map((ch, i) => {
const cell: CellVars = { "--i": i };
return (
<span className={styles.ch} style={cell} key={`${ch}-${i}`}>
<b className={styles.roll}>
<i>{ch === " " ? " " : ch}</i>
<i>{ch === " " ? " " : ch}</i>
</b>
</span>
);
})}
</span>
</button>
);
}05 글자 분할 슬라이드 — 측정 누적면적 2.35% · 움직인 프레임 19/23GODRICH 원작 · zip 에 SCSS·React 포함 · css 버튼 hover 효과 모음 9종 — 수상작에서 반복되는 기법
이 데모가 속한 글
css 버튼 hover 효과 모음 9종 — 수상작에서 반복되는 기법css 버튼 hover 효과 모음은 마우스를 올렸을 때 버튼이 어떻게 반응하는지를 기법별로 나눠 정리한 것입니다. 아홉 개 중 하나는 누르는 순간 버튼 폭이 원으로 줄어 스피너가 돌고, 끝나면 체크가 그려진 뒤 원래 이 글의 데모 전부 보기

