---
title: "Give every module its own class names · Agent Wranglers"
url: https://agentwranglers.se/playbook/website/site-architecture/module-class-names
updated: 2026-10-20
licence: "All rights reserved"
---

# Give every module its own class names

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [Site architecture](https://agentwranglers.se/playbook/website/site-architecture)
- Rule: Give each module its own class names, so one module's styles can never reach into another.
- How: Start a module's class names with the module's name, such as `menu-panel` and `menu-toggle`. Keep a short, written list of shared utilities, such as one text style. Make the build fail when one class name styles two kinds of element, such as a list and a panel. Check in a browser that nothing inside the content is fixed in place, except popovers.
- Check: Reuse another module's class name on a different element. The build stops and names the class and both pages.
- Measured: On a reference site, a new menu panel reused the class name of a chapter list. The list became a fixed overlay on one page, while screenshots of the other pages looked fine.

Example:

```js
// One class, one kind of element, unless it is a listed shared utility
const SHARED = new Set(['lede']);
const seen = new Map();
const kindOf = tag => /^(ul|ol)$/.test(tag) ? 'list' : /^(a|button)$/.test(tag) ? 'control' : /^(p|span|h[1-6]|li)$/.test(tag) ? 'text' : 'block';
for (const [, tag, classes] of html.matchAll(/<([a-z0-9]+)\b[^>]*\bclass="([^"]+)"/g)) {
  for (const name of classes.split(/\s+/)) {
    const kinds = seen.get(name) || new Set();
    seen.set(name, kinds.add(kindOf(tag)));
  }
}
for (const [name, kinds] of seen) {
  if (kinds.size > 1 && !SHARED.has(name)) console.log(`FAIL class "${name}" is used on ${[...kinds].join(' and ')}`);
}
```

```python
import re
SHARED = {"lede"}
def kind_of(tag):
    if tag in ("ul", "ol"): return "list"
    if tag in ("a", "button"): return "control"
    if re.fullmatch(r"p|span|h[1-6]|li", tag): return "text"
    return "block"
seen = {}
for tag, classes in re.findall(r'<([a-z0-9]+)\b[^>]*\bclass="([^"]+)"', html):
    for name in classes.split():
        seen.setdefault(name, set()).add(kind_of(tag))
for name, kinds in seen.items():
    if len(kinds) > 1 and name not in SHARED:
        print(f'FAIL class "{name}" is used on {" and ".join(sorted(kinds))}')
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/site-architecture/module-class-names`.

- Previous: [Build repeated HTML from shared modules](https://agentwranglers.se/playbook/website/site-architecture/shared-html-modules-only)
- Next: [Keep the previous build's assets](https://agentwranglers.se/playbook/website/site-architecture/keep-the-previous-build-s-assets)
- [Site architecture](https://agentwranglers.se/playbook/website/site-architecture)
