Build1 distinct publisher3 min readUpdated
A stylesheet rule beat a zoom-compensating presentation attribute for months, silently. The takeaway from one icon editor's postmortem: dynamic SVG styling belongs in custom properties.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The reason this one survives months of use is that nothing in it is invalid. `setAttribute('stroke-width', '0.05')` writes a legal presentation attribute, the browser resolves it against `.handle { stroke-width: 0.35 }` from the stylesheet, and the attribute loses because a presentation attribute ranks below every ordinary declaration [1][2]. No parse error, no console warning, and any test that inspects the DOM reads back exactly the number the code wrote [4].
The arithmetic is what carries it past review. The compensation is `0.35 / zoom`, so at zoom 1 it returns 0.35, which is the number the stylesheet already holds, and the default view is correct [18]. The measurement the author reports, an attribute of 0.05 computing to `0.35px` in Chromium, is the state at zoom 7, where the handles were drawn seven times their intended width [3][17]. An error that is zero at rest and grows with interaction reads as a quirk in the zoom code, not as a dead line in the styling code.
Custom properties fix it for a structural reason rather than a stylistic one. `--px` set on the layer is an ordinary declaration, so it enters the cascade at a level the attribute cannot reach, and the stylesheet does the multiplication inside `calc()` [5]. The division of labour is the real gain: the script publishes one scalar per layer and owns no geometry at all.
The part that should correct the mental model is the finding that turned out to be a non-bug. The author had left a comment claiming `var()` is not substituted in presentation attributes; in fact an attribute and an inline style resolve `oklch(var(--band-l) var(--band-c) 47)` to the same computed colour, including on a node built detached and appended afterwards [7]. So attributes are not an inert side channel. They evaluate custom properties normally and then lose on priority, which means the failure to design against is a silent override, not a failure to compute. That comment cleared a full test suite and a deploy [8], which is roughly what a claim about a browser is worth when nobody pointed a browser at it.
The rest of the writeup has the same shape: authored values agreeing with themselves while computed values say otherwise. Chrome's own focus ring, measured at `outline-width: 2.72727px` in user units, put a blue disc around every clicked point [10], and it took four reports and four wrong fixes before a single `getComputedStyle` call named it [11]; the author's rule covered only `:focus-visible`, the keyboard path where he already draws a ring of his own [12]. The contrast test stayed green because it read the band's raw `stroke`, and a raw colour says nothing about opacity [15], while a 74% opaque band over white sat at 2.29:1, under the 3:1 that WCAG 1.4.11 asks of a graphic [13]. No single lightness cleared both themes at that opacity, so lightness became a theme token, 0.52 on light and 0.74 on dark [14]. The same measuring habit applied to twelve palettes labelled "soft" put them at 5.6:1 to 6.1:1 on a dark ground and 1.03:1 to 1.08:1 on white [16]; on white, the best of them reaches about a third of that 3:1 [19].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The author scaled handle stroke widths by 1 / zoom and wrote the result as a presentation attribute, handle.setAttribute('stroke-width', String(0.35 / zoom)); the value was never used.
A stylesheet rule of .handle { stroke-width: 0.35 } outranks the presentation attribute, because a presentation attribute sits at the very bottom of the CSS cascade.
Measured in Chromium, a stroke-width attribute of 0.05 computed as 0.35px.
Every handle thickened on screen as the user zoomed in, for months, with no error raised anywhere.
The fix was a custom property, which is an ordinary declaration and wins where an attribute cannot: layer.style.setProperty('--px', String(1 / zoom)) with .handle { stroke-width: calc(0.35 * var(--px)) }.
Geometry attributes such as r and width were unaffected, because they have no CSS counterpart here, so nothing was ever overriding them.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Reproducible code, single unverified author
The core claims are backed by published code and specific computed values (0.35px from a 0.05 attribute, outline-width 2.72727px, "oklch(0.52 0.09 47)", 2.29:1 vs the 3:1 WCAG 1.4.11 bar), which a reader can re-run in a browser. But the cluster contains exactly one source, all measurements are the author's own, testing is described only in Chromium/Chrome, and the twelve-palette survey gives ranges without listing values or method.
One self-published hobby deployment
The only adoption signal supplied is the author's own free editor being live at icons.jamuny.com with the described fixes shipped, plus user reports of the focus ring arriving four times. There are no user counts, downloads, dependents, or third-party uses of the custom-property pattern in the supplied material.
Slightly overstated generalisation, modest tone
The write-up is unusually self-critical and its specific findings are demonstrable, so it is close to aligned. The mild overstatement is in scope: measurements are Chromium/Chrome-only and drawn from one codebase, while the framing generalises to how SVG and CSS behave and to where dynamic SVG styling 'belongs'; the labelled-palette survey is presented as a general verdict on 'soft' palettes from a twelve-item sample with undisclosed data.
Self-promotional developer post for own product
The author repeatedly names and links his own product (icons.jamuny.com, 'free, no account'), opening and closing on it and volunteering a security posture (connect-src 'none'), on a self-publishing developer platform with no editorial gate. That is a clear promotional interest, though it is disclosed openly, the product is free, and the post's substance is an admission of the author's own mistakes rather than a capability boast.
Moderate-low: single interested source, checkable core
Confidence is capped by having one self-published, self-interested source and no cross-publisher or cross-browser corroboration. It is lifted above low by the fact that the central mechanisms are stated as code with computed values that any reader can verify independently, and by the author's disclosure of his own errors.
build
height:auto is animatable now, so your max-height ceiling is a bug you can delete1 distinct publisher
build
The exit ping that never left: fetch in beforeunload loses to the browser's unload policy1 distinct publisher
build
Three ways to ask who embedded your iframe, and only one the host cannot switch off1 distinct publisher
build
The third answer: a dead-code tool allowed to say "not traced yet"1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 22, 2026