The key to understanding CSS is to get past the notion that frontend development is about producing visuals. Visuals are one aspect, but we never make them directly. We make it easier for ourselves when we stop thinking about the interface as significantly related to the image. Two different techniques producing the same visual result will be of varying quality. One can be lengthy, fragile and increasingly convoluted, while the other is flexible, logical and to the point.
Claims about CSS being broken, Family Guy memes, the nail polish emoji and aggressive frustration about not understanding the language, although they are turn-of-the-century developers, come from lacking understanding of what is being built. When we want the language to be something it’s not, we actively work not to understand it.
Underestimated programming #
Imagine we have three buttons and want to align one to the left and two to the right. As beginners, we work on each one individually. We make it work by building each additional element on top of the previous. But they don’t wrap nicely on smaller screens; the last button’s margin cause indentation on a new line, and the spacing between the first two disappear entirely. We add vertical spacing to the first two, but not the last, because we don’t want more spacing below the total. But the buttons don’t align on the bigger screen anymore. So we add some breakpoints and just let the buttons fill the width of the small screen.
And we hope we don’t have to add another element because the code spans over twenty lines at this point, and we don’t know if it can take any more without breaking.
If this resembles our experience with CSS, either our approach is wrong, we haven’t practised enough yet, or we underestimate CSS. And if we think CSS is not a programming language, we can check all three and continue to slowly write fragile and increasingly difficult code. All of this, we can turn around by adjusting our approach and keep practising.
System and cascade, not visual #
CSS doesn’t place elements explicitly on a page; it has never been a coordinate-based layout system similar to graphics software – which is why so-called design software is a dead end, but that’s a different story. Like programming in general, CSS is a set of instructions that give predictable output; we never work directly with the result. CSS is a way to calculate the elements and the relationship between them in the environments that render them.
If we try to use the language like a graphics editor, where each element has its shape and place until we tell it otherwise, we fail to make it work to anyone’s advantage. We ignore the cascade, the C in CSS, and use it primarily for styling, the first S. And we get frustrated by messy code and unexpected behaviour because we actively don’t use the language’s strength for systemising inheritance and logic.
When we approach it like programming instead of drawing with words, we recognise the myriad of unknowns in the users’ environments and can program flexibility to handle it.
Think in conditionals #
CSS is a bunch of conditionals with built-in ifs and for loops. There are also functions like where(), not(), has() and is() to extend and modify the default. While relatively straightforward, they can produce some of the most complex selectors when we need them to. And it’s all logic; CSS does what we tell it to.
We write good CSS by working on elements in bigger contexts. When we have three buttons, we control all at once by working on the parent element. We look at how they relate to each other and how they will flow and wrap using a suitable and logical layout method, like flexbox or grid. We define what happens regardless of a change in the number of items. When we do this repeatedly, we recognise which properties different element combinations need. And we expand the same concepts until we have our entire layout.
Logical predictability #
Understanding CSS and frontend is not only about working syntax but also about concepts and approaches. It also requires an understanding of HTML. HTML is not the paint-by-numbers sheet, and CSS is not the colouring pencils. When we write frontend, both languages affect each other and work together as calculations that render differently, but functionally, in every user’s environment.
In the button example, we can probably solve it with an extra division element and a few lines of tidy CSS. It gives us solid and predictable behaviour, which we’re after. It’s not about the shortest solution or the fewest elements but an element structure we can program.