The page is not 960 pixels wide

Learning to design rules instead of screenshots while rebuilding a fixed-width catalogue for an unpredictable web.

The first version of C62Y looked correct in exactly one place: the browser window beside the design file.

It was a catalogue for equipment that people carried into workshops and service calls. The original site had been built around a centered 960-pixel frame, a left navigation column, and product tables wide enough to make a laptop feel like the intended display. That was normal enough until the people using it began opening links from phones. On those screens, the page did not merely become small. Its assumptions became visible.

The useful part of a product row—the name, model, and availability—started beyond the right edge. Zooming in made the table readable but destroyed the surrounding context. The navigation occupied most of the first screen. Product photographs were delivered at desktop size and then reduced by CSS, so the smallest devices did the most downloading.

My first instinct was to make a mobile version. It was also my first wrong turn.

Two sites meant two incomplete sites

I sketched a compact navigation, removed secondary specifications, and imagined routing phones to a separate set of templates. The mockup looked tidy. The content model did not.

There was no reliable line between “mobile” information and “desktop” information. A technician on a phone might need the electrical specification I had classified as secondary. A customer on a narrow laptop might still want the full comparison table. Device detection answered a question about a user agent when the actual question was about available space, input, and intent.

The separate templates also created a synchronization problem. Every new product field would need two presentation decisions and two rounds of testing. The site was small enough that duplicating it felt cheap, which is often when duplication is most dangerous: the cost arrives later, one unremarkable edit at a time.

I abandoned the mobile site and started with the content.

The breakpoint came from the content

I printed the catalogue fields as a list, without layout. For each one, I wrote down why somebody needed it and what it depended on. That produced three useful groups:

  • Identity: product name, model, photograph, and status.
  • Decision: the handful of specifications that distinguished one model from another.
  • Reference: complete dimensions, compatibility notes, and documentation.

The groups were not screen sizes. They were a reading order.

In the widest layout, identity and decision information could sit beside one another while the reference material used the full width below. As the measure narrowed, the columns stopped being useful before they became physically impossible. That point—not the width of a popular phone—became the first breakpoint.

The CSS was modest: percentage widths, a maximum readable measure, flexible images, and media queries that removed floats when the content began to collide. The navigation changed from a permanent column into a compact list above the catalogue. Comparison tables were the stubborn part. Rather than shrink their type until it technically fit, I gave the most important columns priority and allowed the full table to scroll within its own region.

.catalogue {
  width: 92%;
  max-width: 60rem;
  margin: 0 auto;
}
 
.product-image {
  max-width: 100%;
  height: auto;
}
 
@media (max-width: 42rem) {
  .sidebar,
  .products {
    float: none;
    width: auto;
  }
}

The code was not the important change. The important change was that the page no longer had one correct shape.

The early build treated flexibility as permission to let everything stretch. On a large display, line lengths became exhausting and product images expanded beyond the detail available in their source files. On a small display, every piece of secondary metadata stacked into one very long column.

Responsive work still required art direction. It simply moved art direction from fixed coordinates to relationships:

  • Text needed a maximum measure even when the container had room.
  • Images needed multiple derivatives rather than one large file scaled everywhere.
  • Touch targets needed space that mouse-oriented links had never required.
  • Source order had to remain sensible when columns disappeared.
  • Hiding content could not be the default response to a difficult layout.

I also learned to test between the planned widths. A layout designed at 320, 768, and 1024 pixels could fail spectacularly at 611. Slowly dragging the browser edge was crude but revealing. Every awkward interval exposed a rule that belonged to a screenshot rather than to the content.

The photograph was part of the layout

The catalogue initially shipped one high-resolution product photograph per item. It was visually sharp and operationally wasteful. A fluid image only changes the space it occupies; it does not reduce the bytes already transferred.

We added server-generated image sizes and selected a conservative default for older browsers. The result was less glamorous than a new layout, but it made the catalogue materially more usable on the connections for which the redesign mattered. It also started a habit I kept: a responsive interface is incomplete if its delivery remains fixed at the largest case.

I made mistakes. Some early breakpoints were suspiciously close to device widths even though I claimed they were content-driven. The compact navigation briefly depended on JavaScript, which meant a loading error could hide the links entirely. I corrected it so the links existed in the document and scripting only improved their presentation. Progressive enhancement stopped being an abstract preference the first time my own code made the simpler experience unavailable.

Browser support became a capability map

My first test spreadsheet had browsers across the top and pages down the side. Each cell said pass or fail. It was useful for tracking work and weak at explaining what a failure meant.

C62Y depended on capabilities with different consequences. Media-query support enabled the rearranged layout. A browser without it could still receive the complete single-column document. JavaScript enabled the compact navigation control; without it, the link list remained visible. Newer image-selection approaches could reduce transfer for some browsers while every browser still needed a dependable source.

I reorganized the matrix around capabilities and tasks:

  • Read product identity and decision information.
  • Browse categories and follow every navigation destination.
  • Compare products with headers and values intact.
  • Open manuals and reference material.
  • Use the page with keyboard, touch, increased text, and no script.
  • Receive a complete baseline without the enhanced layout.

Browser names still mattered because implementations contained real defects. They stopped defining the product. A browser could miss one enhancement and continue supporting the task.

This made support less theatrical. I did not try to make every browser produce the same screenshot, and I did not use progressive enhancement as permission to ignore older environments. I defined the complete experience they received and tested it.

The distinction was especially important during a period when mobile browsers varied widely. “Mobile” was not one engine or one capability tier. A feature test said more than a device label, and a meaningful baseline mattered when the test failed.

I had been testing mostly on a laptop over a fast local connection. The responsive layout felt quick because the CPU, network, and cache were generous.

On a modest phone with an empty cache, the same page behaved differently. The large photograph delayed useful content. The navigation script initialized after the user could already see the page. A font choice added another request and changed wrapping after it arrived. The comparison enhancement performed DOM work across rows that native layout had already handled.

I wrote a simple first-view inventory: document, styles, images, fonts, and scripts in the order the page discovered them. The inventory did not yet use the industry’s later performance-budget language. It had the same practical purpose. Every required resource needed a reason to compete before the primary task became usable.

The process changed implementation order. I removed optional script before compressing required markup. I reduced and resized the dominant image before tuning tiny icons. I returned to a system font stack after realizing the chosen web font cost more than the small catalogue’s typography gained under the target conditions.

The visible design changed because delivery evidence changed. Performance was not an engineering pass over a finished composition. It participated in choosing the composition.

I kept the laptop test. A page can fail on a large fast display through line length, excessive stretching, and pointer assumptions. The phone added constraints; it did not become the new universal reference.

Abandoning a separate mobile site solved only the presentation duplication. The catalogue data still contained fields whose labels, units, and absence rules varied by template.

I normalized identity, decision, and reference information before the templates received it. A measurement carried its unit and optional condition. A missing value distinguished not applicable, not supplied, and unverified. Category definitions named which properties belonged in the decision summary.

The wide and narrow layouts consumed the same normalized product. They could emphasize and arrange it differently without making separate claims about what the product contained.

This mattered when the catalogue changed. Adding a new decision property required one content-model choice, one validation path, and presentation in the relevant regions. It did not require remembering that a reduced mobile template existed elsewhere.

The model also improved non-page outputs. Search results could weight identity and summary. Print could include complete reference information. A feed or export could use the same canonical labels. Responsive design had forced a content architecture that made the whole system less dependent on one template.

I began to see duplicated presentation decisions as a warning. When two layouts needed different source content, the difference should represent a real product rule, not an unexamined consequence of their widths.

The comparison needed a correction

My first account of the table said that the most important columns received priority. That was only part of the final answer and, stated carelessly, implied that the interface chose which products mattered.

The category model prioritized rows—the properties that supported the decision. Product columns belonged to the reader’s selection. On a narrow screen, the complete selected table remained available inside its own horizontal region. A focused picker could reduce the selection, but the viewport did not silently remove alternatives.

That distinction came from using the comparison rather than admiring its responsive transformation. Stacking products into cards preserved values and destroyed cross-product scanning. Hiding columns preserved the grid and changed the apparent choice. Local horizontal movement was inelegant and more honest.

I kept this correction in the story because it represents how the project actually developed. “Content-driven” did not mean I found the correct rule immediately. It gave me a way to evaluate a rule against the task and revise it when the task got worse.

The table became an early warning against responsive designs optimized for screenshots of responsiveness. A tidy narrow layout can be a worse tool.

As exceptions accumulated, I kept a plain document listing each responsive rule and its reason.

Examples included:

  • The main measure stops growing when body text becomes uncomfortable to scan.
  • Identity precedes decision information in source order.
  • Identity and decision can share a row only when neither drops below its useful measure.
  • Reference information moves later and remains complete.
  • The global navigation is visible without enhancement.
  • Comparison overflow belongs to the table region, never the page.
  • The initial image supports recognition; high-detail inspection is requested explicitly.

The ledger was not a CSS specification. It connected code to product intent. When a breakpoint moved, the reason could stay. When a new layout technique became available, I could preserve the relationship without preserving the implementation.

It also exposed contradictions. One rule said reference information was complete; another early rule hid reference fields below a narrow breakpoint. The conflict was easier to see in language than across several stylesheets.

This became a precursor to later decision records and component contracts. I did not need heavy process. I needed a durable place where the project could remember why its rules existed.

Release checks followed the task

The old release process verified that files had uploaded. The responsive release needed to verify that the experience represented one coherent version.

I added a small set of smoke checks after building a release directory and before making it active:

  • The catalogue index rendered its navigation and category links.
  • A product page contained identity, decision, and reference headings.
  • Image URLs existed in the generated manifest.
  • A comparison URL preserved the selected products and table headers.
  • An unknown route produced the intended response.
  • The stylesheet and page named the same build identity.

The checks did not prove layout quality. They prevented a partial upload, missing derivative, or stale template from making the reviewed rule set impossible to inspect.

Visual review used narrow, intermediate, wide, increased-text, keyboard, and throttled scenarios. I kept notes about known limitations instead of treating a screenshot approval as universal success.

Shipping responsive work made deployment part of design continuity. If HTML from one release could reference assets from another, the browser was not receiving the system I had reviewed.

I thought the growing variety of screens would eventually settle into a manageable set of common widths. It did not, and the rule-based approach became more valuable for reasons I had not anticipated: split-screen windows, zoom, embedded browsers, large displays, new input modes, and user preferences.

I also overestimated how often layout required JavaScript. Better use of normal flow and CSS removed several measurement scripts. Later platform features would remove more.

At the same time, I underestimated responsive images. The conservative derivative approach improved C62Y, but the problem deserved richer browser-native selection that was still developing. When srcset, sizes, and picture became practical, they solved real information gaps between layout and request discovery. The early lesson did not make the early mechanism final.

The most important prediction was not about a technology. I expected maintaining one flexible system to be harder than maintaining a desktop site plus a small mobile version. The flexible system demanded more reasoning at the start and eliminated a growing class of synchronization work afterward.

That trade was repeated throughout my later projects: make the state and constraints explicit once, then stop repairing the disagreement between parallel approximations.

Width was the visible problem and not the only variable C62Y exposed.

The page could have space and lack bandwidth. It could be wide and zoomed. It could be connected while an image source failed. It could render the current HTML with stale cached CSS. It could receive keyboard input in a layout designed with a pointer in mind.

I started describing the interface as a negotiation among content, capability, and constraint. Viewport width was one constraint. Network, input, script execution, source completeness, and time were others.

This kept responsive design from becoming a collection of media queries. A media query could rearrange the page and could not decide whether local intent was synchronized, whether live data was fresh, or whether a release artifact was complete.

Those later problems would need different mechanisms. They shared the same failure pattern: an interface designed around one ideal condition making a stronger claim than the system could support.

From artifact to system

Before C62Y, I thought the main design artifact was the finished page. Afterward, it was the set of rules that allowed a page to remain understandable as its conditions changed.

That distinction reached beyond screen width. A system could be fast or slow, connected or offline, fresh or stale, controlled with a mouse or a keyboard. Each condition asked the same question: had I designed only the ideal picture, or had I designed how the product behaved?

The page was never 960 pixels wide. That was only one measurement of one window at one moment. The actual material was variable from the beginning. I had simply been drawing over it.