---
title: "Write styles only in stylesheets · Agent Wranglers"
url: https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Write styles only in stylesheets

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

For AI agents: [llms.txt](https://agentwranglers.se/llms.txt) is a short guide that sends you to the rules your problem needs, and [rules.json](https://agentwranglers.se/playbook/html-css/rules.json) holds every rule of this playbook as JSON.

- Level: Recommended
- Chapter: [Structure and files](https://agentwranglers.se/playbook/html-css/structure-and-files)
- Rule: Keep every style declaration in a stylesheet. Templates have no `style` attributes or `<style>` elements, and scripts never set `element.style` properties.
- How: When a script must pass a value to CSS, set a custom property with `style.setProperty('--progress', value)` or a state attribute. The stylesheet decides what the value does. This keeps every style in one searchable place and lets a strict Content Security Policy block inline styles. The page-level gate is in [Fail the build on broken rules](https://agentwranglers.se/playbook/engineering/rules-as-code/build-gates).
- Check: The built HTML has 0 `style=` attributes and 0 `<style>` elements. A search of the scripts finds 0 assignments to `.style.` other than `setProperty('--…')`.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Avoid: the script decides how it looks
bar.style.width = `${percent}%`;

// Do: the script passes a value, the stylesheet uses it
bar.style.setProperty('--progress', `${percent}%`);
```

### Python example

```python
# A source check: scripts may only set custom properties
import pathlib, re, sys
pattern = re.compile(r"\.style\.(?!setProperty\(\s*['\"]--)")
hits = [f"{p}:{n}" for p in pathlib.Path("src").rglob("*.js")
        for n, line in enumerate(p.read_text().splitlines(), 1) if pattern.search(line)]
print("\n".join(f"FAIL {hit} sets a style directly" for hit in hits))
sys.exit(1 if hits else 0)
```

### CSS example

```css
.order-progress-bar { inline-size: var(--progress, 0%); }
```

## Sources

- [HTML Standard on the style attribute](https://html.spec.whatwg.org/multipage/dom.html#the-style-attribute)
- [CSP Level 3 style-src](https://www.w3.org/TR/CSP3/#directive-style-src)

## Related rules

- [Fail the build on broken rules](https://agentwranglers.se/playbook/engineering/rules-as-code/build-gates) in Engineering

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets">Agent Wranglers HTML and CSS playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Keep media and container queries with their component](https://agentwranglers.se/playbook/html-css/structure-and-files/queries-with-the-component)
- [Structure and files](https://agentwranglers.se/playbook/html-css/structure-and-files)
