Skip to content
GitHub Copilot is now available for free. Learn more

Artwork: Violet Reed

The modern web’s underrated powerhouse

It’s one of the most important yet under-appreciated building blocks of the internet.

Klint Finley // February 14, 2023

The ReadME Project amplifies the voices of the open source community: the maintainers, developers, and teams whose contributions move the world forward every day.

Consider this web page you’re reading right now. The links, headers, and paragraph breaks are marked up with HTML. But Cascading Style Sheets (CSS) really define the look and feel of it: the colors, the fonts, the column widths, the placement of all the various boxes and elements. If you’re looking at this page on a mobile device, it’s CSS that makes it look right on a smaller screen.

JavaScript and its sprawling ecosystem of tools and frameworks garner the lion’s share of attention in terms of job listings, courses, and online discussions. But CSS is a core skill for front-end and full-stack developers, and the CSS ecosystem plays a crucial and often underrated role in shaping the experience of using the modern web. CSS helps define not just the look of a page, but how pages adapt to different sizes and contexts. It’s foundational for both usability and accessibility on the web.

Though it’s not a full-fledged programming language like JavaScript, CSS is incredibly powerful. Take a look at designer, front-end developer, and artist Lynn Fisher’s website A Single Div, where she draws complex illustrations using only CSS, or her old portfolio site that changes wildly as you resize it, for examples of just how much you can do with CSS.

Once a fairly limited and restrictive approach to styling pages, CSS has become a highly adaptive system for designing web applications, thanks to the dedicated community around it. Developers like Fisher and others have long pushed the limits of what’s possible in CSS. Meanwhile, the open source ecosystem has crafted tools to address common challenges and extend the language’s abilities. Modern CSS is the result of more than two decades of experimentation and practice—and it continues to evolve to meet the ever-changing needs of web and mobile developers.

The frustration years

Designers and developers who have taken the time to learn CSS deeply find the language a joy to work with: Nearly 80% of respondents to the 2021 State of CSS Survey said they enjoy writing CSS and in 2022, only 3.3% of respondents said they were unhappy or very unhappy with CSS. There’s some selection bias, of course: Those choosing to answer this survey are probably more likely to have chosen to write CSS as part of their careers. But it also reflects how CSS has evolved over the years from an often frustrating young technology into a mature and robust cornerstone of modern web development.

In the early days of the web, developers and designers had no ability to style pages. There was no way for designers to specify what fonts a web page should use, or even what color the background should be. Those decisions were generally made on the browser side. Tim Berners-Lee’s first version of HTML didn’t even include tags for bold or italics, though they appeared soon after. As a result, all web pages pretty much looked the same to users—for example, the NCSA Mosaic browser defaulted to black text on a gray background with blue links.

The question of whether to give developers the ability to specify styles was actually pretty controversial.

“Web authors had asked for more influence over the document presentation and welcomed this development, but there was also resistance in the web community,” CSS co-creator Håkon Wium Lie recalled in his PhD thesis in 2005. “Many felt that the web had the potential of realizing personalized publishing where the reader—rather than the publisher—was in control.”

Others, such as Netscape founder Marc Andreessen, advocated for presentation to be incorporated into HTML instead of defined through a separate language. Multiple proposals were advanced and different browsers implemented different solutions. Netscape, for example, added support for new, non-standard HTML tags to give developers more control over the presentation of their pages.

Wium Lie wrote that one major goal of CSS was to negotiate “between the needs and wishes of readers and authors.” CSS provides a compromise between the two by enabling both end-users and developers to define styles, and having browsers resolve the differences. Processing multiple, potentially conflicting styles, is what the term “cascading” in CSS refers to. Though presentation is now primarily defined by sites, rather than users, today’s browsers still typically use stylesheets to set default fonts and other presentation elements, and users can install browser extensions to override sites’ stylesheets to customize their look and feel.

The first draft of the CSS specification was published in 1996, but adoption was slow. Browsers added CSS features piecemeal, resulting in a fragmented experience for developers because different browsers would render the same CSS code in different ways, depending on which CSS features they supported.

As browser support expanded over the early 2000s, developers pushed the limits of what was possible with CSS, creating complex, magazine-style layouts. Developer and web historian Jay Hoffman pointed to the launch of Wired and ESPN’s website redesigns in 2002 as a turning point for the language. Another landmark was the launch of CSS Gardens in 2005. This site, curated by Dave Shea, demonstrated the power of CSS to radically alter the appearance and layout of a page by changing only the CSS, not the underlying HTML.

But creating complex layouts wasn’t necessarily the aim of CSS. “It was clear back then that most of the CSS features we were using for designing web pages had not been created for that purpose,” says State of CSS Survey organizer Sacha Greif. Floats, one of the main tools used for CSS layout in the early 2000s, were intended for word wrapping and other relatively simple positioning purposes. Developers had to execute clever hacks and work-arounds, sometimes even taking advantage of bugs to “trick” browsers into displaying the layouts they wanted, such as setting margins to negative numbers to get an element to appear in the right place. Even something as seemingly simple as vertically centering an element on a page wasn’t as straightforward as it seemed it should be. These “off-label” uses, however, probably contributed to the frustration many faced when working with CSS and helped inspire many a meme—such as those coffee mugs with the text “CSS is awesome” flowing outside the borders of a box. CSS could present a steep learning curve, and many web developers relied instead on brute force to make their sites look the way they wanted. Because different browsers supported different parts of the CSS specification, developers also had to find work-arounds to make their CSS code compatible with all major browsers. Combined, these factors lent to a view of CSS as a difficult and uncooperative technology in its early years, hampering its adoption.

“In the early 2000s, I redesigned my employer’s website using CSS,” says Miriam Suzanne, a developer and member of the W3C’s CSS working group. “They ended up rejecting it because they didn’t think CSS was ready at the time.”

Still, many developers were drawn to CSS. “It always just clicked for me,” says Mark Otto, Principal Design & Brand Architect at GitHub and co-creator of the Bootstrap CSS framework. “I liked the declarative nature of it. Even the quirks made me want to learn. It was a really exciting time.”

The visual nature of CSS also made it appealing to many budding developers. “I found CSS really approachable,” says Fisher, who got her start by editing LiveJournal templates in the early 2000s. “You could change something in a code editor, then see the change reflected almost instantly on your site. It was a visual way to learn.” She also points to the ad-hoc open source CSS community that emerged on LiveJournal as a key resource. “People were sharing their code snippets and explaining how they did things,” she says. “It didn’t seem scary, it just seemed like something everyone on LJ was doing.”

UX Design

Open source to the rescue

The late 2000s saw a number of developments that not only made life easier for CSS developers but paved the way for later improvements in CSS itself.

Starting in the early 2000s, the Web Standards Project organization began releasing a series of compatibility tests to gauge how standards-compliant different web browsers were. Internet Explorer 8, released in 2009, was the first version of IE to pass the Acid2 standards test. It was the first time Internet Explorer could be relied on to offer an acceptable level of feature parity with other major desktop browsers of the time. Although developers had to continue supporting older browser versions for years to come, and the rise of mobile browsers created new challenges, this marked a major milestone in standards compliance and made it easier for developers to write CSS code that worked roughly the same way across modern browsers. 

Meanwhile, an ecosystem of open source tools emerged to make life easier for CSS developers. One of the most important of these was the "Syntactically awesome style sheets" (Sass) pre-processing language, first launched in 2006 by Hampton Catlin. Sass provides front-end developers with a number of features that enable them to work with CSS in a more programmatic way, such as nested classes that make it easier to group related CSS code together, or variables that make it simple to define a property once (a background color, for example) and then use it throughout a project.

Developers compile their Sass code into standards-compliant CSS code they can use on websites. That might sound complicated, but it actually made working on large CSS projects less complex. “I worked at an agency during the early days of Sass and there were a lot of strong opinions at the time,” Fisher says. “What tipped the scales towards ‘yes’ was the ability to more easily import and combine different CSS files so we didn’t all have to work in one giant file.”

Sass was soon joined by other CSS processing languages like Less (short for “Leaner Style Sheets”) and PostCSS. Frameworks, meanwhile, enabled developers to spend less time fiddling with getting different page elements to line up correctly or making padding work in different browsers. One of the first frameworks to garner a wide user base was Bootstrap, released in 2011 by Otto and Jacob Thornton, who worked for Twitter at the time and started it as an internal project.

The basic idea was to provide a set of pre-built design components that fit the company’s style guidelines—today we might call it a design system. “It was an easy way to make things ‘Twittery,’” Otto explains. “Very few folks at the company had a solid understanding of CSS at the time. I wanted to provide a way for people to build things faster without overextending myself.”

As adoption took off within Twitter, Otto realized that the framework could be useful outside the company as well since it had many compatibility work-arounds baked in and included predefined layouts that developers could customize, rather than write from scratch. Bootstrap adoption outside Twitter was similarly rapid. 

Many other open source frameworks followed. The most popular today, according to the State of CSS survey, is Tailwind. Creator Adam Wathan says the project aimed to hit a sweet spot between not using vanilla CSS and using a more opinionated framework like Bootstrap. But in doing so, it ended up challenging some of the prevailing wisdom about how to best write CSS.

Traditionally, you’re encouraged to keep a strict separation between the CSS and HTML—as demonstrated on the CSS Zen Gardens site—with CSS often living in a separate file from HTML markup. Tailwind, on the other hand, has developers specify styles throughout their HTML. The reason for separating the two is to make it easier to modify one without affecting the other. But Wathan argues that this isn’t the way it works in practice. “Separation of concerns never really existed in HTML/CSS,” he says. “You have to write CSS with reference to the underlying structure of your HTML and, realistically, when you change HTML you have to make changes to the CSS and vice versa. People are trying to do something that’s never really worked and it comes at a high cost.”

Tailwind’s approach was controversial at first, but it skyrocketed to the top of the State of CSS Survey charts, demonstrating that there was room for multiple different approaches to CSS.

The state of CSS

These efforts to improve the CSS developer experience helped shape the development of the ever-evolving CSS specification itself.

Tools like Bootstrap helped demonstrate how much easier layout could be in CSS, validating the idea behind two of the most important CSS features of the past 10 years: Flexbox and Grid. Both features help developers create responsive layouts that adapt to the size and dimensions of different screens without having to resort to hacks or work-arounds, helping alleviate some of the biggest pain points for CSS developers. “Today you might not like how a given CSS feature works, but at least that feature is a tool designed for the specific task you’re trying to achieve,” Greif says. “There’s a big difference between having to parse through blog posts and Stack Overflow answers every time you need to center something, and being able to rely on just reading the docs for CSS Grid or Flexbox.”

Other features were inspired more directly by the open source ecosystem. CSS now supports variables (known as “custom properties” in CSS) and will soon natively support nested rules—two ideas pioneered in Sass. “There was a lot of back and forth between Sass core contributors and W3C spec-writers,” says Suzanne, who is both a core Sass contributor and W3C working group member. “Sass could move faster than the W3C. We could experiment and validate ideas that might later become full-fledged CSS features.”

However, the way things like grid layouts or variables work in the CSS standard is quite different from the way they work in Bootstrap, Sass, and other third-party tools that pioneered this functionality. “We can’t just copy features straight from third-party tools like Bootstrap or Sass,” explains Lea Verou, a computer scientist and instructor at MIT who has co-authored several CSS specifications and is now a W3C Technical Architecture Group member. “We have different constraints when designing specifications, especially with regards to performance. We work closely with the community, including browser makers, to balance all potential trade-offs in new features.”

“CSS has to work on every screen, and even in places where there is no screen, like screen readers or smart speakers,” Suzanne adds.

Another much-anticipated new feature is “container queries,” which makes CSS layouts even more adaptive. Tools like Grid and Flexbox already make it easier to resize elements based on the size of a screen. Container queries, which Suzanne worked on, allow you to apply styles to elements based on the size of their containers, rather than the size of the screen. For example, you could use different font sizes within a column depending on how wide it is.

Verou, meanwhile, has been finalizing updated specifications for how color is handled in CSS. One major new feature is “relative color syntax,” which enables you to define a color as a calculation of the components of another color, in any color space. “For example, if you wanted to have the color of some text become darker when you mouse over it, you would traditionally have to specify the color you want it to change to,” Verou explains. If you wanted to change the original text color, you’d have to manually update the darker color as well. Now, developers can simply specify how much they want to lighten or darken a color in different contexts.  “Being able to express the relationship means that every time you change A, B just adapts without your intervention. This is basically the software engineering principle of ‘don’t repeat yourself.’” Many of these new features are pushing CSS to become far more adaptable to different environments. “Historically, CSS has been a very precise language,” Fisher says. “You specified the exact look and position of things. Now, CSS is becoming smarter and better able to adapt the page based on a set of parameters for different scenarios, instead of requiring a lot of instructions.”

“It’s more about giving the computer a set of constraints and having it decide how to style the elements based on those constraints,” Suzanne says.

Verou emphasizes that anyone can contribute to the future of CSS. “I joined the W3C’s CSS specification mailing list in 2010 and started sharing my ideas and eventually I was invited to the CSS Working Group,” she explains. “Today we do our work on GitHub instead of a mailing list.” 

She says the best way to get involved is to start reading existing proposals and get a sense of why different features are, or are not, added. “Not every idea is going to get traction,” she says. “But anyone can participate.”

About The
ReadME Project

Coding is usually seen as a solitary activity, but it’s actually the world’s largest community effort led by open source maintainers, contributors, and teams. These unsung heroes put in long hours to build software, fix issues, field questions, and manage communities.

The ReadME Project is part of GitHub’s ongoing effort to amplify the voices of the developer community. It’s an evolving space to engage with the community and explore the stories, challenges, technology, and culture that surround the world of open source.

Follow us:

Nominate a developer

Nominate inspiring developers and projects you think we should feature in The ReadME Project.

Support the community

Recognize developers working behind the scenes and help open source projects get the resources they need.

# For Newsletter

Every month we’ll share new articles from The ReadME Project, episodes of The ReadME Podcast, and other great developer content from around the community.

Thank you! for subscribing