Terminal aesthetic: a green screen that types itself
Green phosphor, scanlines and a blinking block caret. Each line types itself with one CSS animation and a steps() timing.
Motion loop
Terminal aesthetic, typed live
$ boot --warm phosphor phosphor ...... ok scanlines ..... ok$ cat todo.txt 1. make something small 2. make it well 3. ship it$
Sundry Millsundrymill.com/library
Terminal colours
-
Phosphor
-
Output
-
Amber
-
Screen
-
Title bar
The font
The font is Departure Mono by Helena Zhang, free under the SIL Open Font License. See it paired with Inter on its own page.
The code
Terminal
Each line needs --n, its number of characters, and --i, its place in the order.
HTML
<div class="term" role="img" aria-label="A green terminal typing out commands">
<div class="term-bar"><i></i><i></i><i></i><span>~/sundry-mill</span></div>
<div class="term-screen"><span class="term-line term-cmd" style="--n:22;--i:0">$ boot --warm phosphor</span><span class="term-line term-out" style="--n:20;--i:1"> phosphor ...... ok</span><span class="term-line term-out" style="--n:20;--i:2"> scanlines ..... ok</span><span class="term-line term-cmd" style="--n:14;--i:3">$ cat todo.txt</span><span class="term-line term-out" style="--n:25;--i:4"> 1. make something small</span><span class="term-line term-out" style="--n:17;--i:5"> 2. make it well</span><span class="term-line term-out" style="--n:12;--i:6"> 3. ship it</span><span class="term-line term-cmd term-last" style="--n:3;--i:7">$ <b class="term-caret"></b></span></div>
</div>
CSS
.term {
--green: #7CFF9B;
width: min(100%, 440px);
border-radius: 14px;
overflow: hidden;
background: #0B130E;
box-shadow: 0 0 0 1px rgba(124, 255, 155, .18), 0 30px 60px -30px rgba(0, 0, 0, .8);
font-family: 'Departure Mono', ui-monospace, monospace;
}
.term-bar {
display: flex;
align-items: center;
gap: 6px;
padding: 10px 14px;
background: #13201A;
color: rgba(124, 255, 155, .6);
font-size: 11px;
}
.term-bar i { width: 10px; height: 10px; border-radius: 50%; background: rgba(124, 255, 155, .3); }
.term-bar span { margin-left: 8px; }
.term-screen {
position: relative;
margin: 0;
padding: 16px 18px 20px;
min-height: 15em;
color: var(--green);
font: 15px/1.6 'Departure Mono', ui-monospace, monospace;
text-shadow: 0 0 6px rgba(124, 255, 155, .55);
overflow: hidden;
}
/* scanlines */
.term-screen::after {
content: "";
position: absolute;
inset: 0;
background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, .28) 0 1px, transparent 1px 3px);
pointer-events: none;
}
.term-line {
display: block;
width: 0;
white-space: pre;
overflow: hidden;
animation: term-type 8s steps(var(--n)) infinite both;
animation-delay: calc(var(--i) * .7s);
}
.term-out { color: #C8FFD6; }
@keyframes term-type {
0% { width: 0; }
8% { width: calc(var(--n) * 1ch); }
90% { width: calc(var(--n) * 1ch); }
100% { width: 0; }
}
.term-caret {
display: inline-block;
width: .6em;
height: 1.1em;
vertical-align: -.2em;
background: var(--green);
animation: term-blink 1s steps(1) infinite;
}
@keyframes term-blink { 50% { opacity: 0; } }
How to use it
- The typing is a width animation with steps(n): the line grows one character at a time because the font is monospaced and 1ch is one character.
- The caret blinks once a second. Keep anything that flashes under three times a second so it is safe for people with photosensitive epilepsy.
- For an amber screen, swap the green for #FFB23F. It was the other common phosphor colour.
Free to use in personal and commercial work. No credit needed, though a link back is always nice.