9th week of 2021

Published on

Action-driven and smoother CSS animations, alternative to CSS clearfix hack, icon creation tutorials for Figma, .NET refactoring videos.

Table of contents

👨‍💼 Work

We had a certain deadline this week, so this and the last week have been quite hectic. Nothing special apart from that.

👨‍🚀 Personal

Nothing this week. It was hectic at work.

👨‍🎓 Learnings

CSS: action-driven animations

I read Josh W Comeau's comprehensive article An Interactive Guide to CSS Transitions. The Action-driven motion section had a nice idea about animating based on actions instead of states:

Another common example is modals. It can be useful for modals to enter with an ease-out animation, and to exit with a quicker ease-in animation.

This is a small detail, but it speaks to a much larger idea.

I believe most developers think in terms of states: for example, you might look at this situation and say that we have a "hover" state and a default state. Instead, what if we thought in terms of actions? We animate based on what the user is doing, thinking in terms of events, not states. We have a mouse-enter animation and a mouse-leave animation.

Makes sense. I'll keep this in mind the next time I'm working on animations.

CSS: will-change property for smoother animations

Another learning from Josh's article (see the previous section), from the Hardware acceleration section.

The beginning and ending of animations can sometimes be glitchy because some property transitions (like transform) are rendered by the GPU, whereas the elements are otherwise rendered by the CPU.

GPUs and CPUs render things slightly differently. [...]

We can fix this problem by adding the following CSS property:

.btn {
will-change: transform;
}

will-change is a property that allows us to hint to the browser that we're going to animate the selected element, and that it should optimize for this case.

In practice, what this means is that the browser will let the GPU handle this element all the time. No more handing-off between CPU and GPU, no more telltale "snapping into place".

But wait, there's more!

There's another benefit to hardware acceleration: we can take advantage of sub-pixel rendering.

Properties like margin-top can't sub-pixel-render, which means they need to round to the nearest pixel, creating a stepped, janky effect. transform, meanwhile, can smoothly shift between pixels, thanks to the GPU's anti-aliasing trickery.

Note however that you shouldn't overuse the will-change property, like Josh later mentions. It's also mentioned on the will-change page on MDN:

Important: will-change is intended to be used as a last resort, in order to try to deal with existing performance problems. It should not be used to anticipate performance problems.

CSS: display: flow-root is better than the clearfix hack

display: flow-root is described on Can I use like so:

The element generates a block container box, and lays out its contents using flow layout. It always establishes a new block formatting context for its contents. It provides a better solution to the most use cases of the "clearfix" hack.

The browser support of the flow-root value is excellent (supported by all modern browsers). That's quite funny, because I don't remember hearing about this value before. I also don't remember where I found this.

🕵️‍♂️ Cool stuff

How to create icons in Figma, step by step

Steve Schoger has shared three step-by-step icon creation tutorials on Twitter:

I'm no designer, and I haven't used Figma much, so these are very helpful.

.NET refactoring videos

YouTube recommended me a video (part 1) about refactoring some .NET code by Nick Chapsas. It was excellent.

In the first part of the two-part video series, Nick makes the code testable by extracting its dependencies and injecting them back via constructor injection. This way the dependencies can be mocked in unit tests.

Then he creates unit tests for the method before doing any refactoring. Otherwise it would be too easy to accidentally modify the logic of the code.

In the part 2 video, Nick does the actual refactoring. Some things that struck in my mind:

Renaming method parameters can cause backwards incompatibility

One method parameter has a typo in its name. It would be tempting to rename it, but it would be a breaking change to the consumers of the code (warranting a major version increment) because C# supports named arguments. That's a good point that I would have missed.

When are interfaces needed?

Nick creates interfaces for the extracted dependencies to make them mockable, expect for one class. That class doesn't need mocking, so it doesn't necessarily need an interface.

Using tuples instead of creating simple classes

One method needs to return two values. You could create a simple class for the return value, but Nick uses a tuple, skipping the need for creating that simple class.

💁‍♂️ More Weekly log entries

Next week: 10th week of 2021

Previous week: 8th week of 2021