Disclaimer, these are some free-form thoughts I am accruing while I work on this website. Some of this information may not be useful
Most people I know learned CSS by first using a framework like Bootstrap, and then slowly adding CSS selectors for custom elements. CSS itself is not a language taught in many courses, and a lot of work goes into cursing at layouts while googling StackOverflow on how to align elements in weird ways.
CSS itself is relatively unstructured. There are selectors and rules that are applied to elements in order of specificity, and then the cascade. It broadly follows a decorator pattern, where new styles decorate elements based on added ID’s and classes. The CSS specifies the “feature interactions”–the way combinations of classes are resolved and applied on elements. Implicitly the CSS also interacts with the HTML layout of the page, as it is able to specify sibling and nested child selectors. Thus a page’s CSS is also constrained to its HTML layout.
It seems that a designer should take advantage of specificity to style common types of elements, inheritance to control sizing, and the cascade to provide customization over other stylesheets. However, reasoning about feature interactions is not simple. A CSS stylesheet codebase is constrained by the following rules in CSS:
- Children cannot affect the styling of their parents.
- An element cannot modify its preceeding elements.
- Padding controls spacing where background-color is applied.
- Margin: auto causes elements to expand to fill space, depending on context
- Media queries do not add specificity–order matters!
- Rules cannot be removed, this makes it difficult to dynamically mix stylesheets.
Specificity by design causes issues. Styles that are too generic cause side effects, while styles that are too specific become hard to reuse or override. Thus it is important to have good architecture in a CSS project that avoids the inherent complexity of CSS.
Below is a comparison of a few ideas for CSS Architecture
SMACSS - Scalable and Modular Architecture
Based on Jonathan Snook’s Book
Advocates for a modular architecture that I would prefer not to explain.
OOCSS - Object Oriented CSS
Based on Nicole Sullivan’s Talk.
- Encapsulate page elements with CSS classes
- Apply mixin classes to elements to change behavior
- Independent CSS hierarchy for “structure” and “skins”
- structure controls positioning and hierarchy
- skins apply visual theming
- Encapsulate styles with HTML structure
- should be able to copy and paste HTML and have it look the same
BEM - Block Element Modifier
Based on the BEM website
- Blocks are a top level, independent container for a semantic item on a page.
- Elements are independent items within blocks, they have no meaning outside of blocks.
- Elements do not depend on surrounding blocks or elements
- Do not combine block selectors with element selectors
- Element selectors should be prefixed with the block they apply to
- Modifiers alter the styles of blocks or elements
- Modifier selectors should be prefixed with the element they apply to
Out of all of these I prefer BEM, as it is simple and seems to mimic common CSS frameworks. However I do not like how BEM uses elements in that they are independent selectors. This removes the ability for general purpose elements to exist within a CSS system. I do like that BEM flattens CSS structure, and moves specificity into the selector name as opposed to the traditional idea of specificity, this helps with overriding styles.