9 min read
CSS, a vast and unknown universeMastering CSS for Efficient Web Development
My first interaction with CSS was back in 2009/2010. I wanted to customize a Blogger website and started playing around with it. Since then, I’ve seen this ecosystem evolve, and to be honest, I’ve been lost and might be at the moment.
I decided to learn more CSS long ago and had the opportunity to collaborate with great CSS experts that taught me a lot. My goal here is to put some order to spare ideas and concepts. So, please consider this post as some notes that I’ve been collecting over the years. The content will follow this structure:
- Origins: standard and implementations
- Style Optimizers
You could jump from section to section and choose your reading order. But you should follow the one I proposed because every section is a new building block that adds value to the previous one. I’m following a bottom-up approach.
Origins: standard and implementations
Is CSS a programming language?
No, CSS (Cascading Style Sheets) is not a programming language. It is a stylesheet language used for describing the look and formatting of a document written in HTML or XML. CSS is used to control the presentation and layout of web pages, including colors, fonts, and spacing. While it is an essential part of web development, it does not have the features of a programming language, such as logic, conditionals, and loops.
A bit of background
The World Wide Web Consortium is the organization in charge of maintaining the CSS Standard. Experts in the fields and representatives of different companies comprise the CSS group.
This group has meetings where they prioritize and vote on the inclusion of new features to the standard, and later on, different browsers will implement those features.
CanIUse is a great resource to check which browser supports a CSS feature.
I wanted to add this information because it is crucial to understand that adding a new CSS functionality is not trivial.
Every browser implements its version of the standard. We would expect the default values they apply for every attribute to be the same, but unfortunately, that’s not the case. So, when running your website in different browsers, the UI could have small changes you can’t control.
Some tools help to keep a consistent design across different browsers. They reset the default values of every property to some default values. Examples:
In this post, Elad Shechter analyzes Normalize and Reset, adding real examples of how and why to use them.
|Separate structure from look and feel||Use HTML for structure and CSS for colors, margins, typography, etc|
|Structure and group styles||Be more efficient for reuse and maintenance|
|Ensure consistent appearance across browsers||Make websites look consistent across different browsers|
What have we learned?
- CSS is not a programming language. It is a language used to style HTML elements in a website.
- There is a group of people that maintain the standard.
- Every browser implements the standard.
In computer science, a preprocessor (or precompiler) is a program that processes its input data to produce output that is used as input in another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers. Wikipedia
What is a CSS Preprocessor?
A CSS preprocessor is a scripting language that extends the capabilities of regular CSS by allowing developers to write more maintainable and dynamic stylesheets. It provides additional features and syntax not available in native CSS, such as variables, nesting, mixins, functions, and more.
What do they add to the standard?
CSS preprocessors aim to add missing functionalities to the standard in a friendly way to simplify the developer’s life. So, let’s see some examples:
|Variables||Used to store and reuse values throughout the stylesheet|
|Mixins||A way to group a set of CSS declarations and reuse them throughout the stylesheet|
|Functions||Similar to mixins, but they return a value instead of a set of CSS declarations|
|Nesting||Allows you to write nested selectors, which can improve readability and organization|
|Imports||Used to bring in external CSS files into the current stylesheet|
The previous elements can help us with the following:
|Reusability||Code that can be used multiple times, making it efficient and less repetitive|
|Maintainability||Code that is easy to update and modify over time, reducing the likelihood of errors|
|Readability||Code that is easy to read and understand, making it simpler to maintain and modify|
It’s interesting to observe how some tools appear to fill some gaps in the standards. This is something I’ve already covered in one of my previous posts. But over time, once preprocessors proved the actual need for those missing functionalities, the CSS standard included some of them. Good examples are variables in 2012, grids in 2015, and in January 2023, a draft for nesting.
In the last twenty years, different preprocessors have appeared:
But there are many options out there:
- CSS Blocks
- CSS Modules
- CSS-in-JS: Emotion
- CSS-in-JS: Styled Components
- CSS-in-JS: JSS
I’d like to make some special mentions and clarifications, sharing my experience using some of the previous ones.
Sass is one of the most famous preprocessors. Popular frameworks and libraries like Angular Material Components rely on it.
For developers using tools like the previous one could be pretty handy because, out of the box, you have many features.
BE CAREFUL!! The usage has downsides; I lost track of reality for a while and couldn’t distinguish CSS from SASS, thinking that nesting or even mixins were part of the standard.
In React ecosystem, and due to the usage of JSX, the usage of tools based on CSS-in-JS is very popular. Some popular libraries like Material UI come with it.
We are again in the same situation; it was exciting when I transitioned to React world; learning a new way of writing CSS felt exciting.
Soon, I was in the same dark place I was with SASS not long before; I started to have problems distinguishing actual components from styled ones.
Another alternative is PostCSS, the default preprocessor used by NextJS (a trendy React framework).
This preprocessor is interesting because it is a plugin system. So, for example, if you want to use CSS Modules, Nesting CSS, or any other functionality, you can add/install a new PostCSS plugin.
This “pluggable” system is fascinating because you could create your plugin to cover a missing functionality on the preprocessor.
Going back to NextJS and analyzing the package.json on v13.1.2, we can identify that the framework comes with the following PostCSS plugins:
The good news, on this case, is that they’re adding some pretty basic stuff that most of the devs expect or are used to, but the list of PostCSS plugins is massive
What have we learned?
- A CSS preprocessor is a scripting language that extends CSS.
- The CSS standard keeps evolving and including new functionalities, sometimes the most popular across preprocessors.
- Many preprocessors are in the market, and different frameworks/libraries can use different ones by default.
- Mastering the standard will give you confidence and make your life easier when transitioning between these tools.
As the size of CSS resources in a project increases, a development team often must decide on a standard design methodology to keep them organized. Wikipedia
What is a CSS Methodology?
A CSS methodology is a set of guidelines, conventions, and best practices for writing maintainable, scalable, and well-organized CSS code. These methodologies provide a systematic approach to structuring CSS in a way that makes it easier to understand, maintain, and collaborate on, especially in large-scale projects with multiple developers involved.
Why could it be beneficial?
Bridging a methodology to your team or codebase will provide some benefits:
|Consistent name conventions||Common languages among developers|
|Improve reusability and maintainability||Easier to introduce changes|
|Clear and readable code||Better organization|
|Keep code DRY (Don't Repeat Yourself)||Prevents unnecessary repetition in the codebase|
As always, it comes with some challenges, especially initially. Before you integrate it, I suggest analyzing your situation: codebase size, number of projects, seniority of team members, and previous knowledge or experience with existing methodologies.
As you can see, many options exist, and any of them can bring many benefits and especially consistency to your codebase:
I had the opportunity to work with some of them, and I like the predictability of the code.
It’s easy to end up with a “messy” code where different devs apply their version of the chosen methodology, being hard to maintain or even identify the right/wrong way of using it.
What have we learned?
- CSS methodologies offer guidelines for creating organized, maintainable, and scalable code in large projects with multiple developers.
- Implementing a methodology improves naming consistency, reusability, maintainability, and adherence to the DRY principle.
- Selecting a methodology involves assessing codebase size, project number, team members' seniority, and prior methodology experience.
Some utilities are crucial but not popular. I’m talking about style optimizers. These tools can be grouped into different categories. Let’s learn about it.
What is a Style Optimizer?
A CSS Style Optimizer is a tool or a set of tools that help improve, optimize, and maintain the quality of CSS code. These tools assist developers in writing clean, efficient, and well-organized stylesheets, ensuring better performance and easier maintenance.
|Formatting and linting||Ensure consistent code formatting and enforce best practices||Prettier, Stylelint|
|Vendor prefixing||Adds necessary vendor prefixes to CSS properties, ensuring better cross-browser compatibility||Autoprefixer, ACSS|
|Minification and optimization||Optimize CSS code by removing unnecessary whitespace, comments, and redundant rules, leading to smaller file sizes and faster loading times||CSSNano|
Using these tools over your existing codebase can add some benefits, like
|Consistency||Streamline code formatting and style rules for better collaboration and maintenance|
|Error prevention||Linting tools catch errors and enforce best practices, reducing debugging time|
|Enhanced collaboration||Uniform code styling and organization promote easier teamwork and code comprehension|
|Maintainability||Organized and optimized CSS improves understanding, updates, and maintenance|
|Time-saving||Optimizers automate tasks for increased focus on other project aspects|
|Performance||Optimizers reduce file sizes and remove unused styles for faster loading and better performance|
What have we learned?
- Improve code consistency, making collaboration and maintenance easier.
- Enhance website performance by reducing file sizes and optimizing styles.
- Automating tasks like linting and formatting saves developers time and effort.
A CSS architecture brings reasoning to CSS authoring. Imagine it as a set of guidelines and best practices to help developers write code that’s maintainable, flexible to scale, and more reusable. CSS Architecture
What is a CSS Architecture?
CSS architecture refers to a set of organized principles, methodologies, and conventions for writing and structuring CSS code in a scalable, maintainable, and modular way. A well-designed CSS architecture makes it easier for developers to understand, maintain, and update the stylesheets in a web project, especially as the project grows in complexity and size.
As we learned, CSS Architecture is a combination of rules and standards to try to organize and maintain your codebase:
|Reduce code duplications||Easy to maintain and reuse common pieces|
|Easy-to-read||File names and folder structures can help you to understand the code|
|Scalability||In a large project or one that could grow over time, architecture will help to grow in an organized and common way|
|Onboard new team members||With a common guideline and architecture in place, it would be easier to teach new members the rules behind them|
|Performance||Reducing the amount of CSS could lead to performance improvements due to the less code needed to be loaded|
A different point of view
As we can see, Architectures usually combine some of the previous concepts, adding new ideas like file structures and naming. Some great examples of those are:
But to be honest, the best Architecture's definition I've seen is the one of Elad Shechter. He manages to combine all the concepts I’ve covered in this article and put them together in a straightforward way to understand and leverage all of them. The slides are here.
What have we learned?
- CSS architecture comprises guidelines and best practices designed to assist developers in creating maintainable, scalable, and reusable CSS code.
- By integrating strategies such as reset rules, preprocessors, methodologies, style optimizers, and defining file naming and structures, CSS architecture enhances code organization and efficiency.
- Additionally, CSS architecture streamlines the onboarding process for new team members and contributes to performance enhancements.
CSS frameworks are usually considered libraries that give you pre-made components and styles. These projects could be beneficial for speeding up development, especially in the initial phases of a project, but they come with some downsides.
What is a CSS Framework?
A CSS (Cascading Style Sheets) framework is a pre-prepared library of code that helps developers create visually appealing and responsive web designs more efficiently. It provides a standardized set of styles, components, and structures that can be used as a starting point for building web pages or web applications.
Some popular ones
Frameworks tend to provide some standard functionalities like:
|Common elements||Buttons, forms, navigation, alerts, cards, modals, tables|
|Grid systems||Organize content into responsive columns and rows|
|Utility classes||Helper classes for everyday tasks like spacing and alignment|
Good and not-so-good parts of using them
|Faster development and consistency||Learning curve|
|Responsiveness and cross-browser compatibility||Limited flexibility and dependency|
|Community support||Dependence on updates and maintenance|
What have we learned?
- Frameworks help us with faster development, consistency, responsiveness, cross-browser compatibility, and uniformity.
- They provide common elements, grid systems, and utility classes.
- Downsides include a learning curve, limited flexibility, dependency, and uniformity.
In the intro, I mentioned that this journey has been going on for 14+ years at the moment I’m writing this post. During that period, I had the chance to learn a lot about CSS, and I worked as a native mobile developer with Android and iOS apps. I learned Xamarin at some point. Before that, I had some experience in desktop app development with Java Swing or even Visual Basic.
What I mean by this is that I’ve seen different ways of defining styles in UIs. They all have pros and cons, but after learning about the CSS ecosystem, I’m astonished, overwhelmed, and extremely excited.
The CSS ecosystem is massive and complex, but at the same time, it is very powerful and exiting. It has a unique vocabulary and combines software and programming concepts with design ones.
Did I manage to master it? Not yet, and honestly, I’m not sure I will because it’s evolving super fast and adding more and more capabilities every year.
I’ll do my best to keep up to date and continue adding new skills to my toolchain, and that is my advice to all of you, keep learning and enjoy the journey.