Scoped styles
A page can carry its own CSS in a <style> block. The engine scopes every
rule to the article automatically — your selectors only ever match inside
the article body, never the site chrome or other pages.
<style>
.timeline { border-left: 3px solid #888; padding-left: 12px; }
.timeline h3 { margin-bottom: 2px; }
@media (max-width: 600px) {
.timeline { padding-left: 6px; }
}
</style>
<div class="timeline">
== 476 ==
The western empire ends.
</div>Under the hood each selector is prefixed with the article container, so
.timeline becomes .hw-parser-output .timeline.
What survives, what doesn’t
- Kept and scoped: ordinary selectors, and
@media,@supports,@container,@layerblocks (their inner rules are scoped too). - Kept as-is:
@keyframesand@page(animation names are global by nature). - Removed:
@importand@font-face— no external resources, no custom fonts. - Neutralized: dangerous constructs (
expression(),javascript:URLs and similar) are blanked out. - Selectors targeting
html,body, or:rootsimply never match — you can style your article, not the page around it.
url(…) backgrounds are allowed in <style> blocks. Note the asymmetry:
in an inline style="…" attribute, a url(…) causes that entire
attribute to be dropped — put image backgrounds in the <style> block.
Behavior notes
- The style applies on the article’s own page (and its previews). Reading another article never applies this one’s CSS — scoping plus the reader app’s per-article style handling keep pages isolated.
- Multiple
<style>blocks are fine; each is scoped independently. - The block itself renders nothing — put it anywhere; top of the page is conventional.
- Class names should be simple tokens (letters, digits,
-,_). Exotic characters get stripped fromclass=attributes by the sanitizer.
Theme-friendliness: readers switch between White, Paper, and Desert themes. Prefer semi-transparent colors or borders over hard-coded light backgrounds so your styling survives on every theme.