Skip to main content
ansicode

DECDHL / DECDWL / DECSWL — Double-height / double-width lines (ESC # 3 / # 4 / # 5 / # 6)

Mark the current line as double-height (top or bottom half) or double-width / single-height — DEC's per-line big-banner primitives, used by VT100 splash screens.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b#3 (DHL top) \x1b#4 (DHL bottom) \x1b#5 (DECSWL) \x1b#6 (DECDWL)
\\033[\033#3 / \033#4 / \033#5 / \033#6
\\e[\e#3 / \e#4 / \e#5 / \e#6
ESC [ESC # 3 / ESC # 4 / ESC # 5 / ESC # 6
hex1b 23 33 / 1b 23 34 / 1b 23 35 / 1b 23 36

Description

Four **C1-class** escape sequences with intermediate byte `#` (0x23) and a digit final byte (`3`/`4`/`5`/`6`). No CSI, no parameter — just `ESC # n`. Each affects the **current line** (where the cursor sits) and **persists** until overwritten by another `ESC # n` on that line, scrolled out, or cleared. - **`ESC # 3` — DECDHL top half**: render this line at double height, displaying the top half of each glyph (so the visible row is twice as tall as a normal row, occupying its own grid row). - **`ESC # 4` — DECDHL bottom half**: same line content as the `# 3` line above it, but rendering the **bottom half** of the doubled glyphs. The convention is to write the same string on two consecutive lines and mark the first `# 3` and the second `# 4` — the terminal stitches them into one double-height word. - **`ESC # 5` — DECSWL**: Single-Width Line — the default. Use this to explicitly clear a previous `# 6` / `# 3` / `# 4` from the current line. - **`ESC # 6` — DECDWL**: Double-Width Line — each glyph occupies two cell-widths. The line is the same height as a normal row but half as many glyphs fit. Glyphs past the new visible width are clipped (not wrapped). Why four sequences and not two? The double-height pair (`# 3` + `# 4`) requires the **same text** on two adjacent rows because the display engine renders the top half from the upper line and the bottom half from the lower line — each line still occupies one grid row, so cursor positioning, scroll math, and erase still work on a one-row-per-byte basis. Double-width (`# 6`) doesn't need a partner because it doubles only horizontally. Modern emulators that implement these (xterm, mlterm, urxvt, gnome-terminal partial, konsole partial) honour them visually; alacritty / kitty / wezterm / ghostty silent-ignore — they're considered a legacy aesthetic feature with no path forward in graphical-output-rich emulators. Use case today: nostalgia / retrocomputing demos, DECALN-paired alignment tests (`ESC # 8`, slug `decaln`), and faithful VT100 ROM emulators. Cursor behaviour: when entering a double-width line, the cursor's logical column 1-40 maps to visual column 1-80; a write past visual column 80 (logical 41) is clipped or wraps depending on DECAWM.

Spec citation: DEC VT100 (DECDHL / DECDWL / DECSWL) / xterm-ctlseqs

Parameters

Examples

bash
# Banner-style double-height header:\nclear\nprintf '\033#3WELCOME\n'   # top half\nprintf '\033#4WELCOME\n'   # bottom half — same text, completes the doubled glyph
python
import sys\nsys.stdout.write('\x1b#6BIG\n')   # double-width single-height\nsys.stdout.write('\x1b#5normal again\n')   # explicit single-width
go
// Construct a 2-line splash header:\nfor _, half := range []string{"\x1b#3", "\x1b#4"} {\n    fmt.Print(half + "ANSICODE\n")\n}
javascript
process.stdout.write('\x1b#6Wide Title\n')   // double-width\nprocess.stdout.write('\x1b#5')               // reset line to normal width
c
printf("\x1b#3SPLASH\n");   /* top */\nprintf("\x1b#4SPLASH\n");   /* bottom — terminal stitches into doubled glyphs */

Terminal support

xterm
yes
Linux console (fbcon)
no
macOS Terminal.app
partial
iTerm2
partial
Windows Terminal
no
cmd.exe / ConPTY
no
kitty
no
alacritty
no
WezTerm
no
Ghostty
no
GNOME Terminal
partial
Konsole
partial
tmux
no
GNU screen
no

Related sequences

In the family cookbook

ESC cookbook · 4. Double-width / double-height lines + alignment test — `\x1b#3-#6` and `\x1b#8`