Skip to content

Learning CSS

(Ongoing)

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.

Activity

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.

Hi there!

With all the summer holidays and various other things going on, it took me a bit more time to go through this module. But now it's done! This one was all about Typography and Images. Even though it may seem trivial at first, there's actually a lot of nuance.

First of all, I must confess my relation with these. And the truth is that it's almost non-existent 😅️. When it comes to fonts, most of the time I use the default from the system. If anything, when an app deserves its own branding, I choose a single font and use it everywhere (for example, I'm using Montserrat for Media Kraken and Livvic for Umai). I do take advantage of font weights and sizes to add some variety, but that's as far as I go. My approach to images is not much better. I usually have a single image that is big enough for most screens, and that's it.

I was well aware, even before taking this module, that I have a lot to improve here. But the thing is that for the types of products I work on, these things are an after-thought. As has been made clear with the content in this module, doing these properly takes a lot of time and dedication. And quite honestly, in my list of priorities, these are at the bottom. Still, I appreciate their importance, and I've learned a thing or two in these lessons that I'll be able to apply right away.

One of the first lessons of the module makes a great point that hadn't downed on me. The exact same website is very likely to look different in different devices (even if the screen has the same resolution). Which is obvious if you think about it, there are differences in browsers, operative systems, etc. But I had this idea of "pixel-perfect design", and how websites should be implemented that way. Many things in this course so far have reaffirmed it, like the attention to detail I mentioned in previous entries. But other things like fluid design, and the rendering quirks introduced in this module, make me think otherwise. In reality, the way designs should be implemented is with specific rules, rather than pixels. For example, if something should have a given margin, it shouldn't be in order to make look exactly as you see it in your design tool. It should be to conform to a certain layout (like the popular 12-column grid), or align to other elements in the UI. Other than that, content should flow freely through the screen, and grow or shrink depending on its contents.

Other than getting conceptual insights, I also learned about a couple of specifics. I was already aware of Google Fonts and similar websites, but I had been downloading and configuring them by hand to remove the dependency with Google. Turns out there are some tools out there, like this google-webfonts-helper, that make the process seamless. I also found about a couple of CSS features I didn't even know existed, like the font-display property to configure font loading strategies, the concept of line break opportunities to understand how text wraps, the <picture> element to control multiple image sources, etc. I was also glad to see one of my biggest pet peeves mentioned: using the optional line length for text readability (50 to 75 characters per line). I learned about it in Refactoring UI, and ever since I noticed it, I haven't been able to make any UI without following that rule of thumb.

There is still a lot more I have to learn on the topic of Typography and Images, but this module was definietly a good overview of everything that is important. I'll be sure to revisit it in the future if I ever want to go more in depth.

I didn't think I'd be posting any more updates this year, but I finished the Grid module just in the nick of time!

At first, this module seemed shorter than usual. But when I got to the workshop, I realized I was wrong. It's definitely been one of the longest workshops of the course, but I cannot say I've enjoyed it tremendously. In fact, I don't think I have enjoyed any of the workshops too much. They are quite good nonetheless, but compared to the enjoyment of taking the lessons, they fall to average. I think the reason why I don't like them too much is that I feel like I have to do a lot of work for something I don't care too much about. And being forced to use Styled Components and React doesn't help, because I still don't like them :/. But I have to recognize that some times, it's necessary to roll up your sleeves and do the work to solidify the concepts learned. Though I enjoy the small exercises in lessons a lot more, and I'm thankful the entire course is not like this.

Anyhow, besides the slog of a workshop, I also enjoyed this lesson overall. I haven't been using grid much, and as is becoming tradition in this course, I noticed how little I knew about it. But this time, I'm not sure I'll be using this too much, because I feel like I can do mostly everything with Flex. Though I'm sure there will be some situations where grid will come in handy. If you want to learn about it yourself, Josh recently published a blog post going over the basic concepts: An Interactive Guide to CSS Grid.

And that's mostly everything I have to say about grid, but in the periphery of taking this module I read a couple of his posts I'd like to mention:

The first one tackles exactly the point I mentioned in my last update about pixel-perfection. Other than learning pure CSS, these are the things that are making this course so interesting to me. I am a developer who enjoys design, but unfortunately I don't do as much of it as I'd like. And learning about things like designing on top of a screenshot is golden. The second one tackles collaboration with designers, and I've always thought that the work I've enjoyed the most in my carreer has been working alongside designers. I hope I can do a lot more of that in the future.

When I started this task I wouldn't have believed I'd still be working on it a year later. In the course FAQs Josh mentions that it should take an average of 40 hours to complete, and so far I've spent more than 50. But if anything, I have to say that's a good thing, because I'm still enjoying it like the first day. What's even more amazing, is that the last two modules could be the ones I enjoy the most: Animations and Little Big Details. And they also seem to be some of the longer ones! So there is still plenty of juice to squeeze.

And here we are, one module away from the last!

As I anticipated, this one about animations was great. One of the things I've always aspired to do with my apps is to make them enjoyable and fun. Or as Josh puts it, more whimsical. This module was all about that.

It is one of the modules I've enjoyed the most, but ironically it's also one of the modules where I've learned the least new "features". I was already familiar with mostly everything introduced, but it has been very interesting to learn about Josh's explanations of how and why to use animations. For example, I've always used timing functions almost at random (or not at all); but Josh lays down a theory of when to use which and what to consider. I also got some terminology for things I've been doing but didn't have a name for, like Orchestration. And I learned about the importance of Spring physics and the FLIP technique (now I know why I've heard so much talk about Framer Motion).

But there is also something bittersweet about this lesson. There was a lot of "this is beyond the scope of this course", specially for the parts I was more interested about. Which is understandable, given that this is a course about CSS and not animations specifically. But that makes me hope, maybe some day we'll be able to see a course of his about animations? That would be awesome!