The Section now routes Min Height, Container Width and vertical-align to stylesheets — should the background (color/gradient/image/overlay) move to the per-page page-{id}.css too, or stay an inline style?
The question. We just moved the Section shortcode's per-instance styling out of inline style=
and into stylesheets: Min Height (a fixed enum) became predefined .section--minh-{40|60|80|100}
classes, Container Width (a user-extensible named-width library) and the vertical-align flex
became .u{hash}-scoped rules in the per-page page-{id}.css. The background
(color / gradient / image / overlay) is now the only thing the section still prints as an inline
style="background-…". Should it move to page-{id}.css as well — for a fully inline-free markup —
or stay inline?
Context. The Section routes each setting to the leanest layer that fits it: a fixed-enum value
becomes a predefined utility class; a user-library or otherwise-reusable value becomes a
.u{hash}-scoped rule written into the per-page page-{id}.css (aggregated by dynamic-css.php);
genuinely per-instance appearance stays inline. sc_bg_pro_style() builds the background string —
background-color, then a stacked background-image (overlay tint over the image url() over a base
gradient), plus background-position / repeat / attachment / size when an image is present — and
the view prints it on the <section>'s style. Because the scope class and the aggregator already
exist, moving it is mechanically trivial: emit a .u{hash}{background-…} rule and drop the inline
attribute. So "is it possible?" is yes — the real question is should we.
Options considered.
- Move the background to
page-{id}.css(a fully inline-free<section>). Consistent with the other section styling and satisfying if the goal is "zero inline styles." But the background is a per-instance, per-URL value with no reuse, so relocating it dedupes nothing — it just moves ~200 bytes from the HTML into a CSS file and adds a file dependency. Worse, it puts the hero background behind a render-blocking stylesheet: an inline background is available the moment the HTML parses, whereas a background inpage-{id}.csscan't paint until that file downloads and parses — landing squarely in front of the largest paint. And the front-end builder, which mutates the inlinestylelive as you drag the Background controls, would need a file-regen round-trip. - Keep the background inline (status quo). One inline
style=remains on sections that carry a background, but it is the right place: per-instance, immediately available, WYSIWYG-friendly, and best for LCP.
Decision. Keep the background inline. The Min Height / Container Width / vertical-align cleanup was worth doing because those were reusable, small-vocabulary values that had been wrongly inlined (a preset class, or one library value edited in a single place). The background is arbitrary, unique per section, and performance-sensitive — the textbook case for the inline bucket in our own placement rule, not a lazy holdout.
Why. The line is drawn by the value's nature, not by a blanket "no inline" aesthetic:
- Reuse decides class vs. file: a value shared across sections (a variant, a named width) earns a shared class or one shared rule; a value unique to one section earns neither.
- Performance decides inline vs. file within the unique bucket: a hero background is usually the
LCP element, and inline paints it without waiting on a stylesheet. Moving it to
page-{id}.cssadds a render-blocking dependency for zero byte savings, and re-invalidates the whole per-page file on any single background edit. - Editability favors inline: the live editor updates
styledirectly; a file-based background needs regeneration to preview.
So the placement rule, stated in full: fixed enum → predefined class; a reusable library value →
a generated .section--… class in presets-{hash}.css (shared + cached, like Gap / Section Variant /
Container Width presets); a one-off arbitrary value → a .u{hash} rule in page-{id}.css; genuinely
per-instance, per-URL, performance-sensitive appearance (the background) → inline style=. Background
is the one value the rule deliberately sends to inline — which is why it was the last thing standing
after the cleanup, and why it should stay there.
(Refinement, 2026-08-11: Container Width's named library presets were subsequently moved from
per-instance page-{id}.css rules to generated .section--cw-{slug} classes in presets-{hash}.css —
matching Gap and Section Variant — so only a Custom width still routes to the page file. That's the
"reusable library value → generated class" clause above in action.)
(Related: container widths as a converter-populated preset family and the never-drop CSS placement rule.)
