Agent Wranglers

Site architecture Recommended

Give every module its own class names

Give each module its own class names, so one module's styles can never reach into another.

How to do it

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.

Example

// 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 ')}`);
}
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))}')

How to 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.

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.