Menu Typography That Reads on a Phone
How to set a restaurant menu as a web page: type scale, measure, hierarchy, the leader-dot problem, and the accessibility rules that decide the floor.

A menu set for the web is not a menu set for print with the paper taken away. The page has to carry the same hierarchy using a completely different set of tools: a type scale that survives a 375 pixel screen, a measure you control rather than one the sheet size gave you, and a set of accessibility rules that decide the floor before taste gets a vote. This is the part of a restaurant website that most builds skip, and it is where most of the perceived quality of a chef-led site actually comes from.
What follows is how we set a menu page: the decisions in the order we make them, what each one is actually solving, and where the standards draw a hard line that overrides preference.
Start with the measure, not the size
The first decision on a menu page is how wide a line of text is allowed to get, and it is first because every other typographic decision depends on it.
Why width comes before size
A type size only means something relative to the line it sits on. Sixteen pixels across a 340 pixel phone column is comfortable. The same sixteen pixels across a 1,400 pixel desktop window is a chore, because the eye has to travel the whole width and then find the beginning of the next line, and there is nothing in a long line to help it. This is the reason a newspaper sets in columns rather than running a story edge to edge, and it is the same reason a printed menu is usually narrower than the card it is printed on.
On a phone, the screen makes this decision for you and it makes it well. On anything wider, you have to make it deliberately, which means putting a maximum width on the text column of a menu page and letting the empty space either side of it exist. Owners frequently read that empty space as waste. It is the opposite: it is what makes the writing readable, and it is exactly what a designed printed menu does with its margins.
How to choose the maximum
Set the maximum in a unit tied to the type, not to the viewport, so it moves when the reader changes their text size. A width expressed in character widths scales with the font; a width expressed in pixels does not. A dish name plus a one line description is a short unit, so a menu page can usually run a little wider than a long-form article without becoming hard to read, but it should still stop well before the edge of a desktop window.
The practical test is simple and does not require a tool: open the page on the widest screen you own, read three dish descriptions in a row, and notice whether your eye ever loses its place returning to the left edge. If it does, the measure is too wide.
The scale: tighter than you expect
A marketing page has one h1, a handful of h2s, and long paragraphs between them. A menu page has a course heading, then eight dish names, then another course heading, then nine more. The structure repeats, densely, dozens of times.
Why a marketing scale fails on a menu
A large-step scale, the kind where each level is noticeably bigger than the last, works when the levels are far apart on the page. On a menu they are two lines apart. Apply a big jump between a course heading and a dish name and the page turns into a staircase: your eye is dragged up and down at every course boundary instead of running smoothly down the list.
The fix is a smaller ratio between adjacent levels on menu pages than on the rest of the site, and then making up the difference with tools that cost no vertical space.
The tools that separate levels without size
Size is the loudest way to signal hierarchy and usually the least necessary one. Four quieter tools do most of the work on a menu:
Weight separates a dish name from its description at the same size, which keeps a dish to two tight lines instead of three loose ones. Case and letterspacing mark a course heading as a different kind of thing entirely; small caps with generous tracking read as a label rather than as a bigger dish. Color, used once, can mark a single class of item without changing the rhythm. And space above a heading is the strongest separator of all, because the eye reads a gap as a boundary before it reads anything else.
A useful discipline: allow yourself one size change per level and force every other distinction to come from these four. A menu page that observes it tends to read as calm, and a menu page that does not tends to read as a form.
Setting the scale in relative units
Whatever ratio you settle on, express it relative to the root size rather than in fixed pixels. This is not only a preference. WCAG success criterion 1.4.4 requires that text can be resized up to 200 percent without loss of content or functionality, and the W3C’s own understanding document notes that content satisfying this using only browser zoom, or using text sized in relative units, meets the requirement without any author-supplied resize control.
A scale built on the root size inherits any change the reader makes to their browser’s default text size. A scale built on pixels ignores it. On a menu page specifically, where a reader may well be in dim light, standing up, holding the phone at arm’s length, this is not a small difference.
Hierarchy inside a single dish
Below the course level, each dish is its own small piece of typesetting, and it usually holds two or three pieces of information: the name, a description, and sometimes a price or a mark.
The name and the description are not the same voice
A dish name is a label. A description is a sentence. Setting them at the same weight and size makes the reader do the work of separating them, which on a tasting menu with twelve courses is twelve unnecessary decisions.
The cheapest reliable separation is weight on the name and the muted text color on the description, at the same or a marginally smaller size. It costs no extra vertical space, it survives any wrap, and it holds up when a reader increases their text size, because both parts scale together.
The leader dot problem
A printed menu frequently runs a row of dots from the dish name to the price. It is a genuinely good device: it carries the eye across a gap that would otherwise be ambiguous.
Typing those dots as periods in the text is the wrong way to reproduce it on the web. A screen reader announces them. They break in an ugly place when the line wraps. And the number of dots has to change with the width of the container, which no static string can do.
The right way is to make the gap itself an element, give it flexible width, and paint the dots into its background as a small repeating image. The dots then fill whatever space is left, they are absent from the accessible name of the row, and when the row is too narrow to hold name and price on one line, the spacer collapses rather than producing a stray run of punctuation on a line of its own.
Marks, without advice
Many kitchens mark certain dishes on their menus. On the web, these are typographic objects like any other: they need to be distinguishable without relying on color alone, they need a legend the reader can find, and they need to be real text or an image with a text alternative rather than a glyph whose meaning lives only in the designer’s head.
We build the marks and the legend. We do not write them, and no website studio should: what a mark means on your menu is a decision for your kitchen and your own advisers, not for the people setting the page.
The mobile test that actually matters
“Looks fine on my phone” is not a test, because it is one phone held by someone who already knows what the page says.
Reflow, and the 320 pixel line
WCAG success criterion 1.4.10, Reflow, sets the real bar. It requires that content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions, at a width equivalent to 320 CSS pixels. The W3C explains the number directly: it corresponds to a viewport of 1280 CSS pixels wide at 400 percent zoom, which is the level of magnification a reader with low vision may genuinely be using.
That threshold is more demanding than it sounds on a menu page, because menus love two-column layouts, and a two-column layout that does not collapse is exactly what produces horizontal scrolling at 320 pixels. It is also more useful than a generic “make it responsive” instruction, because it is a number you can check: set the window to 320 and see whether anything makes the page scroll sideways.
Text spacing, which most menus fail first
Success criterion 1.4.12, Text Spacing, requires that no loss of content or functionality occurs when a reader overrides the page with line height at 1.5 times the font size, spacing after paragraphs at 2 times the font size, letter spacing at 0.12 times, and word spacing at 0.16 times.
A menu page is unusually vulnerable to this because menus are built out of tightly fitted rows. A dish row that assumes its name and price sit on one line will break when a reader adds letter spacing. A course card with a fixed height will clip its own contents when line height goes up. Neither failure is visible until someone actually applies the override, which is why it is worth building the page so that every row grows rather than clips, from the beginning.
The general rule that prevents almost all of it: never give a container that holds text a fixed height. Give it a minimum height if you need a rhythm, and let it grow.
Line height is a ratio, not a length
MDN’s line-height reference makes a point worth repeating here: a unitless number is preferred to a length, because a unitless value is inherited as a ratio and recomputed against each element’s own font size, while a length is inherited as a fixed value and can produce unexpected results in nested elements.
On a menu page, where a course heading, a dish name and a description are frequently nested inside one another at different sizes, this is the difference between a page that stays rhythmically consistent and one where a heading’s descenders collide with the line below it.
Contrast, and where menu pages break it
Success criterion 1.4.3 requires a contrast ratio of at least 4.5 to 1 for normal text and 3 to 1 for large text. The specification defines large as at least 18 point, or 14 point bold, and notes these correspond to roughly 24 pixels and 18.66 pixels respectively in CSS.
The three places a menu page usually fails
Muted description text is the first. A description set several steps lighter than the dish name reads as calm on a designer’s bright monitor and reads as absent on a phone outdoors. The fix is not to abandon the tonal difference but to measure it, and to pull the muted color back until it clears the ratio with the actual background it sits on, which is frequently a tinted panel rather than the page color.
Text on a photograph is the second. A dish name laid over an image has no fixed background at all, so it has no fixed ratio either. If the design needs text over an image, the text needs its own solid or near-solid backing, not a hopeful gradient.
Text inside a coloured fill is the third, and it is the one that survives review most often, because a brand color feels intentional. A color chosen for a logo has no obligation to clear 4.5 to 1 against white, and most do not. Marking a dish class in a brand color is fine; setting a dish description in one usually is not.
Measure, do not eyeball
There is no reliable way to judge a ratio by eye, and there is no need to: the ratio is a calculation on two color values, and browser developer tools will report it directly for any text on the page. The useful habit is to check the four or five text and background pairs a menu page actually uses, once, and then reuse those pairs everywhere rather than introducing new ones per section.
Putting it together: the order we work in
Reduced to a sequence, setting a menu page goes like this.
Decide the measure first, as a maximum width on the text column expressed in a unit tied to the type. Then choose the base size in relative units and build a scale with a smaller ratio than the rest of the site uses. Then assign the levels: course heading, dish name, description, mark, price, and make as many of those distinctions as you can with weight, case, tracking and space rather than with size.
Then build the row: name, flexible dotted spacer, price, with the description on its own line underneath in the muted color. Give nothing a fixed height. Then test: 320 pixels wide with no sideways scroll, 200 percent text size with nothing lost, the text spacing overrides applied with nothing clipped, and every text and background pair measured against its ratio.
Then, and only then, look at it and decide whether it feels like your kitchen. That last step is the one owners want to start with, and it is the one that goes best when everything underneath it has already been settled.
What this changes about updating the menu
A menu page set this way has a side effect that matters more day to day than any of the typography: changing it becomes a text edit.
Because the hierarchy lives in the stylesheet rather than in each individual dish, adding a course does not require re-laying anything out. Because nothing has a fixed height, a longer description in November does not break the row it sits in. Because the scale is relative, the page that was carefully set in spring is still carefully set in autumn after four seasonal changeovers, rather than drifting a little further from its own rules with each one.
That is the real argument for treating a menu page as typesetting rather than as design decoration. It is not that a well-set menu looks better on launch day, although it does. It is that a well-set menu is still well set on its fifteenth revision, and a menu assembled by hand in a page builder is usually not.
Sources
Frequently asked questions
What font size should a menu page use on a phone?
Set the body size in relative units and let the browser decide the base, rather than fixing a pixel size. WCAG requires that text can be resized up to 200 percent without loss of content or functionality, and a menu built in relative units satisfies that automatically, while one built in fixed pixels usually breaks somewhere on the way.
How long should a dish description line be?
Short enough that the eye finds the start of the next line without hunting. On a phone the screen decides for you; on a wide screen you have to decide, which is why a menu page needs a maximum measure on its text column rather than letting descriptions run the full width of a desktop window.
Do leader dots between a dish and its price work on the web?
They work if they are drawn rather than typed. A row of typed periods is read aloud by a screen reader and breaks when the text wraps. A repeating background image on a flexible spacer element gives the same printed look, stays out of the accessible name, and survives any wrap.
Should course headings be bigger than dish names?
They should be different, and size is only one way to make them different. Weight, case, letterspacing, color and the space above a heading all separate a course from the dishes underneath it, and on a narrow screen space and weight usually do the job with less disruption than a large size does.
What is the minimum contrast for menu text?
WCAG sets 4.5 to 1 for normal text and 3 to 1 for large text, where large means at least 18 point or 14 point bold, which the specification notes corresponds to roughly 24 pixels and 18.66 pixels. Decorative tints behind a menu are the usual place this quietly fails.
Does a menu page need a different type scale from the rest of the site?
It usually needs a tighter one. A marketing page has a handful of headings and long paragraphs; a menu page has dozens of short repeating units, so the distance between one level and the next has to be smaller or the page turns into a staircase.
Want a site like the one described here? Book a demo with MenuWebStudio.