Before CSS came along, HTML did not have a version specifically dedicated to styling. But, back in the days when I started creating webpages around 1996, I still managed to style and layout pages using HTML's attributes and tags. I remember doing a lot of copy-pasting to get the right look by reusing those inline styles and trying to tweak everything. It was a nightmare, but it worked for the time.
<form action="submit.php" method="post">
<font face="Courier New" size="-1" color="red">
<input type="submit" value="Submit">
</font>
</form>
....
<table border="5" cellpadding="10" cellspacing="5">
<tr style="background-color: lightblue;">
<th style="background-color: yellow;">Name</th>
<th>Age</th>
<th>City</th>
</tr>
....
Here’s a rough timelineof HTML and CSS:
- (1995) HTML 2.0: it did not include any style specification. It was purely about structuring the content.
- (1996) CSS1: CSS was introduced as a separate standard in 1996 with the aim of separating content from presentation. It allowed developers to define styles for elements like fonts, colors, margins, padding, and layouts in external stylesheets.
- (1997) HTML 3.2: Introduced some presentational elements like
<font>
,<center>
, and<marquee>
, which helped control basic formatting. - (1999) HTML 4.01: By the time HTML 4.01 was finalized, the role of CSS had become much clearer. It emphasized the separation of structure (HTML) and presentation (CSS). Moreover, it encouraged the use of external stylesheets for more flexible and maintainable design.
- (2000+): In the new millennium, CSS gained more widespread support and became the standard for styling HTML pages.
Okay, let's talk about how web design got a whole lot easier around mid 2000.
Before then, making websites look good was a real pain.
People used clunky <table>
layouts or messed around with CSS hacks, which were a nightmare to keep working.
It was a wild west of inconsistent design.
Then, Nathan Smith created the 960 Grid System (Smith, 2008).
It was a game-changer because gave us a simple grid to work with, usually 12 or 16 columns, so we could easily create balanced and organized layouts.
"The 960 Grid System is an effort to streamline web development workflow by providing commonly used dimensions, based on a width of 960 pixels" (Smith, no date).
The 960.gs was not just cool on its own; it kicked off a whole movement. Other grid systems and layout frameworks popped up, like Blueprint CSS and early versions of Bootstrap. These tools all helped make grid layouts the standard way of create websites. They made design more modular and predictable, which meant less headaches for designers and developers.
Approaches to CSS architecture
After 960.gs different CSS approaches emerged as practical responses to the challenges of complexity, maintainability, scalability, performance, and collaboration. Each methodology offers solutions tailored to different requirements, allowing teams to choose the one that best fits their development style and goals. Some of these are:
- BEM (Block, Element, Modifier): Emphasizes component-based architecture and a strict naming convention (Yandex, no date). It breaks down the UI into "blocks" (independent components), "elements" (parts of a block), and "modifiers" (variations of a block or element).
- SMACSS (2011): Focuses on categorizing CSS rules into five categories: Base, Layout, Module, State, and Theme. It provides a general framework for organizing CSS, emphasizing scalability and maintainability, encouraging modularity (Snook, 2011).
- Atomic CSS (or Functional CSS): This approach focuses on creating very small, single-purpose CSS classes (e.g., .bg-red, .f-bold, .m-10). HTML elements are styled by combining multiple atomic classes. While it can lead to very small CSS files and good reusability, it can also result in verbose HTML and make it harder to understand the styling at a glance (Vukelic, 2023). A popular example is Tailwind CSS.
- OOCSS (Object-Oriented CSS): OOCSS encourages thinking of CSS styles as reusable objects. It emphasizes separating structure from skin (visual appearance) and containers from content. While it shares some similarities with BEM, it doesn't have as strict a naming convention (Lazaris, 2011).
- ITCSS (Inverted Triangle CSS): ITCSS is a methodology for ordering CSS rules based on specificity and scope (Help Scout Developers, 2025). It starts with low-specificity, global styles at the top and gradually increases specificity and scope as you move down the stylesheet. This helps manage specificity and prevent conflicts (Roberts, 2014). ITCSS can be used in conjunction with other methodologies like BEM or SMACSS.
The methodologies mentioned (BEM, SMACSS, Atomic CSS, OOCSS, and ITCSS) generally focus on organizing and structuring CSS to improve maintainability, scalability, and collaboration. They emphasize clear naming conventions, modularity, and separation of concerns, but they don't specifically advocate for a lean and minimized HTML. Why?
History about Maintainability, Consistency, Modularity, and Flexibility
In the last chapter, I presented some of the most popular CSS approaches used today. I left you with the question of why they don't specifically advocate for lean and minimized HTML. The answer lies in the past. Early work by software engineering leaders already addressed the tension between making systems flexible, maintainable, and modular (or whatever adjective you prefer) and the risk of increased complexity or diluted focus of the original design. They warned that pursuing these qualities, if not carefully balanced, could create more problems than it solves, ultimately preventing the intended goals from being reached.
The "Software Engineering: Report on a Conference Sponsored by the NATO Science Committee" is one of the earliest works that discusses software engineering as a discipline. It features discussions on the trade-offs between modularity, maintainability, and other system qualities. One of these was the trade-off between flexibility and simplicity. Some speakers warned that flexibility often introduces extra layers of abstraction or generalization. This might be useful in theory, but in practice lead to over-engineer systems which only increased complexity without adding much value (Naur and Randell, 1968).
The book "Structured Programming" by O.-J. Dahl, E.W. Dijkstra, and C.A.R. Hoare (1972) also touches on the unintended consequences of over-complicating the design. The authors suggest that programmers must carefully consider the trade-offs between the clarity gained through abstraction and the potential impact on efficiency. Dahl and Hoare say it's important to use abstraction carefully. Just because it can make code easier to maintain and understand does not mean it's always the best idea. (Dijkstra, Hoare and Dahl, 1972).
In the book "The Mythical Man-Month" by Frederick P. Brooks (1975) the author discusses many aspects of software development, including the balance between modularity and complexity. He warns that adding flexibility and modularity can increase the complexity of the system, leading to a situation where the system may lose focus on its core objectives or become more difficult to maintain than originally intended. Brooks mentions how increased modularity often introduces additional overhead and communication costs, which can lead to inefficiencies (Brooks and Brooks, 1975).
I can go ahead with many others examples, but I believe that the concepts is now clear: Focusing too much on things like maintainability, consistency, modularity, and flexibility can distract us from our main goals and lead to wasted effort and resources without right balance.
The separation of structure (HTML) and presentation (CSS) role
While I look all these theories about the modern CSS approaches, I believe that the authors have lost the principal role of CSS: "The separation of structure (HTML) and presentation (CSS)". Let's go practical.
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
This is an example taken from Bootstrap. Why does it use "btn btn-primary"?
- Separation of Concerns: The class "btn" provides base styles, padding, border radius, font size, cursor changes, etc. common to all buttons. "btn-primary" applies the specific modifier styles, like background color and hover states for the "primary" button type.
- Reduce size of CSS: If we merge btn and btn-primary, we need a unique class for every combination, e.g. btn-primary, btn-secondary, btn-large, etc... This would increase the size of the CSS file and reduce maintainability due a code duplication.
Let me bring up an insightful point about the nuance of "Separation of Concerns" in this CSS context. The NIST define "Separation of Concerns" as
"A design principle for breaking down an application into modules, layers, and encapsulations, the roles of which are independent of one another." (NIST, no date)
So, in term of pure software engineering "btn btn-primary" is not a SoC because it is not dividing a program into distinct modules or layers. Instead it is defining a structure by cascade. The first class is the base style and the second define specific modifier styles. The CSS does not have true inheritance in the object-oriented programming sense, but it mimics some of the characteristics of inheritance through the cascade. The browser applies the styles from both classes, so "btn-primary"'s styles will override or add to the styles defined in "btn".
On point 2 we are in presence of a false economy. With tools like Sass, the argument about reduced CSS size and maintainability due to separate classes becomes less compelling. You can define your base btn styles in Sass, and then easily create variations using mixins, functions, or extending the base class.
.btn {
// Base styles: padding, border, font, etc.
}
.btn-primary {
@extend .btn; // Inherit base styles
background-color: blue;
// Primary-specific styles
}
.btn-secondary {
@extend .btn; // Inherit base styles
background-color: gray;
// Secondary-specific styles
}
Let's see another examples
<div class="d-lg-none">hide on lg and wider screens</div>
<div class="d-none d-lg-block">hide on screens smaller than lg</div>
....
....
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
In the HTML above we can see how we are controls the margins, spacing, or any other style INSIDE the HTML. Do we have separated structure (HTML) and presentation (CSS) role? Clearly no.
Conclusion
The first time I saw this code I felt shocked for the first 3 milliseconds and then started to laugh for a good hour.
<button type="button" class="btn btn-primary position-relative">
Alerts <span class="position-absolute top-0 start-100 translate-middle badge border border-light rounded-circle bg-danger p-2"><span class="visually-hidden">unread messages</span></span>
</button>
106 characters for a class definition?
I believe I am not the only one frustrated with some "modern" approaches to CSS architecture. The examples I provided in this document use Bootstrap's utility classes. The core idea behind utility classes is to provide a large set of pre-defined CSS rules that can be quickly applied to HTML elements, this allows developers to rapidly:
- prototype and build layouts without writing custom CSS for every little thing
- diminish their capacity for crafting elegant, semantic HTML and well-structured CSS, replacing it with a frantic scramble to assemble the longest possible class attribute strings.
Do we have separated structure (HTML) and presentation (CSS) role? Clearly no. Unfortunately, the last point is not just a sarcasm, but a sad reality which I will cover in the next article.
Remember: healthy planet, joyful people, shared prosperity.
Ciao
References
Brooks, F.P. and Brooks, F.P. (1975) The Mythical Man-month. Reading, Mass. ; Don Mills, Ont. : Addison-Wesley Publishing Company, pp. 53–60, 205–228.
Dijkstra, E.W., Hoare, C.A.R. and Dahl, O.-J. (1972) Structured programming. Academic Press, pp. 175–219.
Lazaris, L. (2011) An Introduction To Object Oriented CSS (OOCSS), Smashing Magazine. Available at: https://www.smashingmagazine.com/2011/12/an-introduction-to-object-oriented-css-oocss/ (Accessed: 2 February 2025).
Naur, P. and Randell, B. (1968) SOFTWARE ENGINEERING. Available at: http://homepages.cs.ncl.ac.uk/brian.randell/NATO/nato1968.PDF (Accessed: 2 February 2025).
Roberts, H. (2014) Hello, Serbia! Available at: http://csswizardry.net/talks/2014/11/itcss-dafed.pdf (Accessed: 2 February 2025).
Smith, N. (no date) 960 Grid System, 960.gs. Available at: https://960.gs/ (Accessed: 2 February 2025).
Smith, N. (2008) 960 Grid System | SonSpring, Sonspring.com. Available at: https://sonspring.com/journal/960-grid-system/ (Accessed: 2 February 2025).
Snook, J. (2011) Home - Scalable and Modular Architecture for CSS, Smacss.com. Available at: http://smacss.com/ (Accessed: 2 February 2025).
Vukelic, H.Y. (2023) The broken promise of atomic CSS - Hajime Yamasaki Vukelic - Medium, Medium. Available at: https://medium.com/@hayavuk/the-broken-promise-of-atomic-css-4d3de5e25886 (Accessed: 2 February 2025).
Yandex (no date) Quick start / Methodology / BEM, en.bem.info. Available at: https://en.bem.info/methodology/quick-start/ (Accessed: 2 February 2025).