A teletext set hunts through pages 284 to 300, then the SPORT page paints in row by row with a double-height headline, while the header clock ticks. Monospace text and stepped integers.
Also known as: teletext css, ceefax style text, retro tv text page, blocky retro text animation.
<div class="txt-teletext-page" aria-label="Teletext page 300, Sport">
<div class="txt-teletext-page-screen" aria-hidden="true">
<p class="txt-teletext-page-head"><span>P300</span><span class="txt-teletext-page-pg"></span><span>TELETEXT</span><span>Wed 28 Oct</span><span class="txt-teletext-page-clock"></span></p>
<p class="txt-teletext-page-row txt-teletext-page-title" style="--r: 1"><span>SPORT</span></p>
<p class="txt-teletext-page-row" style="--r: 2"><span>Late winner seals title</span><b>302</b></p>
<p class="txt-teletext-page-row" style="--r: 3"><span>Rain stops play at Lord's</span><b>340</b></p>
<p class="txt-teletext-page-row" style="--r: 4"><span>Pole for rookie in Monza</span><b>315</b></p>
<p class="txt-teletext-page-row txt-teletext-page-foot" style="--r: 5"><span>News</span><span>Weather</span><span>TV</span><span>Index</span></p>
</div>
</div>@property --txt-teletext-page-p {
syntax: "<integer>";
initial-value: 300;
inherits: false;
}
@property --txt-teletext-page-s {
syntax: "<integer>";
initial-value: 37;
inherits: false;
}
.txt-teletext-page {
--c: var(--txt-color, #3b82f6);
font-size: calc(var(--txt-size, 32px) * 0.5);
font-family: system-ui, sans-serif;
font-weight: 700;
line-height: 1.2;
display: inline-block;
--t: 7s;
--blue: color-mix(in srgb, var(--c) 35%, #0000d8);}
.txt-teletext-page-screen {
width: 25em;
padding: 0.6em 0.8em;
border-radius: 0.4em;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-weight: 700;
line-height: 1.35;
color: #fff;
background: #000;
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08);
}
.txt-teletext-page-screen p {
display: flex;
justify-content: space-between;
gap: 0.6em;
margin: 0;
white-space: nowrap;
}
.txt-teletext-page-head span:nth-child(3) { color: #00e5ff; }
.txt-teletext-page-head span:nth-child(4) { color: #ffe500; }
.txt-teletext-page-pg {
counter-reset: txt-teletext-page-p var(--txt-teletext-page-p);
animation: txt-teletext-page-hunt var(--t) infinite;
}
.txt-teletext-page-pg::before { content: counter(txt-teletext-page-p); }
.txt-teletext-page-clock {
color: #ffe500;
counter-reset: txt-teletext-page-s var(--txt-teletext-page-s);
animation: txt-teletext-page-s 60s steps(60) -37s infinite;
}
.txt-teletext-page-clock::before { content: "21:04/" counter(txt-teletext-page-s, decimal-leading-zero); }
.txt-teletext-page-row {
visibility: hidden;
animation: txt-teletext-page-paint var(--t) step-end infinite;
animation-delay: calc(var(--r) * 0.09s);
}
.txt-teletext-page-row b { color: #ffe500; }
.txt-teletext-page-screen .txt-teletext-page-title {
height: 2.7em;
margin: 0.25em 0 0.3em;
padding: 0 0.5em;
color: #00ff6a;
background: var(--blue);
letter-spacing: 0.3em;
}
/* teletext double height: same width, twice as tall */
.txt-teletext-page-title span {
display: inline-block;
transform: scaleY(2);
transform-origin: top;
}
.txt-teletext-page-screen .txt-teletext-page-foot { margin-top: 0.3em; }
.txt-teletext-page-foot span:nth-child(1) { color: #ff3b3b; }
.txt-teletext-page-foot span:nth-child(2) { color: #00ff6a; }
.txt-teletext-page-foot span:nth-child(3) { color: #ffe500; }
.txt-teletext-page-foot span:nth-child(4) { color: #00e5ff; }
@keyframes txt-teletext-page-hunt {
0% { --txt-teletext-page-p: 284; animation-timing-function: steps(16, end); }
22%, 100% { --txt-teletext-page-p: 300; }
}
@keyframes txt-teletext-page-s {
from { --txt-teletext-page-s: 0; }
to { --txt-teletext-page-s: 60; }
}
@keyframes txt-teletext-page-paint {
0% { visibility: hidden; }
23% { visibility: visible; }
92%, 100% { visibility: hidden; }
}
@media (prefers-reduced-motion: reduce) {
.txt-teletext-page, .txt-teletext-page *, .txt-teletext-page *::before, .txt-teletext-page *::after { animation: none !important; }
.txt-teletext-page-row { visibility: visible; }
}
@media (prefers-reduced-motion: reduce) {
.txt-teletext-page, .txt-teletext-page *, .txt-teletext-page::before, .txt-teletext-page::after, .txt-teletext-page *::before, .txt-teletext-page *::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.