When the semantic <section> element met style concl’d (resumed)

Previously on the CogitActive Saga:
So, padding‑left or margin‑left? Two properties that, at first glance, seem to do the same thing… until you realize they don’t. And that, dear reader, is where I’ll leave you hanging — because this question turned out to be anything but trivial, and it deserves a post of its own.

Starting where the stopped.

This post picks up where the interrupted one left off. This means that it starts with an H3—not an H2. A bit of a semantic faux pas for someone who usually obsesses over proper structure, but the heading levels had to match.

Implementing indentation

Which CSS property? (solved)

As the ones who follow this blog know, choosing between padding-left and margin-left to indent nested sections quickly spiraled into a full-blown investigation. A single question, deceptively straightforward, opened the floodgates to a cascade of posts, each peeling back another layer of complexity. From semantic nuance to rendering quirks, the trial refused to resolve itself, and I found myself flipping positions more often than the AI witnesses I interrogated. The jury remained silent, and I… well, I nearly lost my sanity to the pursuit of a verdict.

At long last, the gavel struck, breaking the silence that had stretched into eternity. Dragged through labyrinths of logic and stranded in corridors of doubt, I wrestled order from chaos until the interminable suspense finally yielded to resolution. After countless detours and reversals, the tangled trial did not dissolve into endless uncertainty but, against all odds, culminated in the resounding clarity of a verdict hard‑won 1 — a verdict that allowed me to close the chapter on indecision and, at last, resume this long‑delayed post.

Now, no matter which side of the courtroom you imagine — padding‑left or margin‑left — one truth emerged with undeniable clarity: neither was the rightful heir to the task of indentation. Both faltered when measured against the standards of modern practice. In the evolving landscape of CSS, the old ways of hard‑coding “left” or “right” no longer suffice.

Instead, the mantle passes to logical properties, a more enlightened solution that bends gracefully to the flow of language and layout. With tools like padding‑inline‑start and margin‑inline‑start, indentation ceases to be rigid and provincial; it becomes adaptive, responsive to whether text runs left‑to‑right, right‑to‑left, or even vertically. In this way, structure remains consistent, accessible, and true across scripts and orientations — a quiet triumph of design that transcends borders and directions.

Which unit?

At first glance, this seemed trivial. After all, indentation is just a matter of shifting content to the right—how complicated could that be? But as with everything in this endeavor, the devil was in the details. The choice of unit would affect not only the appearance of the indentation but also its scalability, responsiveness, and semantic fidelity.

px? Hardly. Absolute values are rigid, blind to context, and deaf to the rhythm of a responsive layout. Indentation must breathe with its surroundings, and only relative units can rise to that demand — scaling, adapting, and flowing with the environment. From there, the choice appeared straightforward: em or rem, the familiar pair that so often accompany padding and margin. And yes, I did choose one — though not the one the AI had so confidently prescribed. That small act of defiance set off a chain reaction, a detour, and ultimately a new chapter in this series, the tangled tale recounted in the post below.

Expressing sizes, such as margins and paddings, in em means they are related to the font size, and if the user has a big font (e.g., on a big screen) or a small font (e.g., on a handheld device), the sizes will be in proportion.Chris Lilley

Yet even as I wrestled with those familiar units, another contender crept in almost by accident. What began as a casual dismissal revealed itself as a revelation: the humble %. Not even listed among MDN’s relative length units (strictly speaking, it isn’t a “unit” at all), this oddball mirrors the width of its container, shrinking and expanding with surprising elegance across devices. No media queries, no extra calculations — just proportional responsiveness. Where em and rem offer only partial flexibility, % seemed effortlessly fluid. But as with every elegant solution, its grace concealed a catch…

Box 1: Descent through versions

Like Inception (the movie), each draft was another layer of the same dream — a time capsule of what I believed at that moment. The second version was written before the Hydra fight, yet after I had settled temporarily on padding‑left (as a stopgap, not a verdict). In it, I restated the catch with % (see below) and wondered whether it might even outperform the usual suspects: em and rem.

That draft reaffirmed that % behaved differently depending on whether indentation relied on padding‑left or margin‑left. It explained that % is always relative to the parent element — the container, the box itself — and the text contrasted how each property shaped the box’s width:

  • with padding‑left, the box’s width remained stable, but
  • with margin‑left, the available space shrank, as nested sections were pushed against the container’s edge.

Percentage values are always relative to the immediate parent, which can create unexpected results in nested layouts.

From this perspective, percentage‑based indentation appeared unstable with margin‑left, since each level recalculated against a narrower parent. % was not a viable option there, and I almost patted myself (pun intended: patted/padded) on the shoulder for choosing padding‑left and keeping % in play. Not that I had chosen padding-left over margin-left for this reason, but the pieces seemed to fit.

Yet both the first and second drafts were dreams — nightmares, in fact. The reality was distorted by a belief: padding‑left leaves the box’s width intact. It does not! The awakening was harsh.

The full collapse of that illusion is recounted in Through CSS confusion toward insight, the follow-up post after the Hydra fight.

Now I know: padding‑left is not immune, and percentage‑based indentation is unstable no matter which property I choose. The question remains — should I still ask whether % can outperform the usual suspects: em and rem? And what, exactly, is my quarrel with this progressive shrinking that keeps haunting the staircase of my layout?

At first glance, % seemed to shine brighter than its familiar rivals, em and rem. Where those two offered only partial flexibility — one tied to the font of its parent, the other anchored to the root — % promised something more fluid, more alive.

Percentages shine for fluid layouts.

Imagine my theme’s column at its full width: 525 pixels 2. Now, let’s pretend that % is stable, even though it is not: in reality, each nested section’s box shrinks, recalculating the percentage against a narrower parent. Suppose I chose a generous 10% indent, far larger than I would in practice but convenient for easy arithmetic. Under those conditions, a column of 525 pixels would yield 52.5 pixels of indentation. The first nesting: 52.5. The second: again 52.5. But here comes the beauty. On a phone, or at least in its DevTools emulation, the column contracts to 340 pixels. And with %, the indent contracts with it — 34 pixels each, instead of 52.5. No media queries, no recalculations, just a smooth adaptation to the screen’s rhythm.

Contrast that with rem. Fix the indent at 3 rem, and you get 48 pixels — whether the column is 525 or 340 px wide. Rigid, unyielding, deaf to the environment. % alone seemed to breathe with the layout, shrinking and expanding in harmony with its container.

CSS percentage units are fundamental building blocks for creating responsive, flexible layouts that adapt to different screen sizes and container dimensions. Unlike fixed units like pixels, percentage values are relative to their parent element, making them essential for modern web design.CodeLucky

On very large displays, % may spiral out of control. Let’s stay with the 10 % indent example. What happens on an HD or full‑HD desktop monitor? At 1280 pixels wide, the indent swells to 128 pixels; at 1980 pixels, it balloons to 198 pixels — far more than is visually comfortable. What feels balanced on a phone or laptop can become comically oversized on a desktop monitor or TV.

“Without constraints, % risks breaking the visual rhythm at the high end. But with your theme, that doesn’t worry you, does it?”
“You’re right. It fixes the maximum width of the main content column at 525 pixels, and that largely neutralizes the ‘super‑big screen’ problem.”

CSS percentage units have excellent browser support and have been part of CSS since the early days. All modern browsers support percentage units consistently, making them a safe choice for production websites.CodeLucky

Indentation is about spatial relationships, and % expresses space in direct relation to the parent box. It feels natural: the child section’s offset is literally tethered to the dimensions of the container that holds it. That metaphor resonates with the semantic idea of hierarchy — each level inheriting its measure from the one above. By contrast, I never felt fully convinced by the notion of using a font‑based unit. With rem, spacing is derived from typography, as though indentation were a matter of letterforms rather than layout. For pure geometry, % seemed the more fitting voice.

“But what about weaknesses?”

This elegant solution must carry a shadow, otherwise % would already be praised to the sky and adopted everywhere. As far as I know, neither is true. Indeed, % is rarely mentioned in guides and barely documented in references. That lack of community consensus makes it harder to trust. While em and rem are well‑established, % feels like uncharted territory — promising, but lonely.

But the strongest con, the practical “killer” counterargument, I could think of is accessibility and readability under user font scaling. When a reader increases the base font size — through browser zoom or OS accessibility settings — a % indent remains fixed in pixels. It does not grow with the text. The result can be cramped lines, broken rhythm, and a hierarchy that collapses just when clarity is most needed. For users who rely on larger text, % can undermine readability instead of supporting it. This is the decisive flaw, the one that outweighs proportional geometry whenever accessibility matters more than elegance.

“And what about your issue with shrinking? Isn’t that the real catch?”
“Well, it is. And here lies the irony. Progressive shrinking could have been a clever feature, conserving space as the hierarchy deepens. I even toyed with that idea once 3. But in practice, it broke the rhythm, muddied the hierarchy, and demanded what the French call le compas dans l’œil — a compass in the eye.”
“But wait, back then you rejected the idea of stepping down from 2 em to 1.5 em to 1 em — 30 pixels, then 22.5, then 15. That was a real distortion, a staircase warped beyond recognition. But here, with a 10 % indent on a 525‑pixel column, we’re talking 52.5 pixels, then 47.25. And you’d probably choose less than 10 % in practice anyway. That kind of shrinking is nothing. It’s barely perceptible.”
“I see your point. A reader might not even notice the difference. The question is whether that small fracture in the rhythm matters more than %’s responsiveness and conceptual harmony. That’s the balance I’m still weighing — especially with accessibility under user font scaling in mind.”

How much is enough?

The next question is simple to ask yet difficult to answer: how far? Time to choose the depth of each step. Too shallow, and the hierarchy blurs into a flat wall of text. Too deep, and the page collapses under the weight of wasted space, each line retreating like a timid echo. Somewhere between these extremes lies the elusive balance: clarity without excess, rhythm without rigidity.

Deep enough to reveal hierarchy, yet mindful that every pixel is precious.

From wild guessing…

For the sake of telling this story, I will measure in pixels. Not because they hold the crown — far from it, as you should already know — but because they give me a tangible scale, a ruler against which the other contenders can be judged. With px as the baseline, the abstractions of rem and % become easier to grasp: 1 rem equals 16 px, which, within my 525‑pixel column, translates to just over 3% 4. In this way, px becomes the lingua franca, the bridge that allows me to move forward even though I have not yet decided on the unit to adopt.

The challenge, then, is not mathematical but perceptual. What indentation feels right to the eye? Sixteen pixels — the quiet voice of 1 rem — may whisper hierarchy, subtle yet legible. Fifty‑two and a half pixels — the bold gesture of 10% — may shout it, carving a canyon between parent and child. Beyond that, indentation risks becoming theatrical, a gesture so grand it distracts from the text itself. The art lies in choosing a measure that guides the reader’s gaze without stealing the stage.

Web designers often struggle with how to size content and space elements consistently. Issues like choosing a max container width, balancing section padding vs. margins, setting text sizing, and spacing stacks of text and images can feel like a minefield.Kerri Cuthbert

“What about 40 px? That’s the default padding‑left for lists.”
“Which makes it 2.5 rem, doesn’t it? And, for the record, 7.6190476190476190476190476190476 % of my 525‑pixel column.”
“Do you really want to litter your stylesheets with decimals that stretch on forever?”
“Nope. There must be a better way…”

Box 2: 8-point grid system

The 8‑point grid system is a spacing and layout methodology widely adopted in digital product design to create consistent, scalable, and visually coherent interfaces. It is based on the principle that UI elements—such as margins, padding, component dimensions, and icon sizes—should be sized and positioned using increments of 8 pixels. This regularity establishes a predictable rhythm across the interface, reducing visual noise and improving the clarity of spatial relationships.

A key advantage of this system is its ability to streamline collaboration between designers and developers. By adhering to a shared set of spacing values (e.g., 8, 16, 24, 32 px), teams reduce ambiguity during implementation and accelerate design‑to‑development handoff. The system also scales effectively across devices with varying screen densities, making it particularly suitable for responsive and multi‑platform products.

In practice, the 8‑point grid influences a wide range of design decisions. Common examples include button heights of 48 px, icon sizes of 24 or 32 px, and internal padding values that follow the 8‑pixel rhythm. While typography often requires finer granularity, many teams pair the 8‑point grid with a 4‑point sub‑grid to accommodate more precise typographic or micro‑layout adjustments without compromising overall consistency.

Although alternative systems exist, the 8‑point grid remains popular due to its balance of simplicity and flexibility. It provides enough structure to enforce coherence while remaining adaptable to diverse interface patterns. As a result, it has become a foundational tool in modern design systems and component libraries, supporting both aesthetic uniformity and efficient production workflows.

Apple’s Human Interface Guidelines and Google’s Material Design both recommend using an 8-point grid system.Kerri Cuthbert

They were there, scattered like footprints: 0.5 em, 1 em, climbing steadily up to 3 em. em! Most were em indeed, with only a handful daring to be rem or px, and fewer still venturing into %. Some values even dipped into the negative, as if retreating rather than advancing. None of them spoke to my use case. As you may recall from a previous post, even the default 40 px padding‑left for lists had been annihilated to zero, erased without ceremony. And then, tucked away, I discovered a 65 px margin‑left for .comment‑body. Closer, perhaps, to what I sought — but still not the answer.

…to a practical approach

Don’t be afraid to experiment! There’s no one-size-fits-all approach to margins and padding. The best way to find what works for your website is to try different combinations and see what feels right.Pratiksha Ekbote

Do you recall my footnote #2? It spoke of a technique designed to keep line length within reach: no more than 80 characters, so that readers — especially those with visual or cognitive challenges — can follow the text without losing their place. Yet the story goes deeper. You may have come across the oft‑repeated claim: The ideal line length for readable text is 50–75 characters per line (CPL), with 66 CPL as the sweet spot. Within this span, readers are said to process information with ease, neither overwhelmed by long stretches nor interrupted by constant breaks. Too long, and the eye falters in its return to the next line. Too short, and the rhythm collapses into endless scrolling or paging. But it is worth remembering that this wisdom springs from traditional research in print, and from one influential source in particular:

Bringhurst, R. (1992). Horizontal Motion. The Elements of Typographic Style, pp 25-36. Point Roberts, WA: Hartley & Marks.

Digital design often borrows this wisdom wholesale, forgetting to adapt it to the screen. As the Wikipedia article on the subject matter cautions, Screen reading poses additional challenges, making the adoption of traditional line length research to the digital format problematic. Yet research specific to digital text has begun to fill this gap. One study explored how line length interacts with reading speed, comprehension, and scrolling behavior, and found that a medium line length — around 55 characters per line — produced the best balance: faster reading without sacrificing understanding. So, rather than relying on the 66 CPL inherited from print traditions, I will take the 55 CPL identified in this study as my guide:

Dyson, M. C., & Haselgrove, M. (2001). The influence of reading speed and line length on the effectiveness of reading from screen. International Journal of Human‑Computer Studies, 54(4), 585–612.

Indentation always comes at a cost: every step inward reduces the width available for your words. Reduce it too much, and your lines become too short — choppy, tiring to read, and visually unbalanced. I wanted a system that would keep even my deepest nested headings within the bounds of readability. Instead of choosing indentation values by eye, I think of them as part of my CPL budget. How much can I spend from my 525-px fixed amount of horizontal space without ever dropping below the ideal 55 CPL?

Designing indentation that respects CPL.

The first step was to measure the average character width in my theme. With a little help from AIs, I estimated it from the font‑family and font‑size defined in my stylesheet: about 7.5 px per character. Multiply that by the ideal 55 characters per line, and you arrive at a sweet spot of 412.5 px. Against my 525‑px column, that leaves 112.5 px of “space to spend” before falling below the target CPL. Divide this allowance by the maximum depth of indentation (H3 through H6, though in practice I rarely go beyond H4), and the result is a clean rhythm of 28.125 px per step. Round that figure to the nearest value on the 8‑point grid, and the cadence resolves neatly at 32  px — a number that feels both precise and harmonious.

I turn a fuzzy visual choice (“1 rem, 2 rem, or 3rem?”) into a typographic constraint problem with a numeric answer. No guesswork. No arbitrary numbers. Just a clean typographic system.

“32 px! That’s a lot — it eats too much horizontal space. Remember, most people skip indentation altogether because that space is precious.”
“I know. But smaller steps, like 16 px, don’t create enough visual separation. At 24 px, the structure begins to hold together, though it still feels a little tight. Rounding up to 32 px, by contrast, gives the hierarchy more breathing room.”
“Fair. But what about the other rules? Indentation should be at least the size of your body font to be noticeable, and no more than two or three times that. Or, keep the deepest indentation under 10 % of the column width.”
“For the first, I’m within the two‑to‑three‑times range. For the second, it only really works at the first level. Still, I’ve seen another guideline: nested sections shouldn’t reduce the text block by more than 5–10 % per level. That fits. Where did you pick up these rules, anyway?”
“Copilot. It says they’re good upper bounds for long‑form reading. No sources, but it does note that readability research warns against cutting line length too aggressively — deep indentation eats into the optimal 60–75 characters per line.”
“Exactly. QED.”

What about smartphones?

If the desktop was a matter of refinement, mobile is the battlefield. Columns shrink, line lengths collapse, and every pixel of indentation suddenly feels extravagant. The challenge is simple to state but hard to solve: how do you preserve hierarchy and readability without wrecking the layout on a narrow screen?

“What about your so-called clean typographic system?”
“Let’s put it to the test.”

Before running the numbers for small screens — around 340 px in my case — I needed to adjust the parameters. On desktops, my calculations were based on a 16 px font, giving an average character width of about 7.5 px. On smartphones, the font size drops slightly to 15 px, which translates to roughly 7 px per character. With a 340 px column and that 7 px average width, the maximum number of characters per line — with no indentation at all — is: CPL = 340 / 7 ≈ 48.6.

That’s the hard ceiling. Even at full width, the line tops out at about 49 characters. Which leads to the unavoidable conclusion: a 340 px column can never reach the 55 CPL ideal. Not with indentation. Not without indentation. Not even in theory. The screen is simply too narrow. The indentation on mobile must be handled differently: the goal is no longer “hit 55 CPL,” but rather avoid making an already tight line length even tighter. It’s a shift from optimization to preservation — keeping the text as readable as the physical constraints allow.

Keeping the 32 px indent on mobile is out of the question — the CPL would collapse to about 44, far too tight. Dropping to 24 px barely changes the picture, nudging the CPL to 45, which still feels cramped. Eliminating indentation altogether would certainly preserve line length, and that’s what most designers do. But after fighting so hard to defend indentation as a principle, abandoning it now feels like surrender. Cutting the step in half — 16 px, or even 8 px — begins to look like a compromise worth considering: small enough to protect readability, yet still visible enough to mark hierarchy.

To cut the indentation down, or to drop it entirely — that is the question! Yet whichever path I choose, the riddle remains: how do you actually make it work?

Media query

Media queries are a more definitive set of CSS codes based on the actual media screen width of the device.Saptak Sengupta

Media queries are the classic tool. Their principle is simple: detect the width of the viewport and adjust styles accordingly. On paper, they seem tailor‑made for my problem. I could imagine a neat progression — 16 px indentation for tablets, 12 px for larger phones, and finally, on the tiniest screens, surrendering indentation altogether in the name of readability.

Viewport
The visible area of a web page within the browser window — the “frame” through which the user sees your content.

But here’s where theory collides with reality. The moment I began exploring media queries — not even coding yet, just reading — I felt the ground shift. They aren’t just about distinguishing “phone versus desktop.” They reach into every corner of device behavior: resolution, orientation, aspect ratio, and even user preferences like reduced motion or data saving. Here’s how the MDN article on the subject opens:

Media queries allow you to apply CSS styles depending on a device’s media type (such as print vs. screen) or other features or characteristics such as screen resolution or orientation, aspect ratio, browser viewport width or height, user preferences such as preferring reduced motion, data usage, or transparency.

I pressed on — tutorials, articles, videos (Kevin Powell’s channel (external link) , in particular), and more — and the pattern became clear. Media queries look deceptively simple, but to wield them well, I would need fluency in syntax, a strategy for multiple breakpoints, and foresight for the endless zoo of devices. That’s when the panic returned: what is the viewport of a phone, exactly? How many breakpoints are enough? Which ones matter? My search led me to an article bluntly titled The ideal viewport doesn’t exist (external link) — and suddenly the neat plan of breakpoints felt like chasing a mirage.

What should have been a straightforward adjustment revealed itself as a labyrinth. And even if I mastered the maze, media queries remain blunt instruments: they respond only to screen size, not to the actual container where the text sits. They solve the broad strokes but miss the finer details.

So while media queries carry the weight of tradition and promise, their complexity — and their lack of precision — push me to look elsewhere.

Container queries

Container queries are the new kid on the block. Their principle is elegant: instead of listening to the entire viewport, they respond to the size of the container itself. In theory, this is exactly what I need. My indentation doesn’t care whether the user is on a phone or a desktop — it cares about the width of the column where the text lives. With container queries, I could finally adjust indentation in direct proportion to the actual reading space.

Unfortunately, they don’t magically eliminate the need to define thresholds; they simply shift the reference point. Instead of saying “when the viewport is more than 800 px wide, do X”, you say “when this container is 340 px wide, do X.” That means I still have to decide where the cuts happen. They don’t free me from the tyranny of breakpoints—the same deal‑breaker as media queries.

Moreover, container queries are still relatively new, and browser support, while improving, isn’t universal. They also demand a different mindset: you have to mark up your HTML with container elements, define them carefully, and think in terms of nested contexts. That’s a lot of extra scaffolding compared to the simplicity of a viewport‑based query.

And for someone like me, still learning the ropes, the documentation can feel intimidating. It’s not just “write a query and move on.” It’s “restructure your layout so containers exist, then query them.” Powerful, yes — but also heavier than I expected.

clamp()

The clamp() function is a responsive design superstar. It evaluates its three arguments dynamically: if the preferred value dips below the minimum, it uses the minimum; if it exceeds the maximum, it uses the maximum; otherwise, it goes with the preferred.Gabriel Shoyombo

Clamp is a CSS function that promises fluid scaling. Its principle is straightforward: you give it three values — a minimum, a preferred scaling value, and a maximum — and the browser slides smoothly between them as the available width changes. In theory, this is liberating. No breakpoints to juggle, no blunt “if/else” rules — just a graceful curve that responds as the screen or container changes. The syntax looks like this:

clamp(8px, 1.88vw, 32px);

The preferred value — here, 1.88vw to approximate 24 px on a 1280 px viewport — is chosen if it falls within the bounds. Otherwise, the function snaps to the minimum or maximum, creating a flexible layout without media queries. Imagine saying: “Indentation should never drop below 8 px, it should ideally scale with 1.88vw, but it must never exceed 32 px.” The indentation grows and shrinks gracefully with the viewport, always staying between 8 px and 32 px. It feels effortless, almost like a magic trick.

vw       Relative to 1% of the width of the viewport

These bounds — especially the maximum — are critical when using vw. Without them, indentation could balloon uncontrollably on ultra‑wide screens. With clamp, the browser takes care of the rest:

Phones (≈375 px) → 1.88vw ≈ 7 px, but clamp enforces the minimum, so indentation stays at 8 px.

Tablets (≈768 px) → 1.88vw ≈ 14 px, comfortably within bounds, so indentation scales naturally.

Large desktop (≈1920 px) → 1.88vw ≈ 36 px, but clamp caps it at 32 px, preventing runaway spacing.

Clamp would give me a neat progression: from 32 px on wide screens down through 24 px, 16 px, even 8 px on smaller ones. That part works beautifully — vw handles the scaling, and the maximum keeps indentation from ballooning on oversized displays. Yet my final option, “surrendering indentation altogether on the tiniest screens in the name of readability,” is out of reach. For clamp() to deliver a true zero, the minimum would have to be set at 0 px. But because the preferred value is tied to vw, it will never naturally shrink that far — even the narrowest realistic viewport still produces a positive value.

Below 8 px, indentation stops making sense anyway: what I need is not more fluidity, but a hard drop from 8 straight to 0. That clamp() cannot do. So clamp offers a graceful curve between extremes, but it doesn’t solve my problem. It’s clever, even seductive, but in the end, not good enough.

My breakthrough

After nights of study and failed experiments, I realized how wrong I was. So, I studied even more, but no solution seems to satisfy me. That frustration became the turning point. If none of the standard tools could deliver what I needed, I would have to invent my own. What follows is not a borrowed trick, but my solution — crafted from the ground up.

Clever? No, just stupid!

When I returned to this post—my third attempt at shaping it—I carried in my mind the code I thought would be my solution. If you’ve followed me this far, you may have guessed that percentages played a central role in my plan. I knew they could be unstable in deep nesting, but I loved their responsiveness so much that I was willing to forgive that flaw. So, I start drafting the post, convinced I would use something like this:

section.nested {
  margin-inline-start: clamp(0.5rem, 6%, 2.5rem);
}

Six percent of a 525 px section yields 31.5 pixels. Familiar, isn’t it? That is close to the upper rounded value I had calculated for a 55-character line 5. On a phone, with a 400-pixel display, the column shrinks to 340 pixels, so does my section, and my indent nicely contracts to 20.4 px.

“Do you see the path unfolding? No?”

So, let me translate those rem values into pixels. One rem, under normal conditions, is 16 pixels. My minimum was 8 pixels—the cutoff I had mentioned for small screens. My maximum, 40 pixels—the default padding for lists.

“Still not?”

Yet here lies the stupidity: my theme fixes the content column at 525 pixels. I would never reach the upper bound. Never. And to touch the lower bound, the device would need to be 192 pixels wide — smaller than any contemporary mobile device. Even the Apple Watch has a wider display. In other words, those caps were pointless. Oh stupid! Proof that I didn’t understand the tool I was wielding.

The percentage alone would have sufficed. But the deeper problems remained: percentages are not stable, and they cannot reach zero — nor can they drop cleanly from 8 px to 0 px, the very condition I had argued for (or against clamp() to be more precise) earlier. Thus, the code above was not merely redundant—it was wrong. Worse than wrong, it failed to achieve the very effect I sought.

One problem, one breakthrough

You might imagine that all those long nights of study were wasted hours. They were not. True, I spent countless evenings wrestling with media queries, convinced they were the most powerful tool at my disposal. Yet the tyranny of breakpoints proved fatal to that approach. I abandoned it, though not without reward: along the way, I absorbed the “mobile‑first” mindset, a lesson that would later illuminate my stylesheet in unexpected ways.

Container queries? At first glance, they seemed far too complex. The very notion of defining a container felt clumsy, and what of my nested sections? The effort outweighed the gain, so I dismissed them as well. But was this time squandered? Not at all. My explorations led me to my first true insight. Did you know that container queries bring their own units?

cqw: 1% of a container’s width
cqh: 1% of a container’s height
cqi: 1% of a container’s inline size
cqb: 1% of a container’s block size
cqmin: the smaller of cqi or cqb
cqmax: the larger of cqi or cqb

And here, what once felt like an annoyance suddenly revealed itself as brilliance. What if I defined each H2 section as a container? Then I could use cqw or cqi instead of percentages for my nested sections. The effect would be the same—responsive to screen size—but without the instability of shrinking deeper into the hierarchy. My indentation would always be measured against the H2 section itself.

At first, I thought a single H2 container would suffice. But for cqi to function, the element must live inside the container. That meant defining all my H2s, not just one. The solution was simple: give them a class—say, outer—and add this to my stylesheet:

section.outer { 
  container-type: inline-size; 
}

The only requirement: my H2 section must be declared as a container.

Remember when I said the greatest risk of the class approach was forgetfulness—adding it only to the nested sections, precisely where omission lurks? That risk is gone. My workflow now demands it: when I group sections, transform the default <div> into <section>, and add an anchor link, I also assign a class. Every section, parent or nested, receives its mark. What was once fragile is now routine.

And so, from the ashes of false starts, my first breakthrough emerged.

section.nested {
  margin-inline-start: 5.36cqi;
}

Clever, but for real this time

No single CSS unit is perfect for every situation — and that’s exactly why combining them smartly gives you the most control.Prabakaran Shankar

While cqi had been a revelation—a way to rescue my fragile percentage‑based approach without leaning on media queries—another idea had begun to take root. What I once rejected outright, the abandonment of indentation on small screens, was slowly transforming from an unthinkable compromise into a defining feature. It was this shift that finally led me to discard the clamp() solution.

But how could I make a percentage, or a cqi unit, truly collapse toward zero? Screens have limits; there is no such thing as a display of zero width. I began sketching equations, searching for a formula that would fade gracefully as the viewport shrank. And then, mid‑calculation, a thought stopped me cold: A quoi bon!—what’s the point? CSS would never carry the weight of the mathematics I was conjuring 6.

The calc() function lets you specify CSS property values using addition, subtraction, multiplication, and division.MDN Web Docs

Suddenly, the impossible was possible, but with some limits (CSS alone doesn’t have a native “mathematical piecewise function” operator that maps an element’s absolute x coordinate to a numeric value). But I did not stop there. That is the beauty of study: one topic opens onto another, one path becomes a new avenue, and the journey is endless. Along the way, I rediscovered two functions I had seen before but never truly considered: min() and max(). Now the pieces were in place. I reached for a pencil and paper, began to sketch, and in that moment, the spark of genius struck. Or not.

Attempt #1

On large screens, the target was clear: 5.36 cqi, which translates to 28.125 px on my 525 px column. Actually, I could even use 6 cqi (i.e., the upper 32 px rounding value). But left alone, that 6 cqi refused to shrink enough on smaller viewports: on a 340 px column (a phone), it still held at 20.4 px. Worse, it could never collapse to zero, nor perform the graceful drop from 8 px to 0 px that I had argued for earlier. So the challenge sharpened: how to craft a single CSS expression — no media queries — that behaves like 6 cqi on wide screens, 3 cqi across a chosen viewport range, and then bottoms out, reaching a defined floor, on the narrowest displays.

section.nested {
  margin-inline-start: max( min(6cqi, calc(3cqi + (100vw - 768px) * 200)), max(0cqi, min(3cqi, calc((100vw - 480px) * 200))) );
}

On paper, the math checks out. It works. The logic is sound. The expression does exactly what I asked of it. And yet, here is the truth: it isn’t elegant. It isn’t clean. It is unconventional, even precarious. It’s just a convoluted way of doing what a media query already does. Yes, I had to choose two breakpoints—480px and 768px—to anchor the behavior. In the end, it might feel like a clever trick, but it’s not a sustainable solution.

section.nested { 
  margin-inline-start: 0cqi; 
}

@media screen and (min-width: 480px) {
  section.nested { margin-inline-start: 3cqi; } 
} 

@media screen and (min-width: 768px) {
  Section.nested { margin-inline-start: 6cqi; } 
}

Attempt #2

Once I saw the flaw — my dependence on breakpoints, the very thing that had made me reject media queries in the first place — I picked up my pencil again and returned to the equation. The Heaviside step function lingered in my notes, a tool that CSS could never wield. Or could it? I stared at the page, waiting for something to surface. Nothing came. Until…

Until I fell asleep right there at my desk. When I woke, the equation was still waiting. But the night had done its work. Out of sleep came the spark — the idea that had eluded me while awake. If calc(3cqi - 8px) dropped below zero, then the indent should collapse to 0cqi. Below 8 pixels, indentation is indeed pointless. The vision was the equation that captured that truth.

The path to the final solution, however, was still hidden. I pressed on, scratching notes, testing variations (on the paper), chasing each thread of logic as far as it would go. Hours passed before the outline of an answer began to show.

section.nested {
  margin-inline-start: calc(3cqi * clamp(0, calc(3cqi - 8px) / 1px), 1) + 3cqi * clamp(0, calc((3cqi – 15.725px) / 1px), 1));
}

This is pure CSS, no media queries, no JavaScript. It uses container units so the thresholds are compared to the container’s actual inline size. Genius! Pure genius. What I had built was, in effect, a piecewise function written directly in CSS. The logic was simple but powerful: two thresholds, two steps. Here’s how it works:

  • Each clamp() acts like a switch.
  • When the value inside drops below the threshold, the result is 0.
  • When it reaches or exceeds the threshold, the result flips to 1.
  • Multiply that by 3cqi, and you get either nothing (0) or a full 3 cqi indent.
  • Add the two together, and the margin grows in stages — first at 8 px, then again at 15.725 px.

In other words, the code mimics the behavior of a mathematical piecewise function: below the cutoff, no indent; above it, the indent appears in discrete steps. Of course, this required defining not just one threshold but two. And that was the moment I realized…

The 8‑pixel cutoff had come naturally from my earlier drafting: 32px was far too wide for mobile, 16px still felt cramped, but 8px struck a balance — small enough to protect readability, yet visible enough to signal hierarchy. In theory!

The second threshold, though, was trickier. To find it, I turned to DevTools and began experimenting with the responsive options. Using 3 cqi as my base, I watched how the margin behaved as the column approached its maximum width of 525 px. Strangely, before settling at that cap, the indent spiked higher, only to drop back again.

To play it safe, I leaned on the preset devices. Phones, tablets — I checked them all. No clear pattern emerged. So I took the largest value I saw: the iPad Pro, with an indent of 15.725 px. And no, I’m not a Mac fan boy; quite the opposite. But that is indeed the second time in this post I found myself citing an Apple product.

The second thing that stood out was the process itself — the way I hunted for values, tested devices, and tried to anchor the behavior. What I was really doing, without realizing it, was stumbling into the logic of container queries. DevTools was showing me not only the indent, but also the size of the content column itself (i.e., indent width + content width). In other words, I already had the container’s dimensions — my H2 section. That’s indeed a container query in disguise. Which means the code above could just as well have been written like this:

section.nested {
  margin-inline-start: calc(3cqi * clamp(0, (100cqi - 266px) / 1px, 1) + 3cqi * clamp(0, (100cqi – 524.3px) / 1px, 1));
}

Or, if coded properly:

@container (min-width: 266px) {
  section.nested { margin-inline-start: 3cqi; }
} 

@container (min-width: 524.3px) {
  section.nested { margin-inline-start: 6cqi; } 
}

Sometimes the most powerful breakthrough is realizing that the tool you tried so hard to avoid may, in fact, be the simplest answer.

The first was about the smallest threshold: 266 px. An abstract figure, a column width on paper. But when translated into the real world, it meant a screen only 326 px wide. Once more, I found myself circling back into the same nonsense that had haunted my earlier attempts. No phone today is that small. Even the Apple Watch stretches beyond it — and no, Apple does not sponsor this post.

So the thought pressed in: should I raise the limit, abandon the 8 px threshold, and rebuild everything around 16 px instead? I did not. For beyond that question lay the second realization…

I had been so consumed by the battles — months of wrestling with padding‑left versus margin‑left, the collapse of my selector scaffold, the endless duel with length units — that I lost sight of the living page itself. From the Hydra fight, I had learned: never trust blindly, always test with your own hands. And so I spent long hours in DevTools, yes, but too few in the Customizer, and not a single moment in the stylesheet of my child theme. Why? Out of caution. I dared not tamper with the stylesheet directly — not laziness, but a desire to stay safe. Honest.

I was busy learning, endlessly writing, and constantly debugging. But seeing the code in action? No. Too much time with pencil and paper, not enough with the real thing. And so the numbers became their own illusion. 1 rem, 2 rem, repeated until they hardened into dogma. You stop asking if they look good. They must, surely. On my laptop, 2 rem looked fine. Ten percent was too much, six percent just enough. But on my phone?

The CSS changes I published through the Customizer never reached my device. The changes I had published were invisible there, hidden behind the stale veil of cached pages. My phone browser — or perhaps my hosting provider — kept serving me an older copy of the page, a cached version stripped of the new styles. So the indent never appeared. Yes, I could have flushed the caches, but I didn’t; mea culpa.

And so, after realizations piling one upon another, I finally reached for the tangible. A real phone. Two, in fact, to compare. And what I saw was mind‑blowing: my 5.36 cqi indent was not shocking at all. It was not too big on a small screen. The fear that “the screen is simply too narrow” dissolved. There was no need to halve the indentation, no need to quarter it (the infamous 8 px in action), no need to erase it altogether in the name of line length.

What I saw was structure, hierarchy, and the DOM itself made visible. Rebel paragraphs falling neatly into place. The indent worked — and it worked beautifully. So farewell to the idea of constraining my 5.36 cqi indent, of bending it to half or to nothing on phones that do not even exist (except perhaps for those nostalgic enough to still cradle a Nokia 3310). I will keep one single code:

section.outer { 
  container-type: inline-size; 
}
	
section.nested {
  margin-inline-start: 5.36cqi;
}

The end

It’s everywhere—quietly shaping the digital landscape. HTML is indented. Lists are indented. Comments are indented. Even the Table of Contents gets their own little nudge to the right. Indentation is the silent organizer, the spatial whisper that says “this belongs here.” And yet, when it comes to the article itself—the actual content meant for human eyes—we don’t. We flatten. We fear the space it consumes. I don’t.

I won’t flatten my structure just to fit in. I won’t sacrifice clarity for conformity. Indentation may be unconventional in blog design—but so is semantic markup. And if that means being the only blog with indentation, so be it. I don’t care. Especially if the rest are getting it wrong (see External links best practices, for instance).

If you love it, say so. If you hate it, tell me why. If you have a better idea—please, please—drop it in the comments. I’ve stared at this problem long enough. Your fresh eyes might just see what mine can’t.

Either way, thank you for reading, and may this season bring you joy. Wishing you all a Merry Christmas.


1 Ironically, the whole trial might have ended swiftly had I known about the “internal ≤ external” rule. This principle holds that the spacing inside a component — its padding — should never exceed the spacing outside it — its margins. In hindsight, it explains why I once encountered both margin‑left and padding‑left in the same example (see The generic section nobody talks about), and it would have spared me much anguish in delivering a verdict. A component should never have more space inside it than the space separating it from other components. The rest is yours to decide — apply the rule, test the balance, and reach your own verdict. ^
2 Why such a limit? For a long time, I wondered why my posts refused to stretch across the full width of my screen. After all, 525 px out of 3840 px leaves oceans of white space on either side of the column. The answer came when I discovered that the Web Content Accessibility Guidelines (WCAG) include an advisory that lines of text should not exceed 80 characters in length for better readability. With a base font of 16 px, that translates to a maximum content width of roughly 600–800 px on desktop paragraphs. In other words, the narrow column is not a flaw but a feature. And as it turns out, whitespace on the sides isn’t wasted – it actually improves readability by reducing eye strain and grouping content in the centre, as Gestalt principles and eye-tracking studies have shown. ^
3 That was Caveat #2, born of my attempt to rescue the whole indentation idea. ^
4 Strictly speaking, the conversion from 16 px to a percentage of a 525‑pixel column yields a decimal: 3.047619047619047619047619047619 %. Rounded, this becomes 3 %. The caveat is that percentages in CSS can involve such decimals, and while browsers handle them gracefully, the neatness of “3 %” is itself a simplification. ^
5 That original choice of six percent was not born of my CPL system at all. It was anchored instead in a rough equivalence to 2 rem, a decision made long before I began designing with line length in mind. Had I already built the CPL framework, my numbers would have been different, more deliberate: 5.36 % — which translates to 28.125 pixels on a 525‑pixel column — or perhaps 4.57 %, a clean 24 pixels. In hindsight, those figures would have aligned far more gracefully with the system I eventually devised. ^
6 I found a function, a step function to be specific, that starts at 0, jumps to a value of 3 at a certain point, and jumps again to a value of 6 at a later point: f(x) = 3H(x-point1) + 3H(x-point2). It uses the Heaviside step function H(x), which is a piecewise function whose value is zero for negative arguments and one for non-negative arguments. It is also known as the unit step function and is typically defined as: H(x) = 0 for x < 0 and 1 for x ≥ 0. ^