Skip to content

Instantly share code, notes, and snippets.

@souljorje
Last active October 22, 2025 08:28
Show Gist options
  • Save souljorje/5c5ca05018cbdeefd2a1d05471e39c9a to your computer and use it in GitHub Desktop.
Save souljorje/5c5ca05018cbdeefd2a1d05471e39c9a to your computer and use it in GitHub Desktop.
Typewriter animation with pure css
@keyframes grow {
0% {
max-height: var(--lineHeight);
}
100% {
max-height: calc(var(--lineHeight) * var(--lines));
}
}
@keyframes carriageReturn {
0% {
top: 0;
}
100% {
top: calc(var(--lineHeight) * var(--lines));
}
}
@keyframes type {
0% {
width: 100%;
}
100% {
width: 0%;
}
}
@keyframes caret {
0% {
color: var(--bgColor);
}
100% {
color: black;
}
}
.typewriter {
--bgColor: white;
--lines: 100;
--lineHeight: 1.5rem;
--timePerLine: 1s;
--widthCh: 22;
/* --width: calc(var(--widthCh) * 1ch); */
/* do not touch the time property!!! */
--time: calc(var(--lines) * var(--timePerLine));
animation: grow var(--time) steps(var(--lines));
animation-fill-mode: forwards;
line-height: var(--lineHeight);
max-height: var(--lineHeight);
overflow: hidden;
position: relative;
/* width: var(--width); */
word-break: break-all;
mix-blend-mode: lighten;
}
.typewriter::before {
content: "";
animation: type var(--timePerLine) linear infinite,
carriageReturn var(--time) steps(var(--lines)) var(--lines), caret 0.5s steps(2) infinite;
background: var(--color-base-100);
border-left: 2px solid;
bottom: 0;
height: 2rem;
position: absolute;
right: 0;
width: 100%;
}
.typewriter.no-caret::before {
border-left-width: 0;
}
.typewriter.big-caret::before {
border-left-width: 1ch;
}
.typewriter.monospace {
font-family: monospace, monospace;
}
.typewriter.monospace::before {
animation: type var(--timePerLine) steps(var(--widthCh)) infinite,
carriageReturn var(--time) steps(var(--lines)) var(--lines), caret 0.5s steps(2) infinite;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment