January 21, 2018
•Last updated November 5, 2023
On Functional CSS
As my career takes a big shift from being only myself to a team of 20+ I've become more aware of the importance of best practices and scalability with regards to web design and development. This post is a quick discovery session on functional CSS and why it's changing the way I author code.
CSS at its core is a language that paints the web. We can do some fantastic things with CSS that many years prior were never before possible. Everything from inline styles to abstracting all of our styles into an external stylesheet seemed like huge improvements not 10 years ago.
Today, we are animating with CSS, defining abstract grids, and even creating full-fledged illustrations. We can create variables and use preprocessing technologies like Sass or Less to otherwise write object-oriented style code.
The question that still has yet to be completely solved is How does CSS scale?
Semantics
A long time (and still very common) approach with CSS is the seperation of concerns philosophy. This path leads us to only include the necessary markup and content in our HTML
and leaves the rest to be styled by CSS
.
This would otherwise look like this:
<style>
.intro-headline {
font-weight: bold;
font-size: 42px;
text-align: center;
}
</style>
<p class="intro-headline">
Hello World!
</p>
The class name intro-headline
describes the content at hand and then hooks into the CSS
style.
This is still a way I used to like to write CSS. Although it's a bit less reusable, I can quickly scan and understand what it is my CSS
and HTML
are accomplishing together. The problem here is that our CSS
now absolutely depends on our HTML
.
In the video, I shared an author bio card example as shown below. This takes the seperation of concerns idea and applies it to a realistic example.
<style>
.author-bio {
background-color: white;
border: 1px solid hsl(0,0%,85%);
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
overflow: hidden;
max-width: 320px;
margin: 1rem auto;
> img {
display: block;
height: auto;
}
> div {
padding: 1rem;
> h2 {
font-size: 1.25rem;
color: rgba(0,0,0,0.8);
}
> p {
font-size: 1rem;
color: rgba(0,0,0,0.75);
line-height: 1.5;
}
a {
color: teal;
}
}
}
</style>
<div class="author-bio">
<img src="https://cdn-images-1.medium.com/fit/c/320/260/1*I0n0hH7JNeB0vo2PyKrpSw.jpeg" alt="Andy">
<div>
<h2>Andy Leverenz</h2>
<p>Andy is a designer, developer, and maker of things. He works at <a href="https://dribbble.com">Dribbble</a>, runs the blog <a href="https://web-crunch.com">Web-Crunch</a>, and enjoys food very much.
</p>
</div>
</div>
Check out the code pen below for a full preview:
See the Pen semantic-css by Andy Leverenz (@andyleverenz) on CodePen.
With this HTML
and CSS
I can now assume an element with the class of author-bio
will inherit the card-like styles I'm after. It made sense to me to write this way but it always still felt a little fuzzy. I would debate with myself on how often I could/should reuse this author-bio
class in my code. A lot of styles are being repeated that could otherwise be substracted into more reusable classes that do one thing.
Opting for reusablity
I have recently linked an article by Nicolas Gallagher called About HTML semantics and front-end architecture. He touched on points regarding proper semantics and why things are the way they are. My takeaway from this article is that writing scalable code is an absolute must when working on a large scale thing. Writing reusable CSS
is the ultimate way to win when challenged with such a feat. Doing this is ultimately why functional CSS or atomic CSS is a thing.
Functional CSS
Jon Gold of Airbnb kicked off my immediate interest in functional CSS
. At first, it feels dirty writing in such a way but you begin to see why it works well in practice. My advice to you is to build something real with it and see how it feels. At first, you'll likely hate it like I did because it resembles writing inline styles but I think the thing you'll love is the fact that there doesn't need to be a massive amount of CSS in your arsenal to create something great.
Having a codebase already intact also makes for a thrilling use case for functional CSS
. Imagine being able to delete 500+ lines of CSS and rather use just a few more class names in your HTML
.
Ok, so what is it and why should I care?
I'll use a favorite framework called Tachyons to demonstrate the concept. The pen below creates a user list with the following actions. Inside the markup, you'll see a ton of class names that might freak you out at first. Peaking into the SCSS
pane you should notice that these classes are only responsible for 1-2 things on average.
The point here is that these classes can be used virtually anywhere to build anything. Only use what you need and get rid of the rest. Tachyons, for example, comes in many flavors. You can use them all by simply linking to a stylesheet or import only the node modules you know you'll be using.
See the Pen tachyons example by Andy Leverenz (@andyleverenz) on CodePen.
While the class names aren't immediately descriptive you learn to understand what it is they do and how you can combine them to build great UI.
The issues with this approach
- It can feel dirty writing so many classes in your
HTML
. - Sometimes you need very specific refinements in your styles and this approach limits this. A quick, but the dirty solution is to actually use inline styles as opposed to creating a new functional style that you may never reuse. Crazy I know...
- If you're writing the
CSS
grid this approach can be a challenge to do with classes. Flexbox, on the other hand, is a perfect fit.
The perks of this approach
- Scales well
- Multiple people can use the same naming conventions to accomplish things more consistently
- Modularity. Use and reuse classes wherever you like; the way they are supposed to be used.
- Less
CSS
= Better performance
Worthy reads and resources
Functional CSS isn't something you just go and begin writing without some growing pains. If you work alone or in a small group functional CSS
might not be a great candidate for you. The concept was given birth to those who work in a team setting where multiple people need to be able to understand what's happening site or app-wide.
With all of that said I invite you to do some of your own research to see how functional CSS could make an impact on your own design and development workflow.
- Adam Wathan - CSS Utility Classes and "Separation of Concerns"
- Nicolas Gallagher - About HTML semantics and front-end architecture
- Jon Gold - Functional Programming, CSS, and your sanity
- Adam Morse - CSS and Scalability
- Adam Morse - What are classes for?
- Brent Jackson - 5 Ways to Not Shoot Yourself in the Foot with CSS
- Tachyons
- Basecss
- Tailwind
Categories
Products and courses
-
Hello Hotwire
A course on Hotwire + Ruby on Rails.
-
Hello Rails
A course for newcomers to Ruby on Rails.
-
Rails UI
UI templates and components for Rails.