Breakpoints: one design, many screen sizes
A breakpoint is not a device width. It is the width at which your layout stops working, and the only way to find it is to shrink until something gives.
The idea
Nobody decided that 768 pixels is special. It is a number that circulated because an old tablet had it, and designs kept inheriting it long after the tablet stopped existing. Your layout does not care what device it is on. It cares whether eight table columns still have room to be read.
So find the breakpoints the way a carpenter finds a weak joint: put weight on it. Drag the window narrower and watch. Somewhere a row of filters wraps into an ugly second line. Somewhere a chart legend collides with its plot. Those widths are your breakpoints, and they are different for every region on the page, because every region needs a different amount of room.
When a region reaches its width, it has a small set of honest options: reflow, reorder, collapse into a disclosure, swap its pattern, or be dropped. Which one it takes is not a technical question. It is a ranking question, and the ranking is the thing you should have written down before you opened the design tool.
Shrink it until something breaks
One dashboard, four regions. Rank them, mark the one the screen exists for, then pull the width down and watch where it gives. Overflow and clipping are drawn, not hidden.
Everything is full fidelity, and the chart and table still fit side by side. Press shrink, or drag the slider, and watch for the first width where something has to change.
How it works
Start from the content, not the device. Every region needs a width, and that width is arithmetic you can do on a napkin: how many columns, how wide is each, how many gaps between them. The demo above uses these four sums, and nothing else.
what each region needs, derived from its own content
header title 240 + 3 actions (52 each) + gaps 24 = 420 px
filters 5 controls (132 each) + 4 gaps (10 each) = 700 px
chart plot 300 + gap 14 + legend 118 + padding 28 = 460 px
table 8 columns x 78 = 624 px
and the floor below which even the reflowed version is broken
header title 160 + overflow menu 40 = 200 px
filters 1 control 132 + padding 8 = 140 px
chart 12 month labels x 24 = 316 px
table 4 priority columns x 78 = 312 px
Those eight numbers, plus a gutter of 24 on each side, produce every breakpoint the demo finds. Notice that not one of them is a device width, and that they are all different, because the regions are all different.
- Write the priority list first. Rank the regions before you draw anything. The ranking is the only artifact that survives every screen size, and it is what tells you what collapses first.
- Name the invariant. One or two elements exist for the reason the screen exists. On a revenue dashboard that is the trend. On a checkout it is the total and the pay button. The invariant never collapses and is never dropped, at any width.
- Shrink until a region falls below its width. That is a breakpoint. Write down the number you actually observed, not the number you expected.
- At the breakpoint, pick a move. Reflow, reorder, collapse, swap the pattern, or drop. The demo applies a simple policy: rank one and the invariant reflow and stay visible, everything else collapses into a disclosure.
- Cap the disclosures. Two collapsed regions is a compact screen. Three is a menu wearing a dashboard costume. Past the cap, the lowest ranked region is dropped instead.
- Below the floor, only the invariant survives. Everything else collapses rather than shipping clipped. The invariant stays and pays the cost visibly, with a scroll or a clipped label, because you decided it was worth it.
Worked through at a common phone width:
viewport 390 gutters 24 + 24 content C = 342 px
420 > 342 header has broken
700 > 342 filters has broken
460 > 342 chart has broken
624 > 342 table has broken all four, at one width
so the ranking decides, not the arithmetic:
1 header protected by rank reflow title + overflow menu floor 200, fits
2 chart marked invariant reflow legend under the plot floor 316, fits
3 table neither collapse "open table" bar
4 filters neither collapse "filters" bar
two disclosures. that is the cap, so nothing is dropped.
now pull it to 360 C = 312, and the chart's floor of 316 is gone
the chart is the invariant, so it stays and pays:
12 month labels need 12 x 24 = 288 px, the plot has 312 - 28 = 284.
one label clips, and the demo draws the clip instead of hiding it.
unmarked, the chart would have collapsed to a summary line, the edge
would have stayed clean, and the screen would have lost the one thing
it exists for. that is the trade the invariant is for.
Two constraints sit underneath all of this and change layout rather than only spacing. A touch target wants roughly 44 px square, which is why a collapsed region in the demo is 52 px tall rather than the 24 px a text link would take. And the comfortable thumb arc on a held phone is the bottom two thirds of the screen, which is why primary actions migrate downward on small layouts while they sit top right on a desktop.
When to use it
Five moves, and the honest price of each. A senior answer names the move and the price in the same breath.
| reflow | Columns become rows, controls wrap, a sidebar stacks. The content is all still there. | Height. The page gets longer and the fold moves, so something that was visible is now a scroll away. |
| reorder | The stack follows the priority list rather than the source order. | The two layouts stop matching. Anyone who learned the wide one has to relearn the narrow one, and focus order has to be kept sane. |
| collapse | A region becomes one labelled disclosure: a filters button, an expandable row, an accordion. | A tap, and invisibility. What is behind a disclosure is not skimmed, not compared, and often not found. |
| swap the pattern | A left nav becomes a bottom bar. A hover menu becomes a sheet. A table becomes a card list. | Two systems to build and keep in sync, and a real risk that the two stop offering the same set of actions. |
| drop | The region is not rendered at this size at all. | Someone loses it. Legitimate only when it is a decision: the content must be reachable somewhere, and you must be able to say where. |
The hard cases, and a defensible answer for each
- A table with twenty columns Three answers, and you should be able to state the cost of each. A priority column set with the rest behind a row expansion keeps scanning intact but hides comparison, so people expand row after row. A card per row makes every record readable but destroys column comparison entirely, which is usually why the table existed. Horizontal scroll with a frozen key column preserves the whole grid but hides that the columns exist, and on touch it fights the page scroll. Ask which columns the person actually reads first, and whether the job is scanning down a column or reading across a row. Scanning down wants the frozen key column. Reading across wants cards.
- Ten levels of nested replies Indentation runs out long before the nesting does. At 16 px per level, ten levels have eaten 160 px of a 342 px column, and the deepest replies are a ribbon. So depth flattens: past two or three levels, render a flat thread where each reply carries a small parent reference and a jump link back to it. You trade the shape of the conversation for its readability. Keep the first two levels indented, because that is where most replies live and it is what makes a thread feel like a thread.
- Sixty settings, discoverable on a watch and on a desktop Hierarchy is a browsing tool and it needs room. Once the screen is small enough, search beats hierarchy, so the small surface leads with a search field and a short recents list rather than a compressed tree. And the watch is not the same page squeezed: it is a chosen subset, the six settings someone would plausibly change while standing up, with everything else answered by "open this on your phone". You now maintain a subset decision, and it will drift as settings are added. Write the rule down so the next person knows what earns a place.
- A foldable, open and closed The two postures are one session, not two visits. Somebody is mid task when the device changes shape. So the thing to protect is continuity: scroll anchor, form input, selection, playback position, and the identity of whatever was in focus. The layout of either posture matters less than the fact that nothing was lost between them. Continuity means state that outlives a remount, which is a real engineering commitment. Also treat the hinge as a region you cannot place a control across.
- The same dashboard on a 27 inch monitor and on a phone The phone is not the desktop shrunk. It is the same priority list, truncated honestly. The wide screen can afford rank one through four side by side and a wall of context. The phone earns rank one and rank two, gives rank three a disclosure, and sends rank four somewhere else with a link. If you cannot say which is which, you do not have a phone layout problem, you have an unranked design. The wide layout tempts you to add regions because there is room. Every one of them lands on the priority list and eventually has to be answered for on the phone.
The trade-off in one line: a breakpoint costs you a second layout to build, test and keep truthful. Add one only when a region has actually broken, and let the design carry as few of them as it honestly needs.
Watch out for
- Reciting device widths. 768, 1024 and 1280 describe hardware that mostly no longer ships, and they tell you nothing about whether your eight columns fit. Derive the number from content, then check it against the real traffic in your analytics. If a breakpoint lands inside a dense cluster of real viewport widths, move it, because half your users are meeting the layout exactly where it changes.
- Overflow that happens to you. A table that just runs off the edge, or an
overflow-x: hiddenon the body that quietly amputates the last two columns, is not a decision. It is a bug that looks like a layout. Dropping content is allowed. Losing it is not, and the test is whether you can name where it went. - Treating touch targets as spacing. A 44 px target is a layout constraint, not a padding preference. Six icon buttons at 44 px need 264 px plus gaps, which is most of a phone's content width, so the row itself has to change: fewer actions, an overflow menu, or a bottom bar. Discovering this at the padding stage means rebuilding the row.
- Collapsing the reason the screen exists. A generic rule such as "hide secondary content under 480" will happily hide the balance on a banking screen, because the rule does not know what the screen is for. That is what the invariant is: a named exception the rule is not allowed to touch.
- Testing only at your own breakpoints. The interesting widths are the ones just either side of a break, plus the ones you never chose: a 320 px phone, a browser at 200 percent zoom, a user with a large text setting, a split-screen tablet at 507 px. Zoom and text scaling move content into the same collapse ladder that width does, so a layout that only survives at five named widths is not responsive, it is five layouts.
Worked example
A whiteboard prompt: design an operations dashboard that runs on a 27 inch wall display in a control room and on a phone in an engineer's pocket. Most candidates start drawing boxes. Start with a ranked list instead, out loud: incident status first, because the phone exists to answer "is anything on fire". Then the active alert list. Then the chart. Then the twenty column host table. Then say the sentence that separates a mid answer from a senior one: the invariant is incident status, and it is present at every width, at the top, without a tap.
Now walk one design through three sizes and name the moves. On the wall display, everything is rank one: four regions side by side, the host table full width underneath, nothing collapsed, because there is room and the room is the point. On a laptop the table loses its side-by-side neighbour and moves to its own row, and the throughput chart drops its legend under the plot. That is a reflow and a breakpoint you found by shrinking, at whatever width the legend and the plot stopped both fitting.
On the phone, incident status stays, full and first. The alert list stays, reflowed into rows rather than a grid. The throughput chart collapses to a single line with a sparkline and a delta, because the number matters on a phone and the twelve month shape does not. The host table is dropped, and this is the part to say deliberately: it is not hidden behind a disclosure, it is not scrolled sideways, it is a link that says "open the host table" and routes to a screen built for it. Twenty columns on a 342 px column is not a layout problem you can solve, it is a screen you should not have tried to fit.
If the interviewer pushes, they will push here, so have the cost ready. Dropping the table means an engineer paging at 2am cannot check a host's disk usage in place, which is a real loss. You take it because the alternative, four columns behind a row expansion, is a screen where nobody finds the fifth column anyway, and because the link keeps the content reachable in one tap. Naming what you gave up is what makes the choice read as a decision rather than an omission.
Check yourself
Your filter row wraps to two lines at 747 px, and your table starts overflowing at 671 px. Where should the breakpoint go?
On the phone layout of a banking app, the account balance no longer fits beside the account name. What is the right move?