Skip to content

Learning CSS


After 10+ years making websites, you'd think I already know CSS. And I guess I do, but I don't really know CSS. As Josh W. Comeau puts it: "if you don't learn how its underlying systems work, your mental model will always be incomplete.".

So I am taking his course, CSS for JavaScript Developers.


Task started

I have a love/hate relationship with courses and educational resources. The ones I like, I like a lot. But I struggle to find the ones worth putting my time and money into. We have something called EduCash at Moodle HQ, which is a training allowance given to employees to spend in these type of courses. And for the 3 years I've been at Moodle, this is the first time I've used it! So that tells you how excited I am to take it :).

I first heard about this course from Adam Wathan's recommendation, and after checking it out I read one of Josh's posts. That really sealed the deal for me. Actually, if you're reading this and want to learn more, I strongly suggest that you check out the articles on his blog. There are lot of free resources in there that I'm sure you'll find very useful.

So far, I've only taken the introduction and a recap of the fundamentals. I didn't get into it intending to journal about it, but right off the bat he's encouraging students to learn in public. So I had no excuse 😂️.

The fundamentals module is a quick overview of the basics of CSS, which of course I already knew. But it's still been useful to clarify some nomenclature, and I even learned a couple of things. I learned about the :last-of-type pseudoselector, and that you can use shift+click in the developer tools to switch between color representations (hex, rgb, hsl, etc.). I also found out that you can see the contrast ratio of colors in the picker, which I hadn't noticed. So I'm sure those will be useful at some point.

I just finished two more modules of the course: Rendering Logic I & II.

When I started this task I was somewhat worried that I'd be giving away too much of the course by journaling what I learn. But now, I'm totally convinced that's not the case at all. The content goes extremely in depth. Even when he talks about things I've been using for years, I feel like I'm back in university being told about a new concept alien to me (which is awesome!).

So yeah, I still totally recommend the course :D. I will refrain from bringing up this point in every update though, or it'll get tedious. But I've been blown away by Josh's teaching, and I'm sure I'll be following him for years on end.

Now, about what I've actually learned in these two modules. They tackle some of the most basic properties you can think of: width, display, position, etc. But instead of just explaining what the properties do, the modules introduce the mental models to understand why they work the way they do. Which also includes learning about new properties and tricks, but that's the least important.

In particular, these concepts were new to me:

Other than learning about the concepts, exercises are also quite fun. Even though you think by reading the lessons that you already understand everything, the exercises did get me to notice something I'd missed in a couple of occasions.

And finally, workshops have also been great. What I noticed in these is how hard it is to get rid of bad habits :/. I'm so used to writing CSS with trial and error when something doesn't work, that it's difficult to actually think about the underlying mental models of the language. But after some dedication, I did manage to apply the learnings from the course.

In module 3, the course takes a small detour from pure CSS to foray into the world of building UI components. And it is done with Styled Components as our guide.

I'd heard of Styled Components before, but I'd never used them. In fact, I didn't like the idea of CSS-in-JS at all. But I took this module with an open mind and it wasn't as bad as I thought. Although I still prefer TailwindCSS :D. There is actually a page in the course comparing many of the popular approaches to building CSS, including Tailwind, and I have to agree with mostly everything Josh says. To me, the killer feature in Tailwind though is that you don't have to think about naming. And unfortunately, Styled Components still has that problem. Still, it was nice to learn about a new tool.

In any case, the tool is the least important in this module. The real point is to learn how to build UI components. One of the things he mentions from the get go is that he doesn't think it's a good idea to use component libraries for "real" projects, but they are good for prototyping or small endeavours. And I strongly agree with that, I've actually worked with a bunch of component libraries in the past, and there isn't a single time I haven't regretted it. They key problem I see with them is that it's usually fine to build cookie cutter UIs, but as soon as you want to do something more unique, you're in for a world of pain.

What I enjoyed the most from this module was the exploration of different UI Component design techniques (design in terms of architecture, not UI). There is a lot of nuance, but these are some lessons I would highlight:

  • There are 3 ways to tackle customizations: composition, variants, and contextual styles.
  • It is important to reduce the API surface (number of props) as much as possible.
  • Convention over configuration: Make it easy to follow the defaults, but possible to break from them.
  • Inversion of control nesting: Declare child styles in the component itself, not the parent.

Other than that, as ever, I also learned about a couple of features I didn't know: Tagged templates, the revert CSS value, and Chrome Live Expressions.

I just completed module 4, which was all about flexbox.

If there was ever a good example of a CSS feature I've been using a lot but didn't understand, this is it 😅️. I've been building almost everything with flexbox, and I've ran into some issues here and there, but for the most part I thought I had it under control. Well, after taking this module I just realized how wrong I was. To be fair with myself though, I did know 80% of its mechanisms; and it isn't like I was using it "wrong". But this definetly took me to the next level.

One of the things that keeps blowing my mind in this course is learning the underlying mechanisms of the language I wasn't aware of. Which is funny, because I consider myself a bottom-up learner, but for some reason when it comes to CSS I've been flying blind my whole life. In this module, I've learned about the core concepts that explain the way flexbox works: Hypothetical size, primary axis vs cross axis, justify vs align, items vs content, etc.

At the end of the module, there is a review that was very helpful to solidify all these concepts. If you're curious about them, you can check it out yourself in this blog post: An Interactive Guide to Flexbox.

In these lessons I've also realized how much attention to detail Josh puts into his UI. I'm no designer, but I enjoy working with UI and I like to think that I pay attention to detail as well. But I still learned some things I've been missing in my own designs. For example, aligning the baseline of text. This also made me realize how powerful flexbox really is, because it can do some crazy stuff with nested flex containers that are not obvious at all. Can't wait for module 9, "Little Big Details"!

Finally, in order to speed-run through all the important concepts, I took Flexbox Froggy again. I'm glad to say I completed it in a breeze, with two exceptions. In level 10, you have to use justify-content: flex-end;, and I'm still using justify-content: end; instead. Which is not completely wrong, but it can be an issue in some situations, so you're better off using the flex-* values. I also struggled to complete the last level, to the point that I had to look at the solution :(. But hey, the important part is that I really understood everything! I'm sure that before I would've been baffled as to why the CSS worked at all.

After almost 3 months, I'm finally done with Module 5: Responsive and Behavioural CSS. I've dedicated the same time as usual (1 hour a week), so I guess that means this module was longer. The workshop was specially challenging, since it took me like 3 to 4 hours to complete.

The lessons were interesting and touched on a topic I'm very fond of. But this time I was already familiar with most of the concepts, as I've always kept responsiveness in mind. Although something I don't think much about is fluid design. Essentially, responsive means that you have different styles depending on the breakpoints, whilst fluid means that values scale with the size of the viewport. Both have their pros and cons, and Josh gives some compelling arguments to use both as necessary.

This module also introduced CSS variables, which reminded me of something I forgot to mention in previous updates. One way to think about CSS is as a collection of algorithms; the layout algorithms. And you can see properties as the arguments to these algorithms. For example, even though the width property has the same name, it can have completely different behaviours on a display: block or a display: flex element. Using this mental model, CSS variables and all their quirks are a lot easier to understand. You can learn more about that idea in this post: Understanding Layout Algorithms.

In summary, overall I enjoyed this module as well. But this time, there was something I didn't like: the code stack :/. In module 3, I learned about Styled Components and it was fun to learn something new. But now it's starting to become annoying, since working with TailwindCSS is a lot easier (not to mention React vs Vue). It was annoying to the point that completing the workshop felt more like a fight against the tools than learning CSS. Hopefully, it won't be much of an issue for the remainder of the course.