DistortionFree

CRT Monitor Effect

A cathode-ray monitor in pure CSS: green phosphor text on black, scanlines, darkened corners, and a slight dimming of the lines every 4 seconds.

CSSPseudo-elementsRetro

Updated

> SYSTEM BOOT OK
> LOADING DATA...
> READY_
Hover or click the scene to interact

This effect is free — the Distortion category contains 31 effects total, including 5 free. Effect.Labs has 840 vanilla effects. Explore the category →

Usage examples

SombrecourtPier 9 case · day 2
> FILE: SUSPECT NO. 3
> ALIAS: THE GREY ONE
> ALIBI: NOT CHECKED
> LAST SEEN: 11:10 PM_

① Suspect file in a detective game

WhenIn a browser detective game, the investigator's desk shows a paper file on the left and, on the right, the green monitor with the suspect's record; the "Question" and "Accuse" buttons move the game forward.
WhyThe monitor sets the mood of an 80s police station without any image: four lines of text are enough, and players can read them, copy them or have them read by a screen reader.
Settings--crtm-w: 270px, --crtm-size: 13px, --crtm-root-h: 0, --crtm-page: transparent; four lines instead of three. Below 470 px wide, the file is hidden and the monitor takes the full width.
Vifrelle

Reaction test

Click to start, wait for green, then click again as fast as you can.

> READY
> BEST: 231 MS
> TRIES: 0/5_

② Result of a reaction-time test

WhenThe visitor clicks "Start", waits for the button to turn green, then clicks: the monitor shows the time in milliseconds, the best time and the number of tries. Clicking too early shows "TOO EARLY!". The test works with the keyboard (Enter or Space).
WhyThe result lands on a "machine" screen, which makes the number feel like a measurement; the glow and the dimming make the wait less dry than plain text.
Settings--crtm-w: 250px, --crtm-size: 14px. The scene's small script times the click and rewrites the text of the three lines; the monitor carries aria-live="polite" in the scene's HTML. The effect itself has no script.

Your site online tonight, backups included.

Servers in France, nightly backups, a human on the phone.

See the plans

Corbalis

Independent web host since 2009

Network status
> PARIS-1 OK
> LYON-2 OK
> BACKUP 03:00 OK_

③ Server status in a web host's footer

WhenIn a web host's footer, next to the links and the address, a small monitor lists the state of two server rooms and the time of the last backup.
WhyShrunk to 190 px, the monitor becomes a reassuring technical wink: the green "OK" words read at a glance in an otherwise plain footer.
Settings--crtm-w: 190px, --crtm-size: 11px, --crtm-frame: #334155 to match the footer; the scene also reduces the inner padding (padding: 10px 14px) and the frame (5 px).

How it works

.crtm-monitor draws the screen: #0a0a0a background, 8 px grey frame with rounded corners, 280 px wide by default, and a green inner glow (box-shadow: inset). The text in .crtm-content uses Courier New, #33ff33 green, with an 8 px text-shadow that mimics phosphor afterglow.

Two pseudo-elements cover the screen without catching the mouse: ::before draws scanlines (2 px transparent, 2 px of 15 % black), ::after darkens the edges with a radial gradient (transparent up to 60 %, then 50 % black). That vignetting suggests a bulging tube; the picture is not actually curved.

Each text <span> follows the 4 s crtmFlicker animation: nothing for 92 % of the time, then opacity drops to 0.7, comes back, drops to 0.8 and returns to 1. The lines are real text, free to replace. No JavaScript; settings go through CSS variables.

Accessibility

  • Real text: the lines are HTML text, read as is by screen readers and selectable. The ">" chevron will be read out; remove it when the content matters.
  • Contrast: #33ff33 green on #0a0a0a, a ratio of about 14:1, well above the AA threshold. The vignetting only darkens the corners.
  • Reduced motion: under prefers-reduced-motion: reduce, the periodic dimming is switched off; the text stays on screen continuously.
  • No interaction: the effect adds no button and no focusable element. If you write into the lines with a script (score, status), add aria-live="polite" on the monitor so the change is announced.

Browser compatibility

CSS only, no dependency. Gradients, inset box-shadow, animations and CSS variables have been everywhere for a long time; the most recent feature is prefers-reduced-motion (Chrome 74, Firefox 63, Safari 10.1, according to MDN data). Measured in Chromium 151, Firefox 153 and WebKit 26.5: same rendering, two independent copies, fluid width up to 100 %.

Chrome 74+✓ Full (measured)
Firefox 63+✓ Full (measured)
Safari 10.1+✓ Full (measured in WebKit)
Edge 79+✓ Full
Mobile iOS 10.3+✓ Full
Android Chrome 74+✓ Full

In a browser without prefers-reduced-motion, the dimming always plays, with no other consequence. Without CSS variables (very old browsers), the settings are ignored and the monitor keeps its default values.

The code

Copy the two blocks (HTML and CSS) into your page. No JavaScript, no dependencies.

HTML
<div class="fx-0271-root">
  <div class="crtm-monitor">
    <div class="crtm-content">
      <span>&gt; SYSTEM BOOT OK</span><br>
      <span>&gt; LOADING DATA...</span><br>
      <span>&gt; READY_</span>
    </div>
  </div>
</div>
CSS
.fx-0271-root,.fx-0271-root *,.fx-0271-root *::before,.fx-0271-root *::after{box-sizing:border-box}

/* Settings (all optional, set them on .fx-0271-root or a parent):
   --crtm-w        monitor width (280px; 100% fills the parent)
   --crtm-color    phosphor color of the text (#33ff33)
   --crtm-glow     text glow (rgba(51,255,51,.6))
   --crtm-size     text size (14px)
   --crtm-frame    frame color (#2a2a2a)
   --crtm-page / --crtm-root-h  wrapper background and min height (rgb(10,10,15) / 280px) */
.fx-0271-root{display:flex;align-items:center;justify-content:center;width:100%;min-height:var(--crtm-root-h,280px);position:relative;background:var(--crtm-page,rgb(10,10,15));color:#fff;font-family:sans-serif}

.crtm-monitor{background:#0a0a0a;border:8px solid var(--crtm-frame,#2a2a2a);border-radius:20px;padding:24px;position:relative;overflow:hidden;width:var(--crtm-w,280px);max-width:100%;min-height:160px;box-shadow:inset 0 0 60px rgba(0,255,0,.1),0 0 20px rgba(0,0,0,.5)}

/* scanlines */
.crtm-monitor::before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,0,0,.15) 2px,rgba(0,0,0,.15) 4px);pointer-events:none;z-index:2}

/* vignetting */
.crtm-monitor::after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:radial-gradient(ellipse at center,transparent 60%,rgba(0,0,0,.5) 100%);pointer-events:none;z-index:3}

.crtm-content{color:var(--crtm-color,#33ff33);font-family:"Courier New",monospace;font-size:var(--crtm-size,14px);line-height:1.6;text-shadow:0 0 8px var(--crtm-glow,rgba(51,255,51,.6));position:relative;z-index:1}

/* every 4s the lines dim briefly, like an old tube */
.crtm-content span{animation:crtmFlicker 4s infinite}

@keyframes crtmFlicker{0%,to{opacity:1}92%{opacity:1}93%{opacity:.7}94%{opacity:1}96%{opacity:.8}97%{opacity:1}}

@media (prefers-reduced-motion:reduce){
  .crtm-content span{animation:none}
}
JavaScript

Pure CSS — no JavaScript needed.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Width (CSS — --crtm-w) 280 px 100% fills the parent; the monitor never overflows its container (max-width: 100%).
Text colour (CSS — --crtm-color) #33ff33 Amber #ffb000 for an orange terminal, bluish white #d8ecff for a colder screen. Match --crtm-glow too.
Glow (CSS — --crtm-glow) rgba(51, 255, 51, .6) Colour of the 8 px halo around the letters; transparent gives crisp text without afterglow.
Text size (CSS — --crtm-size) 14 px 11 px for a small widget, 18 px and up for a title screen. Line height stays at 1.6.
Frame colour (CSS — --crtm-frame) #2a2a2a Beige #cfc6b0 for an old computer case, or your interface colour to blend the monitor into the page.
Text lines (HTML — the <span> elements of .crtm-content) 3 lines, separated by <br> Add or remove lines; every span dims together with the others.
Demo frame (CSS — --crtm-page, --crtm-root-h) rgb(10, 10, 15), at least 280 px tall transparent and 0 drop the monitor into your page without the dark band around it.

FAQ

Is the screen really curved?

No. The sense of curvature comes from the vignetting (edges darkened by a radial gradient) and the rounded corners. The text is not distorted, which keeps it perfectly readable.

How do I show changing text, like a score?

Replace the content of a <span> from a script (span.textContent = '> SCORE: 247'). Add aria-live="polite" on .crtm-monitor so screen readers announce the new value.

Can the dimming every 4 seconds be bothersome?

It is short and faint (0.7 opacity at its lowest), far from a blink. It stops by itself when the visitor asked for less motion, and you can remove it everywhere by deleting the animation rule on .crtm-content span.