Summary
Responsive Latin paragraphs can put an opening quotation mark at the start of an internal line. An author may want that mark to protrude beyond the text edge, but the amount remains a design decision. Optical Margin demonstrates an adjustable treatment in a local Chromium specimen. Its measurement is a character advance multiplied by a fraction, subject to limits. That operation does not establish an optically correct margin or a reading benefit.
Start with the simpler alternatives. Use native CSS when its semantics meet the design and the target browser implements them. For one known pull quote, a manual first-line indent can be sufficient. Consider JavaScript when an actual responsive paragraph needs internal-line control, and inspect the result rather than assuming it improves the composition.
Start with the platform
The CSS Text Level 4 editor’s draft defines hanging through keywords. Its first and last values concern eligible punctuation at the first and last formatted lines. Its allow-end and force-end values concern stops and commas at line endings, with different conditional and forced behavior. Those are distinct promises: it would be wrong to describe native CSS as incapable of any internal-line punctuation hanging.
A reasonable progressive enhancement starts here:
.prose {
padding-inline: 1em;
}
.prose > p {
hanging-punctuation: first allow-end last;
}The padding reserves space; it is not a measured correction. The declaration requests native behavior without wrapping individual words in script-generated markup. An unsupported browser can retain ordinary punctuation layout. If forced stop or comma hanging is wanted, choose force-end instead of allow-end and verify the result. Do not treat the two keywords as interchangeable or infer a numeric hang fraction from either one.
The draft is work in progress, not a support table or a report of our tests. This paper does not present a measured native-versus-JavaScript comparison. The alternatives are included because they may solve the reader’s problem with less machinery, not to stage a contest that we have not run.
One quotation can be an editorial adjustment
For a known opening quote, the author can tune the first line directly:
.pullquote {
padding-inline-start: .4em;
text-indent: -.4em;
}This combination moves the first line toward the outer edge while keeping following lines inset. The .4em value is illustrative and should be adjusted in the actual typeface and surrounding layout. It does not find a quotation mark that becomes an internal line start after reflow. It can also move the first line when no opening mark is present, so restrict the class to content for which the adjustment is intentional.
For an isolated editorial quotation, that explicit choice may be the whole solution. Adding line detection and repeated measurements would increase the implementation burden without answering a new requirement. Neither a native declaration nor a manual indent needs this package to be useful.
The internal-line case
The remaining case is narrower: general Latin opening punctuation at internal line starts after wrapping. CSSWG issue 9708 asks for treatment beyond the first line. The discussion distinguishes Latin needs from the Chinese, Japanese, and Korean cases informing the existing model. It is evidence of a design question, not an adopted extension or endorsement of Optical Margin.
Our specimen is original explanatory prose, not a quotation from a typographic authority. At the observed wide setting its hung opening mark belongs to the paragraph’s first line. That is insufficient evidence for an internal-start thesis. Narrowing to 50% also did not produce the required opening mark. We therefore searched narrower widths and recorded the first matching state at 54%, with a 1440 by 1100 CSS-pixel viewport.

Magnified recorded detail · sixth-line quote left of guide

At that setting, justified text has Start and End enabled, threshold 0.5px, and maximum hang ratio 0.90. The sixth rendered line starts with the question visible in the figure. Its opening mark begins at x=199.5 against a paragraph start guide at x=208: an observed displacement of 8.5 CSS pixels in the recorded original layout. The preceding line ends with the words internal line. The mark is therefore inside the paragraph’s flow, not a repeated illustration of its opening quote.
The figure preserves browser pixels and guides. Cropping changes its framing, not the letter positions. The labelled magnified detail enlarges those same recorded pixels; its displayed separation scales with the image. The observation data records the settings, coordinates, source-image hash, and crop. Do not infer that the same percentage always produces this line in another viewport, font environment, or browser. Confirm the rendered line before using it as a demonstration.
What the implementation measures
The implementation checks eligible punctuation on words at aligned edges. It measures the rendered character advance through a DOM Range when available. Canvas is a fallback approximation; it does not reproduce every shaped DOM setting or later font replacement. It then applies a configurable fraction, capped by the maximum ratio and filtered by the threshold. These are implementation policies, not derived laws of perception. The case study’s displacement is a layout observation; it is not a measurement of ink outlines or a perceptual optimum.
That distinction matters even when a result looks persuasive. Sidebearings, the drawing of a quote, neighboring letters, and the rest of the composition can affect an author’s choice. A single default fraction cannot resolve those questions for every typeface. CSSWG issue 9329 discusses the difference between hanging characters and optical alignment, including the possibility of information supplied by fonts. These are participant proposals and judgments, not a shipping universal font feature.
A small application can expose the choice explicitly:
<OpticalMarginText
hangStart={true}
hangEnd={true}
threshold={0.5}
maxHangRatio={0.9}
hangFractions={{ '“': 0.8 }}
>
{paragraph}
</OpticalMarginText>The displayed numbers are example policy inputs. An author still needs room for protrusion and a decision about whether the resulting edge suits the page.
Alignment and stability impose limits
The observed controls make the eligible edge inspectable. At 50% width, Left alignment retained the opening treatment and removed ending treatments. Right retained endings and removed the opening treatment. Turning off the corresponding Start or End control removed those treatments. With justified alignment and maximum ratio zero, the observed specimen had no recorded hangs. These are useful null and edge checks, not a browser certification exercise.
A hang also changes available space. A negative margin can allow a word to move onto the preceding line, undermining the very edge that was measured. The implementation checks unstable treatments and can leave a mark flush. The source explains that compromise; the eight-state observation set does not establish that every unstable case is detected. Leaving some eligible marks untreated is an intentional limit of the approach, not evidence of universal correctness.
Objections answered
Why use JavaScript at all? Only when the actual layout needs internal-line control that the simpler choices do not provide. For ordinary text, accepting the untreated edge is reasonable. A preferred composition does not imply that every paragraph needs intervention.
Does measuring the font make the result correct? It makes the amount responsive to a measured advance. The fraction remains authored. The measurement neither identifies a preferred ink edge nor predicts how a reader will respond.
Does the example show native CSS losing? No. CSS semantics come from the specification and discussion; the visible displacement comes from JavaScript in Chromium. We have not run the same specimen through a native-supporting engine for a controlled comparison. That missing test must remain visible wherever the example is presented.
Recommendations and open questions
Prefer a platform feature when its behavior is sufficient. Tune a known quotation manually when that is the real task. If responsive Latin prose needs internal-start treatment, preserve an untreated reference, inspect narrower columns, and review the fractions when changing the typeface. Test the container’s clipping and padding too: a correct coordinate can still put punctuation outside visible space.
Open questions include whether font-supplied adjustments could reduce repeated author tuning, how to expose overrides without burdening editors, and which line changes justify skipping a treatment. None is answered by the single internal quote. A preference study or reading study would be a separate project with a different method.
Method and tests still needed
The underlying observation session used headless Playwright Chromium at 1440 by 1100, awaited document fonts, and operated eight core states. This was horizontal Latin layout without transforms; vertical writing and transformed geometry are not validated. The figures are static recorded browser images, not live demonstrations or native-versus-JavaScript comparisons. A targeted sweep from 51% through 54% found the internal opening quote. Character Range geometry supplied the recorded line starts and edge coordinates. A later Start-toggle check found the treatment wrapper removed when disabled; it did not log an off-state character coordinate. The browser version was not logged in that panel session. This is local-demo evidence, not parity testing of downloaded releases or wrappers.
A separate November 8 check ran the integrity-verified published 2.0.1 core directly in Chromium 149.0.7827.55, using plain DOM text with the demo’s loaded font and styles. It reproduced the internal quote at x199.5 against guide208. With Start disabled, reflow put the quote at x247.921875; disabling hanging does not simply move it back to the guide. A zero ratio applied no margins, and removal restored clean HTML. This is a bounded released-core check, not wrapper parity or a native-engine comparison. Released-core browser results.
Unsupported-browser tests remain necessary: verify the plain-text fallback when native hanging-punctuation is unsupported, verify the native declaration in a supporting engine, and compare native, none, and JavaScript with the same content and font. WebKit and Firefox JavaScript rendering were not tested in this observation set. CSS support detection alone would not establish correct rendering. Repeat with delayed font loading, font substitution, resize, overflow clipping, selection, copy/paste, links, and project-specific hyphenation. Screen-reader operation, non-Latin typography, wrapper parity, and reading outcomes are untested here. Do not infer those results from unchanged text in a screenshot.
Disclosure
Overpunch makes Optical Margin and the other Type Tools. We have more than 15 years of experience building websites for type foundries and are developing Typetin, a storefront for independent foundries. Typetin is in development. This is an interested implementation case study, not an independent product evaluation.
Sources
- CSS Text Level 4, hanging-punctuation: primary editor’s draft; reopened November 6, 2026. Semantics and limits, not shipping support.
- CSSWG issue 9708: primary internal-line discussion; reopened November 6, 2026. A proposal and responses, not consensus.
- CSSWG issue 9329: primary discussion of optical alignment and design-specific amounts; reopened November 6, 2026. No direct quotations used.
- Local specimen observations and figure provenance: November 6, 2026. Coordinates and settings, not a native-engine comparison.
- Optical Margin implementation: local core source inspected for method and stability limits. This paper does not claim released-artifact parity.