Formalize utility-first css preference
Proposal
Let's formalize a "utility-first" CSS preference (this is different than "utility-only"):
- Start with utility classes.
- If composing utility classes into a component class removes code duplication and encapsulates a clear responsibility, do it.
Why?
- "utility-first" encourages the organic growth of component classes.
- It prevents the creation of one off not reusable classes.
- It keeps component classes cohesive, since they can be combined with other utility classes.
- It also encourages the creation of design-centered classes (e.g. button, alert, input), rather than domain-centered classes (e.g. security-report-widget, commit-header-icon).
Inspiration:
Description
Throughout all Frontend projects, it is unclear when to prefer utility classes vs. component classes. Let's formalize our preference and add it to our FE documentation.
What are utility classes?
.d-flex.prepend-top-default.append-bottom-default
Bootstrap4 introduced many utility classes that each apply a single CSS rule. We've also adopted this pattern and created some custom utility classes. These are helpful for quickly overriding styles that are highly specific.
What are component classes?
.component-header
This is the common practice of creating CSS classes that encapsulate a logical set of rules.
Analysis
What are our goals?
- Increase maintainability
- Reduce CSS bloat
Advantages of utility classes:
- Prevents the need for one-off CSS classes that are never reused
Disadvantages of utility classes:
- Harder to read
- Harder to edit in the browser inspector
- The set of utility classes applied to an element is not reusable (although the Vue component itself is reusable)
Advantages of component classes:
- Easier to read
- Easier to edit in the browser inspector
- Reusable
- Semantically describes the HTML element
Disadvantages of component classes:
- When reused in the wrong place, it can cause coupling of unrelated elements, hurting modifiability.
- Naming of these classes can easily be inconsistent and unintuitive (e.g. wrapper, container, content, etc.
Conclusion
There is nothing keeping us from doing both, but using either inappropriately leads to a brittle style sheet. utility-first
is a pragmatic way to ensure we are creating the right kind of component classes.