How do you write CSS when you hate it
From CEe-ESS-ESS to CEe-ess-Yes!
I hate CSS.
Okay, I hate CSS. When learning to write code, CSS can seem like an inoperable black box. The dual task of deciding what something should look like and then making it look like this seems impossible. This naturally led to a deep-rooted hatred of art as a whole.
However, it turns out that a lot of the aversion stems from not having the process in place to build and write good CSS rules. As I moved between building an application from scratch and jumping into a code base that was already built, I started compiling small pieces, not the rules themselves, but the things that worked, you know, like there were rules but it was good for us anti-dictators. One day, I went into work and realized that I really added fuel to the fire by having my todo list of tasks that day…… And all of their CSS.
My cat, Ellis, had a shocked and surprised look on her face
Shock. Awe. Mild to moderate terror. In the name of a hand-built component, how does this happen?
CSS, it turns out, is ultimately just like any other type of programming. It’s first and foremost a problem decomposition task, and once you have a neat set of discrete to-do items, it’s just as satisfying and enjoyable as any other type of programming (fight me, Internet).
Below is a collection of standards and practices for writing effective CSS. It’s far from the only way — if you just delete one thing from this article, hopefully having a system is more important than having the system, but if you don’t have one, it’s a good place to start. With just four fairly simple guides, you can hate CSS even more than you do now.
1. Classes are for styles.
Tags are used for semantics and ids are used for references.
Each CSS rule I write is associated with a class, and ideally, only one class. From the beginning, this meant that when I looked at my documentation and tried to understand why it looked the way it did, I knew exactly where to start tracking down the CSS rules that applied, and it helped minimize code conflicts with unpredictable results and pasta.
This is the key to keeping my CSS clean and organized, and it pays great dividends for the availability of any application that applies it as a principle. This payoff is a good old coding favorite: separation of concerns. In this case, separate visual presentation from semantics.
If you’re writing HTML correctly (or, let’s be honest, your JSX, because who’s writing HTML these days), Your
codec probably doesn’t have a lot of S in it – why does
But well-written semantic HTML means that you select elements based on what they do on the page and what their content means, not how you want them to look. An
is the most important context in your view, not “You want large text and stylized signage fonts.” Although many times these two concerns will flow together and occasionally they will diverge, if you have your style < H1 > written on it, then you have two options:
- You can write some extra CSS rules so that you have
<h1 class="special-not-big-h1">
(Or worse,<h1 id="special-not-big-h1">
thisindeedCan cause some heartache), increasing the complexity of the code base and reducing its readability. (Which, if you do it once, won’t be such a problem, but we all know how quickly these tips and special situations start to add up, right?) - You may decide not to
<h1>
Use it for the important content of the view, keeping your page hierarchy unknown to people using screen readers or other assistive technologies. That’s really bad.
However, if you don’t give < H1 >’s the dual responsibility as both a semantic element and a style setter, then all you have to do is not add that particular class to a special case element. Wouldn’t that be easier? And cleaner?
The point here is to break the psychological link between “semantic elements” and “visual style.” If you want “big text”, put it in your CSS and don’t look for an element that doesn’t necessarily belong there.
2. BEM will prevent changes to elements from becoming verifiable garbage fires (CSS CTF paradigm)
BEM stands for “Block, Element, Modifier” and is a set of naming conventions that help keep CSS organized. There are quite a few naming convention systems out there, and no one is the best choice for all situations and projects — just like CSS systems in general, having one is more important than having any particular system. But BEM is very convenient, and I think it’s a good place to start various applications (in part because it’s well known, so it’s not hard to explain to new developers joining your project in the future), so let’s talk about what it is and why it’s great.
BEM divides our CSS rules into three categories, which provide logic for how to apply visual styles to your HTML. Rather than treating each visual requirement as a separate task, BEM encourages you to think about the overall structure of your view and decompose your style accordingly. No matter where you store YOUR CSS, all your rules should be divided into these three parts (organized hierarchically or alphabetically, wherever it makes sense to your team).
- block: blocks are independent entities in code that contain meaning completely independently. Good examples are headings, input, menus, check boxes, etc. A block essentially contains all of its own rules without relying on or referring to the parent element. Block classes are defined without underscores or hyphens and use camel case to separate different words, for example:
.button
..mainNav
..orderedList
. (Often, you’ll see a single hyphen used in BEM to separate words in a block, as this is the more common CSS convention outside of BEM, but I personally think it leads to visual confusion in element and modifier naming and adds the possibility of typos). - The element: Elements are components of a block, and their names should be semantically associated with their parent block. They don’t work as separate parts — we’re talking about things like navigation links, list items, or input headings. Elements are named after their parent block, followed by their own descriptive names, separated by two underscores:
.mainNav__link
..orderedList__item
..checkbox__caption
. - The modifierModifiers are flags that can be placed on blocks or elements to change the appearance or behavior of a particular item (often, these are your special cases and must be treated differently for color, size, or location). The: modifier is named by appending two hyphens, followed by a descriptive name in a block or element
.button--danger
..orderedList__item--last
..list--collapsed
, and so on. Modifiers are also where I group the style rules for pseudo-classes, because that’s essentially what they are.
It was hard for me to really see the utility of this system until I took an existing project and migrated it to the BEM convention. The next set of features/views I built went much smoother than the previous ones, and I was completely overwhelmed.
3. Accessibility is a good design guide
Sometimes, I know it’s hard to believe, but bear with me, you’re writing code that doesn’t have high-fidelity, full-featured wireframes. Sometimes your graphic designer sucks, or doesn’t exist, or is working on 12 million other projects that aren’t part of your daily workflow. Increasingly, front-end and full-stack Web developers are expected to do, at least in part, the work of a designer.
So if you’re trying to develop your own aesthetic, and you just don’t know where to start, consider first what can visually make your application usable. And naturally, when I say useful, I mean use as many people as possible, not just current able-bodied people (that’s what we’re talking about, where’s the guy on the right?). .
The benefit of developing accessible applications is that, in most cases, they make for a better experience for all of your users, no matter how they use your content. If you’re not sure how something should look, start thinking about how to design it in a way that works for as many people as possible. Make sure the line height is at least 1.5em, the font size is large enough, the color contrast is 4.5:1 or higher, and the line length is limited to 80 characters or less per line. And never use color alone to convey important information to your users (especially, especially red and green).
True accessibility is beyond the scope of this article, but I encourage anyone who writes code, especially code that touches the UI, to learn more about it and to actively advocate for usable, accessible design within the team. Deque offers extraordinary online courses for anyone with an Internet connection (and a full scholarship for anyone with disabilities), and the World Wide Web Consortium (W3C) has a list of how to meet different levels of accessibility criteria for people who don’t have Deque resources, or just need a quick reference check. Even if you do this by having a designer work with you at every step, they probably know more about accessible design than you do, and the voice of someone who knows what’s going on behind the scenes can be important.
4. The only good Shame is shaming.css
I wish I was smart enough to come up with the phrase and concept of sham.css. Alas, I didn’t, so I must first give credit and praise to Harry Roberts, a true CSS wizard, for explaining what shame.css is and why it’s so handy here and here.
But let me talk to you about how and why I use it in my projects or the projects I work on. I’d be lying (and unconvincing) if I told you THAT I consistently followed all the principles I’ve outlined here 100% of the time. Sometimes you just need to modify the title to look like a million times, and you don’t want to go in and add a new class on top of all the titles. Sometimes you need something fixed now – now – now ** and clean code has to take a back seat to functionality. Sometimes, it’s a Friday afternoon and you’re just too tired to think straight. Whatever the reason, sometimes you’ll do it the easy way instead of the right way.
These things happen, and if we pretend they don’t, we lose the opportunity to control the damage they cause.
Type, sham.css: When you write some hack-y and rough CSS, own it. Put it in your own special CSS file (or just along the fourth section /* blocks */, /* elements */ and /* modifiers * – have /* FIX THIS SHIT ASAP */ section too). Now your code is running, but you’ve taken steps to ensure the future – you won’t deal with a mess of bad style in the future.
The key to shay.css (just for the record, in my own code I usually call it “to-fix.css” or “hacks.css”, just to be less negative and blame it) is that part of your workflow now has to go back to that file, And actually sort out any CSS mistakes you make in the name of a quiet life. Ideally, you should address your next low mood as soon as possible, but since these are difficult to achieve organically, I like to schedule time formally no less than once a week. Monday morning can actually be a great time — it’s a great way to unwind the week and score some not-too-difficult, moral victories that don’t require a lot of decision-making.
Whenever you do this, just make sure you do it, otherwise, you’re not reducing complexity, you’re just neglecting your own system.
As always, I’d like to hear where you think I went wrong, what you think I missed, and how you could make it better. How do you start hating CSS less? How is it better for you to start?