From
Josh Comeau
Date
January 1st, 2021
Subject
Happy New Year! My top devtips from 2020…
Not already subscribed?
Sign up so you don't miss the next issue!
Josh Comeau

Happy New Year!

A few days ago, I published my first-ever “Year in Review” post. I always enjoy reading these articles from other folks, and I felt I had a lot to say about 2020 😅.

I'll warn you now, it's pretty self-indulgent. My feelings won't be hurt if you aren't interested in hearing about how my year's gone! But if you are, you can find it on my blog.

Link to this heading
A year of tips

A couple weeks ago, I got an email from a subscriber, Karen S:

By the way, your twitter is so good that I kind of expected you to be sending some sort of ‘top picks’ to your email subscribers.

I realized that I've been operating under a faulty assumption: that everyone on this newsletter also follows me on Twitter, and has seen the tips I share!

When Twitter was first released, I rememeber people called it a "microblogging platform". And that's kinda how I use it — if I learn a neat trick, and it's short enough to fit in a tweet, I share it on Twitter instead of my blog.

In this “New Years Edition” newsletter, I thought it'd be fun to share some of my Twitter tips from 2020! Even if you happen to follow me on Twitter, I bet some of these will be new to you (Twitter is so ephemeral!).

I've broken them down into categories, for easy browsing 😄 You'll find code snippets and other resources in the linked tweets.

Link to this heading
CSS aesthetics

As its name implies, box-shadow is only really useful when you have a box, and want to give it a shadow. But what if you have a shape that isn't a box?

CSS filters to the rescue! filter: drop-shadow works just like box-shadow, but it applies to the element's contents. If that element is a .png or a .gif, it'll add the shadow to the non-transparent pixels in the image!

A side-by-side comparison of a 3D avatar with shadow. The box-shadow variant has a rectangular shadow, while the drop-shadow version has a shadow around the avatar itself

View tweet

filter: drop-shadow is just one of many awesome CSS filters! They can be helpful in all kinds of situations. I used one recently to create a neat hover animation, by rotating the hue to shift a button to a new color!

Two buttons, one blue, one pink. The pink one has a cursor, indicating that it's a hover state

View tweet

Some other aesthetics stuff I shared this year:

*Be sure to see the follow-up tweet, which addresses a potential accessibility concern with this technique.

For a long time, it's been common for desktop apps to allow users to resize sub-elements — think sidebars, panels… We haven't seen as much on the web. Let's change that!

The resize property allows end users to resize an HTML element, just like <textarea>s!

css
  • Can be restricted to a single axis (resize: horizontal)
  • Can be constrained by max-width / max-height
  • Observable with ResizeObserver, so you can react to changes

I use this nifty property in my blog post, “Full Bleed Layouts with CSS Grid”:

A 3-column demo is resized, by dragging on the corner

View tweet

Some other cool CSS layout stuff:

I've known that accessibility is important for a long time, but my experience this year with my nerve injury has really driven the point home.

Accessibility is hard, but there is definitely some low-hanging fruit. One of the best places to start is to make sure we aren't actively making HTML/CSS less accessible.

A lot of designers want us to remove the blue "focus" outlines when we click on things, since they aren't always so aesthetic. If we do that, though, we'll make it impossible for keyboard users to use our product!

This twitter thread dives into some of the ways we can solve this problem. There are some modern APIs that give us more options. It's possible to solve our problem and satisfy our design team!

Some other cool stuff:

  • It's common practice to add a dark overlay to a large hero image, but how dark should it be to ensure legible text? I share a link to a tool that can help you figure it out!
  • Do you know if folks with color-blindness or other visual disorders can use your products? Chrome now includes built-in visual emulation, so you can see your site/app as they do. It's eye-opening.

One of the most frustrating things about CSS is that there aren't typically errors. If you're not getting the result you want, there's no helpful exception message that points you towards the problem.

Firefox shipped an awesome new feature: “Inactive CSS”. If a CSS property isn't working, it tells you why!

I walk through this feature in a 1-minute video on Twitter.

A screenshot of a video recording, showing the Inactive CSS feature

View tweet

Some other cool stuff:

Even after so many years of doing web development, I still discover new stuff about HTML all the time!

I learned this year that HTML has native elements for progress bars. They're not quite as flexible as building a custom one with JS, but you get a lot of stuff for free with them (including good accessibility!)

Several progress vars. Different progress values, sizes, and colors.

View tweet

I also learned about:

Link to this heading
Animation and UX

Folks who know me in real life know that I can be somewhat fastidious 😅 In particular, I get really bothered by small imperfections, little details that aren't quite right.

These tips are all about improving our animations and general UX polish by going that extra mile. I won't embed any big GIFs here, but do check these tweets out if you care about this stuff too!

If you've been working with React for a while, I bet you've seen this error message:

A Chrome error message: “Warning: Can't call setState on an unmounted component”.

It's the most common thing in the world: a component needs to fetch some data from an API, but if the user changes routes before the request completes, we'll get a warning about memory leaks.

It turns out, we can cancel fetch requests! We don't have to resort to hacky isMounted flags or other sketchy fixes.

If only we could cancel promises in general now 😬

A code snippet showing a cancellable fetch. For code, view sandbox in linked tweet

(Click the image to see the tweet. Probably easier to read, plus it features a link to a live demo!)

Here's another pain point in React: Forms.

It's just such a pain to set up state hooks and event listeners for every input in a form. And I have yet to find a form library that makes it as easy as I feel it should be.

Lately I've been using uncontrolled form inputs in React, and it's way nicer. Wish I started doing this years ago!




I made a conscious decision a year or two ago to share what I learn on Twitter and my blog. It helps me deepen my understanding — in order to teach something, you really need to understand it! It's also a great way to "spread the wealth" and help others. I highly recommend this practice. The next time you learn something cool, share it online!

It's so easy to assume that everyone already knows everything you do, but it's so far from the truth. I bet you already know a bunch of neat tricks that others would find valuable!

I'd love to hear if any of the tricks I shared in this email were especially useful — anything in particular make you think "Oh I know exactly where I can use this!"? As always, you can reply to this email and let me know. I read every response 😄

All the best in the new year ✌
-Josh



PS. I actually tweeted quite a few more tips than this, but I didn't want it to be too overwhelming 😅 if you want to be a completionist, or if you're looking to kill some time, here are the search queries to find the complete set of tips and tricks.