^CF, ^FD and ^FO Basics

The three commands behind every text field in ZPL - set a default font, position the field, and supply the text.

A text field in ZPL needs three things: a position (^FO or ^FT), a font (^A or the default from ^CF), and data (^FD … ^FS).

^FO: field origin

^FOx,y,z places the top-left corner of the field, in dots from the label’s home position.

  • x distance from the left edge
  • y distance from the top edge
  • z justification: 0 left, 1 right, 2 automatic (follows the text direction)

Use ^FT instead when you want to position by the text baseline rather than the top. This is handy when mixing font sizes on one line.

^FD and ^FS: field data

Everything between ^FD and ^FS is printed. Characters with special meaning (^ and ~) cannot appear directly; use ^FH to include them as hex, for example ^FH^FD100_5E off^FS prints 100^ off.

^CF: change default font

^CFf,h,w

Sets the font and size used by any field without its own ^A. It stays in effect until changed or the printer is reset. The factory default is font A at 9 x 5 dots.

^XA
^CF0,30
^FO40,40^FDLine 1 in font 0^FS
^FO40,80^FDLine 2 in font 0^FS
^CFD,36,20
^FO40,130^FDLine 3 in bitmap D^FS
^XZ

A complete minimal label

^XA
^PW812
^LL406
^CF0,40
^FO40,40^FDProduct name^FS
^FO40,100^A0N,28,28^FDSKU 12345-AB^FS
^XZ

^PW sets the print width in dots and ^LL sets the label length. 812 dots is 4 inches at 203 DPI.

Useful companions

Command Purpose
^FB Wrap text in a block with width, lines and alignment
^FR Reverse print (white on black)
^FW Default orientation for all fields
^CI Select the character set. See code pages

Try these live in the label preview.

Think of a label as a grid of dots

The easiest way to get comfortable with positioning is to stop thinking in inches. Imagine a sheet of graph paper where each square is one dot. The top-left corner is 0,0. Moving right increases the first number, and moving down increases the second. When you write ^FO40,100, you’re saying “start this field 40 squares from the left edge and 100 squares down from the top”.

On a 4-inch label at 203 DPI the grid is about 812 squares wide. That’s a lot of room, so a margin of 20 or 30 dots on each side is usually enough to keep text away from the edge. Printers also have a small non-printable zone, and cheaper media can wander slightly as it feeds, so don’t push text right to the limit.

^FO versus ^FT, and which to use

Most people start with ^FO, because the top-left origin matches how you’d naturally place a text box. It works well when each field stands alone.

^FT positions by the baseline of the text, the invisible line letters sit on. That sounds fussy, but it pays off when you put different font sizes on the same line. With ^FO, a big word and a small word placed at the same y coordinate have different baselines, so they look misaligned. With ^FT they sit on the same line, the way you’d expect from a word processor. If you’ve ever fought to line up a large price with small cents beside it, this is the fix.

Getting special characters into ^FD

The text between ^FD and ^FS is literal, with two exceptions that bite: the caret and the tilde are command characters, and the printer will treat them as the start of a command. If a product name contains one, the field ends early or the label breaks. The cure is ^FH, which lets you write those characters as underscore-plus-hex codes. It’s also the safest way to include accented letters when you can’t trust how the encoding will travel. There’s a longer explanation in Unicode and code pages, and the label generator can apply the escaping for you.

Why your default font matters more than you think

^CF feels like a small convenience, but it protects you. If a field has no ^A, it falls back to the default. The factory default is a tiny bitmap font, which is almost never what you wanted. A missing font command then produces tiny text that’s easy to overlook until the labels are printed. Setting ^CF0,30 at the top of each label costs one line and removes that whole class of surprise.

Remember that ^CF stays active until it’s changed, and may persist beyond the label depending on how you’re sending jobs. If two applications share one printer, one of them changing the default can alter the other’s output. Setting it explicitly in every label is the sturdy approach.

A worked example

Suppose you need a shelf label with a product name, a price and a code. A sensible layout is the product name at the top in font 0 at 36 dots, the price below it larger, say 60 dots, and the code at the bottom in a smaller size. Build it field by field: each one gets an ^FO, an ^A, a ^FD and a ^FS. Test it in the live preview and adjust positions until it looks balanced, then confirm with one printed label. If anything runs off the edge, the cut off or wrong size page lists the usual culprits.

Short answers

What happens if I forget ^FS? The field never closes, and the next command may be swallowed into the text or the field may not print at all.

Can I put two ^FD commands in one field? Not usefully. Each field has one data command, so use another ^FO for a second piece of text.

Is there a limit to how long ^FD text can be? There are practical limits, and long strings should be wrapped with a field block. The ^A command guide and the troubleshooting page above cover wrapping.

Where should I go next? After the basics, font sizes by DPI is the page that saves the most reprints.

Last reviewed 2026-10-20