Philosophy
Before getting into the lower level coding recommendations we'll define what this project expects for all of its code. Composition is king.
- Containers do not assume content
- CSS for looks is separate from CSS for layout
- CSS should be semantic
- Avoid utility classes in markup
Containers and Content
By building containers that do not assume their contents it allows for greater flexibility. For instance, a column grid component usually pads in the inner content. Depending on the usage of the grid this "gutter" may not be desired. To overcome this developers usually have to add negative margin to their inner children to overcome the assumptions made by a container.
Another reason for containers to not assume content is around composition. It is much easier to build up quality user interactions when the components are easily mixed together. As soon as containers assume what is inside, the ability to easily compose components into larger components goes away.
Separate Layout and Looks
CSS is used for both layout and looks via styles. However, when building reusable and scalable CSS it is best to separate classes that are the core layout of a component and the classes that give looks to the component.
For example a button class should give the structure of a
button. In order to enhance the button to look a certain way a class
for looks should be added, for example button--primary.
These recommendations relate back to composition. By having a clean separation it is easy to compose different variations of a core component without having to rely on a lot of complex overrides.
Semantics
CSS must be semantic. This leads to easier to maintain code
and code that can grow. A good example here relates to colors and
alerts. It would be a bad idea to create a class color-red.
A much better choice is color-alert--critical.
Semantics allow for the lower level color to change and keep the meaning in the code.
Utility Classes
Avoid creating and using utility classes. At first glance it may seem okay to add a "remove all margin" class or a "no left padding" class. However, these types of classes usually highlight a flaw in the existing components. The question to ask is "why do I need this one-off change?"
There will be cases that a utility class is needed, however, these classes
should be mixed into a more semantic class. For example, if an article on
a page needs to remove the left padding give that a better name for the
specific type of article that needs to remove that padding. Maybe the
article is picture heavy, give it class name of article--picture-heavy.