Skip to content

Add conditional whitespace hanging explanation - #831

Merged
tomcur merged 2 commits into
linebender:mainfrom
tomcur:push-xslvxtmxstxo
Sep 22, 2026
Merged

tomcur merged 2 commits into
linebender:mainfrom
tomcur:push-xslvxtmxstxo

Conversation

@tomcur

@tomcur tomcur commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

LLM Contributions: Review.

This explains the reading of the spec, and explains our model based on that. Wrote this as an explanation in
#790 (comment), and figured it may be useful in the docs for posterity.

HTML sample
<style>
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap");
body {
    font-size: 16;
    font-family: "Roboto";
}
</style>

<h1><code>collapse</code> hangs unconditionally</h1>

<div style="width: 200px; border: 1px solid; text-align: right">
  X<span style="white-space-collapse: collapse">&#x3000;</span><br />Y
</div>

<h1><code>preserve</code> hangs conditionally</h1>

<div style="width: 200px; border: 1px solid; text-align: right">
  X<span style="white-space-collapse: preserve">&#x3000;</span><br />Y
</div>

<h1>
  <code>preserve</code> preceding <code>collapse</code> hangs unconditionally
</h1>

<div style="width: 200px; border: 1px solid; text-align: right">
  X<span style="white-space-collapse: preserve">&#x3000;</span
  ><span style="white-space-collapse: collapse">&#x3000;</span><br />Y
</div>

<h1>
  <code>collapse</code> preceding <code>preserve</code> hangs conditionally
</h1>

<p>
  The <code>collapse</code> part hangs in full if the <code>preserve</code> part
  hangs in full.
</p>

<p>Here, the <code>preserve</code> part fits in full, so nothing hangs:</p>

<div style="width: 200px; border: 1px solid; text-align: right">
  X<span style="white-space-collapse: collapse">&#x3000;&#x3000;&#x3000;</span
  ><span style="white-space-collapse: preserve">&#x3000;</span><br />Y
</div>

<p>Here, the <code>preserve</code> part doesn't fit, so everything hangs:</p>

<div style="width: 200px; border: 1px solid; text-align: right">
  X<span style="white-space-collapse: collapse"
    >&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;</span
  ><span style="white-space-collapse: preserve">&#x3000;</span><br />Y
</div>

https://developer.mozilla.org/en-US/play?id=Xvs2WibuByVkeRPwc7hAy%2BfYc%2B5W6ZVidyHcfdDy1%2F%2F41DBLRABlyaBHukdkDbLhL4%2BnN5%2FL5YHGdy5B

Changelog: None

This explains the reading of the spec, and explains our model based on
that. Wrote this as an explanation in
linebender#790 (comment),
and figured it may be useful in the docs for posterity.

@DJMcNab DJMcNab left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it's internal only docs, I'm happy enough just moving forward with this.

//!
//! # Conditional vs. unconditional whitespace hanging
//!
//! Under CSS Text 4 § 4.3.2, some whitespace hangs, and some may hang *conditionally*.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what's missing here is a definition of what hanging actually means. To be completely honest, I still haven't got my head around what the behavioural difference is, if we're not actually omitting the glyphs. Is it mostly/entirely the impact on alignment?

@tomcur tomcur Sep 22, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair! This was mostly copied from my comment that really just focused on the conditional vs unconditional aspect of it.

When measuring the line width hanging clusters/glyphs are not included, so yes: it impacts alignment. We currently only hang whitespace, but e.g. punctuation could also hang, in which case you could see the glyphs go outside the line box.

@tomcur
tomcur added this pull request to the merge queue Sep 22, 2026
Merged via the queue into linebender:main with commit 52c735c Sep 22, 2026
24 checks passed
@tomcur
tomcur deleted the push-xslvxtmxstxo branch September 22, 2026 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants