CSS: inline styles vs style blocks
There are two ways to style content, with different rules:
Inline style="…" | <style> block | |
|---|---|---|
| Scope | one element | the whole article (auto-scoped) |
url(…) backgrounds | ✗ blocked | ✓ allowed |
| Media queries, keyframes | — | ✓ |
Custom fonts, @import | — | ✗ dropped |
| Best for | one-off tweaks | anything bigger |
Inline style attributes
Quick, local, and strict:
<span style="color: crimson; letter-spacing: 0.05em">watch this</span>The value is checked against a blocklist of dangerous patterns (the list). The strictness has a sharp edge: one blocked pattern rejects the whole attribute — in
<div style="background: url(tile.png); color: red">the url(…) is blocked and takes color: red down with it; the element
renders unstyled. Backgrounds by URL belong in a <style> block.
<style> blocks
For anything beyond a one-off tweak, a page-level style block is the better
tool: it’s scoped to the article automatically, and it supports media
queries, keyframes, and url(…) backgrounds. The full treatment —
what’s scoped, what’s kept, what’s dropped — is on
Scoped styles.
Why the rules are shaped this way
CSS can exfiltrate and execute in surprising ways (expression(),
javascript: URLs, XBL bindings — all museum pieces, all blocked
anyway). The engine’s stance: block the scripting vectors everywhere,
allow url(…) only where the CSS is scoped and inspectable — the
<style> block — and keep inline attributes conservative because they
travel through more surfaces (tooltips, previews, diffs).
If styling silently vanished, check in this order: a blocked pattern in an
inline style (whole attribute dropped) → a class name with exotic
characters (token filtered out) → a selector on html/body/:root in a
style block (scoping makes it unreachable).