Skip to content

[6.x] Spaceless tag#15026

Open
marcorieser wants to merge 18 commits into
statamic:6.xfrom
marcorieser:feat/spaceless-tag
Open

[6.x] Spaceless tag#15026
marcorieser wants to merge 18 commits into
statamic:6.xfrom
marcorieser:feat/spaceless-tag

Conversation

@marcorieser

Copy link
Copy Markdown
Contributor

Problem

Antlers template formatting (e.g., with Prettier when using TailwindCSS) adds whitespace and newlines in the rendered HTML. Browsers collapse that into a single visible space, which shows up as unwanted gaps between inline/inline-block elements (e.g., buttons, badges, nav items) even though the template author never intended a space there.

Solution

Adds a {{ spaceless }}...{{ /spaceless }} tag that strips whitespace-only gaps between tags from its rendered content, while:

  • Collapsing (not removing) whitespace within real text nodes, so word spacing stays intact.
  • Leaving <script>, <style>, <pre>, and <textarea> content completely untouched, since whitespace there is meaningful.
  • Not touching whitespace inside a tag itself (attributes, quoted values) — invisible to the browser, out of scope.

@jasonvarga jasonvarga 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.

Thanks for this — the tag genuinely fills a gap the spaceless modifier can't (wrapping block-level output like loops/conditionals, not just a single string value).

One issue blocks merge though: the whitespace-stripping logic strips whitespace next to any tag, not just whitespace between two adjacent tags. That glues together real prose whenever an inline tag sits mid-sentence:

<p>Check out <a href="#">this link</a> for more info.</p>
→ <p>Check out<a href="#">this link</a>for more info.</p>

This contradicts the stated goal of preserving word spacing, and none of the current tests catch it since they only cover structural/list markup. Could you scope the stripping to only whitespace directly between two tags (>...<), like the existing modifier does, rather than between text and a tag? A test with prose + an inline tag (e.g. the example above) would help lock this in.

Previously stripped whitespace beside any tag, which glued inline
tags to surrounding prose (e.g. text before/after a link). Now only
strips between two tags, or at the inner edge of a tag's own content.
@marcorieser

Copy link
Copy Markdown
Contributor Author

@jasonvarga Good catch! Updated the PR.

@jasonvarga jasonvarga 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.

Thanks! There's still a narrower version of the same issue though: whitespace that sits only just inside an opening/closing tag (no space outside) still gets trimmed unconditionally, which can glue words together:

This is<strong> important</strong> info.
→ This is<strong>important</strong> info.
→ renders as "This isimportant info."

Less likely with hand-typed templates (people naturally put spaces outside tags), but plausible with machine-generated HTML like Bard/rich-text output. This needs to be fixed the same way the tag-to-tag case was — only trim inside-tag whitespace when there's already a boundary/whitespace on the outside.

@marcorieser
marcorieser marked this pull request as draft July 18, 2026 07:03
A tag with no gap from the word before it (e.g. is<strong>) could
still have meaningful whitespace on its inner edge; only trim that
edge when the tag itself sits at an actual boundary.
A plain space between two tags is usually intentional; a line break
there is almost always formatter indentation, so only that gets
stripped now instead of every gap between tags unconditionally.
The regex-chain approach couldn't see past a single neighboring tag,
so two bugs slipped through: whitespace inside a tag directly chained
onto another tag was stripped even when both were glued to real
prose, and a line break glued to prose right inside a tag survived as
a literal space instead of being treated as formatter noise. Tokenizing
into tags/whitespace/prose and walking through chained tags to find
the nearest real content fixes both.
Void tags like <br> and <hr> are commonly written without the
self-closing slash, but were only classified void when they had one.
Without it they acted like a container, stripping whitespace on one
side but not the other.
@marcorieser
marcorieser marked this pull request as ready for review July 18, 2026 08:51
@marcorieser

Copy link
Copy Markdown
Contributor Author

@jasonvarga should be fixed and tested now. Found some other edge cases. Also did a code review by Claude and added tests. My main goal for that PR is to prevent rendered spaces in the browser caused by formatters (e.g., Prettier). That's why newlines between tags are removed entirely. This should not happen when generating prose HTML by e.g., Bard, since that shouldn't contain newlines.

@marcorieser
marcorieser requested a review from jasonvarga July 18, 2026 09:09
Each test should verify one claim; the plain line-break case and the
mixed-whitespace-with-newline case are separate claims worth naming
and failing independently.
alt="" so it stops worrying about accessibility, a semicolon so it
stops worrying about ASI, a swapped script for a pre so it stops
pretending to be a JS engine, and a fake CDN URL so it stops looking
for foo.jpg on disk. None of it changes what's under test.
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