Sell the rectangle instead of the sponsored line - #2
Merged
Conversation
The unit was a text link, on the reasoning that it is the only format that fills its container and so the only one safe in a column whose width nothing here can measure. That is true, and it is also the smallest thing the slot can sell. The rectangle is the inventory worth having; the column just has to be made to fit it. So the default format is `banner_300x250`. 300px is the widest fixed creative that still fits a 320px phone, which is what makes one size for every viewport possible at all — picking by width would need a script, and rendering two units for CSS to hide one would bill two impressions for a single reader. Two columns on this site are narrower than 300px, and every creative is laid out at its format's exact pixel width inside the frame, so a narrow column crops it rather than reflowing it: a test page at 320px gave the unit 250px and cut a fifth off the ad, and 360px cut 10px. Below 640px the unit now escapes its column's padding and centres against the viewport instead. The ad does not get bigger — it just stops being cropped by a gutter. Measured at 320, 360, 390, 430, 768 and 1280: the creative is 300px everywhere and the document never scrolls sideways. Nothing asks for a theme, and that is now deliberate rather than a gap. `/api/ads/frame` ships both palettes behind `prefers-color-scheme`, which the frame answers from the reader's own browser — a better signal than this end could offer, since the site's theme is a stored preference the server never sees. The unit renders on #070a10 for a reader in dark and #f6f9fb for one in light, on the same page. The test pinning `format=text_link` pinned the reasoning above, so it is replaced rather than deleted: the new one holds the format to a single fixed size and the frame to that format's exact box, which is the property that breaks if either drifts. A second test holds the embed to naming no theme.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Switches the ad from the inline text link to the 300×250 rectangle.
The text link was chosen because it is the only format that fills its container, and so the only one safe in a column whose width nothing here can measure without a script. That reasoning holds — it is also the smallest thing the slot can sell. The rectangle is the inventory worth having, so the column gets made to fit it instead.
One size, everywhere
banner_300x250. 300px is the widest fixed creative that still fits a 320px phone, which is what makes a single size viable at all:The columns that were too narrow
Every creative is laid out at its format's exact pixel width inside the frame, so a narrow column crops it rather than reflowing it. Measured before the fix:
Below 640px the unit now escapes its column's padding and centres against the viewport (
margin-inline: calc(50% - 50vw)). The ad does not get bigger; it stops being cropped by a gutter.bodyalready hides horizontal overflow, so a stray pixel cannot start a sideways scroll.Re-measured at 320 / 360 / 390 / 430 / 768 / 1280 on both pages: creative is 300px everywhere, cropped nowhere, and
scrollWidth === clientWidthat every width including either side of the 640px breakpoint.Theme
Still nothing asks for one, and that is now deliberate rather than a gap. Since profullstack/crawlproof.com#221,
/api/ads/frameships both palettes behindprefers-color-schemeand the frame answers it from the reader's own browser — a better signal than this end could offer, given the site's theme is a stored preference the server never sees.Verified on the same page:
rgb(7,10,16)for a reader in dark,rgb(246,249,251)for one in light. The dark bar on the light theme is gone.Tests
The test pinning
format=text_linkpinned the reasoning this PR reverses, so it is replaced rather than deleted — the new one holds the format to a single fixed size and the frame to that format's exact box, which is the property that breaks if either drifts. A second new test holds the embed to naming no theme, so nobody re-adds a guess that would override the reader's browser.Verified
biome checkclean · 66 tests pass · static export still ad-free (desktop app untouched) · all 24 pages pass the browser smoke test · no CSP violations and no page errors in a real browser at desktop and mobile widths in both themes.