Skip to main content
ansicode

DECSTBM — Set Top/Bottom Margins (CSI r)

Define the vertical scrolling region — rows outside it stay pinned, rows inside scroll.

Byte forms

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

\\x1b[\x1b[T;Br
\\033[\033[1;24r
\\e[\e[1;24r
ESC [ESC [ T ; B r
hex1b 5b <T> 3b <B> 72

Description

Set Top and Bottom Margins. Final byte `r` (0x72); parameters are 1-based row numbers — `T` (top row, default 1) and `B` (bottom row, default = screen height). Once set, all scrolling — natural overflow at the bottom row, LF beyond row `B`, SU / SD (`\x1b[NS` / `T`), and the alt screen — operates only on rows `T..B` inclusive; rows above `T` and below `B` stay pinned. Sending `\x1b[r` (no parameters) resets to the full screen. After DECSTBM the cursor is moved to the home position of the active region (top-left). Every full-screen TUI uses this to keep a status bar (row 1 or N) frozen while the body scrolls. Pair with DECOM (`?6h/l`) to ALSO clip cursor addressing to the region.

Spec citation: xterm-ctlseqs (DECSTBM, CSI Ps ; Ps r)

Parameters

Ttop row, 1-based (default 1)
Bbottom row, 1-based (default = screen height)

Examples

bash
printf '\033[2;23r'   # rows 2..23 scroll; 1 and 24 pinned\nprintf '\033[r'       # reset to full screen
python
import sys; sys.stdout.write('\x1b[2;23r')
go
fmt.Print("\x1b[2;23r")
javascript
process.stdout.write('\x1b[2;23r')
c
printf("\x1b[2;23r");

Terminal support

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

Related sequences

In the family cookbook

CSI cookbook · 5. Margins & scroll region — DECSTBM `r` and DECSLRM `s`