CSS: Classes Seriously Sprawling

In my previous article The systemic failure of implementing CSS principles, I took a trip back to the early days of web development, when styling was a messy mix of HTML attributes and inline hacks. When CSS was introduced in 1996, it promised a game-changing separation between structure (HTML) and presentation (CSS). This separation was meant to bring order, maintainability, and flexibility to the growing web.

I then explored the evolution of CSS methodologies, from the 960 Grid System to more organized approaches like BEM, SMACSS, Atomic CSS, OOCSS, and ITCSS. While these approaches aimed to address the increasing complexity of web design, a key question emerged: why do so many modern practices seem to ignore the very principle that CSS was designed to uphold: the clear division between content and its visual styling?

Finally, I took a critical look at today's CSS practices, using examples from popular frameworks like Bootstrap. The use of utility classes directly in the HTML raised concerns about a "false economy" in CSS and blurred the lines between structure and presentation. The long class names seemed to bring us back to the days of messy, presentation-heavy HTML, just with a different approach.

To further investigate this, I developed PIERA (Page Inspector using Element Regex Analysis). It is a simple tool to provide a quantitative structural and stylistic analysis of a webpage. By analysing the raw HTML, PIERA aims to shed light on aspects like page size, content distribution, and CSS class usage. The idea of this tool has origin to November 2022 but I have been able to work on it only this weekend ;).

PIERA analyses raw HTML by employing regular expressions to identify key patterns and data points relevant to its analysis goals. While acknowledging the limitations of regex for complex HTML parsing, this approach offers a relatively fast, dependency-free, and eco-friendly way to inspect crucial page characteristics.

The source code is available on Gitlab https://gitlab.com/naranza/piera.

I also created a simple webpage on this website where you can test it: https://www.adavanzo.com/tools/piera/.

PIERA in action

I took 5 pages from different websites. All the pages has been taken on 2025-03-30 about 13:30 and 15:30 UTC. These pages are:

  • Homepage of a website developed with Acquia Site Studio on Drupal 10
  • BBC UK home page
  • BBC UK article page
  • Tailwind CSS documentation page
  • Laravel home page

Results

Below you can see the table with a summary of the results. You can find a more detailed set of results in the appendix. While all the columns give us a idea of the impact of CSS on the web page, the column class_cascade_occurencies, offers a compelling illustration of the trends I discussed.

Page Class-structure ratio class_longest_attribute_value_bytes class_cascade_occurencies
Acquia Site Studio on Drupal 10 21.88% 392 12
BBC UK home page 11.83% 72 3
BBC UK article page 8.23% 72 3
Tailwind CSS 27.82% 695 25
Laravel 9.74% 308 21

Legend:

Class-structure ratio
The ratio between number of bytes used by class attribute values and whole page page bytes.
class_longest_attribute_value
A string containing the longest value found in any class attribute of HTML elements.
class_cascade_occurencies
The number of space-separated class names in a class attribute.

Can you believe that someone cascaded 21 or 25 classes for define a single HTML element? O_O

A new Olympic game: "Longest class attribute ever"

As this first analysis reveals, the proliferation of these lengthy and numerous class names serves as reminder of the joke I made of the CSS acronym: CSS: Classes Seriously Sprawling.

The overuse of automatically generated class names and utility-based styling has introduced significant challenges in web development. The first is the creation of an excessive "fat HTML" that impacts environment and performance. The second is that this approach tightly couple styles with markup undermines the original purpose of CSS: separating content from design.

Rather than using stylesheets for structure and reusability, these odd CSS development philosophies adopted by many modern frameworks, encourage developers to pile class names onto elements as they are competing in a new Olympic game: "Longest Class Attribute Ever".

Every byte matters

That single 72 or 392 bytes class attribute might seem small, but when I think about it multiplied across many elements on millions of websites, the impact becomes clear. Every extra byte takes energy, servers need power to store and send it, networks consume electricity to move it (International Energy Agency, 2023), and users' devices use energy to download and render it. This data reinforces the concerns around a potential "false economy" in this way of developing CSS. While the use of numerous, extremely long, utility or component-based classes might offer perceived structured or development speed, the environmental cost in terms of increased page weight and data transfer should not be overlooked. The trade-off between development convenience and the long-term impact on performance and sustainability needs careful consideration.

This is not just a performance issue, this is a form of digital waste. Just as we are learning to reduce physical waste, we must also consider the energy cost of our digital choices. A more thoughtful approach, using structured CSS, specific classes, and IDs where appropriate, would would restore some sanity to web, its users, developers, and the environment.

For me, every byte matters.

Writing cleaner, more efficient web pages is not just about elegance and efficiency from a software engineering perspective. It is more. It is a long term vision of reducing the environmental impact of what we build while giving a future to the next generations. Even the smallest decisions in our CSS/HTML structure have real-world consequences, and I believe it is our responsibility to strive for a more byte-conscious web.

Remember: healthy planet, joyful people, shared prosperity.

Ciao

References

International Energy Agency (2023) Data Centres and Data Transmission Networks, IEA. Available at: https://www.iea.org/energy-system/buildings/data-centres-and-data-transmission-networks (Accessed: 30 March 2025).

Appendix

Acquia Site Studio on Drupal 10

I took the homepage of a charity website that very likely uses Acquia Site Studio on Drupal 10, because the "coh-container": "coh-" is a common prefix used by Acquia Cohesion for its elements. Moreover, the "ssa-component" and "ssa-component-instance-" strongly suggest Site Studio Accelerator (SSA). The long string of characters following "ssa-component-instance-" is likely a unique ID for that specific instance.

page_bytes = 128103
head_bytes = 6210
body_bytes = 121462
html_tags_bytes = 105710
content_total_bytes_used = 7140
class_total_bytes_used = 28033
class_shortest_class_name = st1
class_shortest_class_name_bytes = 3
class_longest_class_name = js-view-dom-id-44eee3d16d2b0e31ca415f1aeb039a497f48d9691bc134c263ea8567de8a544d
class_longest_class_name_bytes = 79
class_shortest_attribute_value = st1
class_shortest_attribute_value_bytes = 3
class_longest_attribute_value = coh-container ssa-component coh-component ssa-component-instance-43a5af33-7311-4d62-bfd2-056ee2b32a80 coh-component-instance-43a5af33-7311-4d62-bfd2-056ee2b32a80 coh-style-section-full-width-2-column coh-component-full-width layout-component coh-style-composition-vertical  texture-tile-blue.jpg    ssa-instance-bc0a8e009d7406adec1ccf065ca7457c coh-ce-cpt_section_full_width_2_column-9cf5c2d7
class_longest_attribute_value_bytes = 392
class_cascade_occurencies = [
  "1" = 183
  "2" = 360
  "3" = 273
  "4" = 248
  "5" = 35
  "6" = 42
  "7" = 42
  "8" = 80
  "9" = 9
  "11" = 22
  "12" = 24
]
class_cascade_logest = coh-container ssa-component coh-component ssa-component-instance-43a5af33-7311-4d62-bfd2-056ee2b32a80 coh-component-instance-43a5af33-7311-4d62-bfd2-056ee2b32a80 coh-style-section-full-width-2-column coh-component-full-width layout-component coh-style-composition-vertical  texture-tile-blue.jpg    ssa-instance-bc0a8e009d7406adec1ccf065ca7457c coh-ce-cpt_section_full_width_2_column-9cf5c2d7

BBC homepage

Page link: BBC UK home page

page_bytes = 739370
head_bytes = 156004
body_bytes = 583311
html_tags_bytes = 340076
content_total_bytes_used = 11273
class_total_bytes_used = 87502
class_shortest_class_name = no-js
class_shortest_class_name_bytes = 5
class_longest_class_name = ssrcss-1t7ltsf-GlobalNavigationProduct-GlobalNavigationAccount
class_longest_class_name_bytes = 62
class_shortest_attribute_value = no-js
class_shortest_attribute_value_bytes = 5
class_longest_attribute_value = ssrcss-1t7ltsf-GlobalNavigationProduct-GlobalNavigationAccount eki2hvo17
class_longest_attribute_value_bytes = 72
class_cascade_occurencies = [
  "1" = 4
  "2" = 4432
  "3" = 363
]

BBC UK article page

Page link: "The environmental campaigners fighting against data centres"

page_bytes = 372823
head_bytes = 129976
body_bytes = 242792
html_tags_bytes = 125088
content_total_bytes_used = 10013
class_total_bytes_used = 30682
class_shortest_class_name = no-js
class_shortest_class_name_bytes = 5
class_longest_class_name = ssrcss-1t7ltsf-GlobalNavigationProduct-GlobalNavigationAccount
class_longest_class_name_bytes = 62
class_shortest_attribute_value = no-js
class_shortest_attribute_value_bytes = 5
class_longest_attribute_value = ssrcss-1t7ltsf-GlobalNavigationProduct-GlobalNavigationAccount eki2hvo17
class_longest_attribute_value_bytes = 72
class_cascade_occurencies = [
  "1" = 2
  "2" = 1552
  "3" = 117
]

Tailwind CSS

Page link: Get started with Tailwind CSS

page_bytes = 321196
head_bytes = 9162
body_bytes = 311887
html_tags_bytes = 145880
content_total_bytes_used = 4741
class_total_bytes_used = 89350
class_shortest_class_name = h-5
class_shortest_class_name_bytes = 3
class_longest_class_name = bg-[image:repeating-linear-gradient(315deg,_var(--pattern-fg)_0,_var(--pattern-fg)_1px,_transparent_0,_transparent_50%)]
class_longest_class_name_bytes = 120
class_shortest_attribute_value = line
class_shortest_attribute_value_bytes = 4
class_longest_attribute_value = group inline-flex items-center gap-3 text-base/8 text-gray-600 sm:text-sm/7 dark:text-gray-300 **:data-outline:stroke-gray-400 dark:**:data-outline:stroke-gray-500 **:[svg]:first:size-5 **:[svg]:first:sm:size-4 hover:text-gray-950 hover:**:data-highlight:fill-gray-300 hover:**:data-outline:stroke-gray-950 dark:hover:text-white dark:hover:**:data-highlight:fill-gray-600 dark:hover:**:data-outline:stroke-white aria-[current]:font-semibold aria-[current]:text-gray-950 aria-[current]:**:data-highlight:fill-gray-300 aria-[current]:**:data-outline:stroke-gray-950 dark:aria-[current]:text-white dark:aria-[current]:**:data-highlight:fill-gray-600 dark:aria-[current]:**:data-outline:stroke-white
class_longest_attribute_value_bytes = 695
class_cascade_occurencies = [
  "1" = 70
  "2" = 48
  "3" = 132
  "4" = 80
  "5" = 965
  "6" = 252
  "7" = 105
  "8" = 200
  "9" = 99
  "10" = 80
  "11" = 99
  "12" = 48
  "13" = 78
  "14" = 70
  "18" = 3168
  "25" = 150
]

Laravel

Page link: Laravel home page

page_bytes = 1180155
head_bytes = 4727
body_bytes = 0
html_tags_bytes = 1051899
content_total_bytes_used = 21477
class_total_bytes_used = 115007
class_shortest_class_name = {
class_shortest_class_name_bytes = 1
class_longest_class_name = not-motion-reduce:transition-opacity
class_longest_class_name_bytes = 36
class_shortest_attribute_value = {
class_shortest_attribute_value_bytes = 1
class_longest_attribute_value = font-medium rounded-xs transition inline-block duration-100 border border-transparent shadow-secondary-button hover:shadow-secondary-button-hover text-sand-light-12 dark:text-sand-dark-10 dark:hover:text-sand-dark-12 dark:hover:border-sand-dark-5 px-4 py-1 inline-flex! bg-white pr-1 items-center gap-2 mt-10
class_longest_attribute_value_bytes = 308
class_cascade_occurencies = [
  "1" = 728
  "2" = 1390
  "3" = 939
  "4" = 968
  "5" = 1030
  "6" = 936
  "7" = 406
  "8" = 920
  "9" = 1440
  "10" = 110
  "11" = 440
  "12" = 324
  "15" = 75
  "16" = 192
  "18" = 90
  "19" = 19
  "20" = 20
  "21" = 147
]

Author:

Date: