Dot Matrix Printer
A perforated paper ticket whose lines print one by one, in order, then print again each time the ticket comes back on screen.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Distortion has 31 effects, including 5 free. Explore the category →
3 usage examples



How it works
.dmp-paper draws the paper: ivory background, grey edge, red margin 20 px from the left edge, and two columns of 16 tractor-feed holes (.dmp-holes-l, .dmp-holes-r). The text lines, in 13 px Courier New, sit inside .dmp-lines.
Each .dmp-line starts invisible and follows the dmpPrint animation (0.3 s): it appears while rising by 4 px. Its start is --dmp-start + rank × --dmp-gap, i.e. 0.5 s, 1.2 s, 1.9 s, 2.6 s, 3.3 s for the five lines provided; the rank is set on the first eight lines. The old version counted the hole columns among the lines: lines 4 and 5 showed on load, before the first three. That is fixed.
A small script watches each ticket with an IntersectionObserver (30 % threshold): when the ticket comes back on screen, its lines are reset and the print replays. Each copy of the effect is tracked separately; the script adds nothing to window and runs no loop.
Accessibility
- Real text: every line is in the HTML from the start; a screen reader reads them without waiting for the print. The holes, decorative, have
aria-hidden="true". - Contrast:
#333ink on ivory paper, a ratio of about 12:1. - Reduced motion: under
prefers-reduced-motion: reduce, the ticket shows complete at once; replaying when it comes back on screen has no visible effect. - Nothing to operate: the effect creates no focusable element. The replay depends on scrolling, never on hovering.
Browser compatibility
CSS + 0.7 KB of JavaScript, no dependency. The most recent feature is IntersectionObserver (Chrome 51, Firefox 55, Safari 12.1 according to MDN data); without it, the print plays once on load. Measured in Chromium 151, Firefox 153 and WebKit 26.5: at 1 s only line 1 is visible, at 3.8 s all five lines, in order; with two tickets, bringing the second one back only replays the second.
Without JavaScript, the print plays once on load, even if the ticket is off screen. Without CSS animations, the lines would stay invisible: the reduced-motion rule shows them; for always-visible text, remove the animation from .dmp-line.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0278-root">
<div class="dmp-paper">
<div class="dmp-holes dmp-holes-l" aria-hidden="true">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="dmp-holes dmp-holes-r" aria-hidden="true">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="dmp-lines">
<div class="dmp-line">INVOICE #00142</div>
<div class="dmp-line">Date: 1989-03-15</div>
<div class="dmp-line">Item: Floppy Disk x10</div>
<div class="dmp-line">Total: $24.99</div>
<div class="dmp-line">*** THANK YOU ***</div>
</div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Lines (HTML — <div class="dmp-line"> inside .dmp-lines) |
5 lines | Up to 8 lines follow one another on their own; beyond that, set the rank: style="--dmp-i: 8". To align columns, add white-space: pre. |
Pace (CSS — --dmp-start, --dmp-gap) |
0.5 s, then 0.7 s between lines | 0.1 s and 0.25 s for a quick till receipt; a 1 s gap for a slow, noisy printer. |
Width (CSS — --dmp-w) |
280 px | 100% fills the parent; with a fixed height on .dmp-paper, the paper covers a whole area. |
Paper and ink (CSS — --dmp-paper, --dmp-ink) |
ivory, #333 |
Green printer paper #e8f3e3, purple ink #4c1d95 for a till-stamp look. |
Text size (CSS — --dmp-size) |
13 px | 11 to 12 px in a narrow receipt; line height stays at twice the size. |
Replay on return (JS — threshold) |
0.3 (30 % of the ticket visible) |
0.6 waits until the ticket is well in view; remove the script for a single print on load. |
Demo frame (CSS — --dmp-page, --dmp-root-h) |
#0a0a0f, at least 300 px tall |
transparent and 0 drop the ticket into your page. |
FAQ
display: none and show it when you want. An element that becomes visible replays its CSS animations: the lines then print from the first one..fx-0278-root has its own observer; bringing one ticket back on screen only replays that one. The old version only tracked the first ticket on the page.