Code style for HTML and CSS
Semantic markup, one documented class naming scheme, design tokens, and calm stylesheets.
Rules and reasons
- Use elements for what they are: headings for headings, buttons for actions, lists for lists. Reason: accessibility and fewer scripts to repair meaning.
- Write element names, attributes, selectors and properties in lowercase. Reason: one spelling, nothing to normalise.
- Choose one class naming scheme per project and document it. Reason: a mixed scheme cannot be searched or checked.
- Prefer design tokens (custom properties) over repeated raw values for colour, spacing and radius. Reason: a change happens in one place.
- Avoid !important; document the exceptions. Reason: it breaks the cascade for everyone after you.
- Keep business logic out of markup; compute it in the layer that produces the document.
- Comments in English and about why, not what.
Braces
In stylesheets we own, the opening brace of a rule goes on its own line. If the repository has a formatter or an established style, that wins.
Generator mapping
A canonical name becomes hyphen-separated for CSS and camelCase on the DOM side.
| Canonical | CSS class | Custom property | data attribute | DOM dataset |
|---|---|---|---|---|
tab_list | tab-list | --tab-list-gap | data-tab-list | dataset.tabList |
Example
:root
{
--tab-list-gap: 8px;
}
.tab-list
{
display: flex;
gap: var(--tab-list-gap);
}
Counter-arguments
- Google's HTML/CSS guide puts the opening brace of a rule on the same line as the selector, and common formatters default to that. Own-line braces cost a line per rule and need configuration.
- Google's guide separates the words of a class name with hyphens. This convention agrees on that for CSS; where a class name must also be a code identifier, the canonical underscore form and the hyphen form differ and need the mapping above.