Bunny Fonts

Bunny Fonts bills itself as the “privacy-first web font platform designed to put privacy back into the internet.”According to its FAQ:

With a zero-tracking and no-logging policy, Bunny Fonts helps you stay fully GDPR compliant and puts your user’s personal data into their own hands.

Hard for my mind not to go straight to Google Fonts. Bunny Fonts even says they are a drop-in replacement for Google Fonts. It offers the same open source fonts and holds the same API structure used by Google Fonts.

Now, I’m no GDPR expert but the possibility of Google collecting data through its Fonts API is hardly unsurprising or even unexpected. I was curious to check out Google’s privacy statement for Fonts:

The Google Fonts API logs the details of the HTTP request, which includes the timestamp, requested URL, and all HTTP headers (including referrer and user agent string) provided in connection with the use of our CSS API.

IP addresses are not logged.

Comparing that to what Bunny Fonts says in its FAQ:

When using Bunny Fonts, no personal data or logs are stored. All the requests are processed completely anonymously.

Or perhaps more thoroughly explained on the bunny.net GDPR statement:

In most cases, the data held and collected by bunny.net does not contain any user identifiable data. In some cases, which depend on how you are using bunny.net and how your website is structured, personal data may be collected from your users. Such information includes hosting user uploaded content as well as personal data that might be transmitted in the URL, User-Agent or Referer headers of the HTTP protocol.

Sounds pretty similar, right? Well, it may not have been that similar earlier this year when a German court ruled that embedded Google Fonts violated GDPR compliance. It appears that one line in the Google Fonts privacy statement about IP addresses came after the ruling, once the API scrubbed them from collected data.

So, do you need to ditch Google Fonts to be GDPR compliant? I would imagine not if IP addresses were the sole concern, but I’ll leave that for folks who know the rules to comment on that.

But if you are concerned about Google Font’s GDPR compliance, I guess Bunny Fonts is worth a look! And seeing that it’s powered by bunny.net’s CDN services, you should get pretty comparable performance marks.

To Shared LinkPermalink on CSS-Tricks

Bunny Fonts originally published on CSS-Tricks. You should get the newsletter.

Text-overflow: ellipsis considered harmful

Eric Eggert:

There are a few legitimate use cases for this technique. For example, you might have a table with titles and descriptions. To preserve more space for the title, you constrain the description to one line on small viewports to the one-line and you repeat the description on the detail page for this item.

However, I often see it used on items like buttons or even form labels to make them look nicer(?) or when aligning them vertically. But once you change the viewport or resize the text, the end of the text disappears.

I think “… if used in certain situations” belongs there, but it certainly makes for a better blog post title without it. As Eric says, there are legitimate use cases for truncating text. Maybe only a few, but legitimate nonetheless.

The ultimate goal is to prevent “losing” data, something that can certainly happen in CSS. Text that inadvertently overflows a container is lost in the sense that it’s simply not there. And if that text is simply not there, users will miss it, even if it is the best and most well-crafted call to action ever published to the web.

Eric points out that there is no way to make the text truncated by text-overflow: ellipsis visible. Once it’s gone, it’s gone (although screen readers seem to announce it). It’s practically lost data. You might be OK with that. That’s cool as long as you know what’s happening and it’s intended.

But here’s what Eric says that made me want to share this:

Don’t constrain the content to fit your design, make your CSS flexible to handle longer words gracefully.

Again, you might want to conform content to the design. But I’d probably argue, like Eric, that the design should adapt to the content rather than the other way around. I have a hard time recalling any situation where the text on a page is unimportant or without purpose to the extent that I’d be cool cutting if off at any arbitrary point determined by a CSS property. Maybe an archive of blog posts where each post shows an excerpt of the post content before truncating, but that’s not exactly a use case for text-overflow: ellipse.

CSS has the tools to make a flexible design that accounts for varying lengths of text. So maybe err on the side of writing defensive CSS… CSS that anticipates issues and knows how to gracefully handle different content scenarios. text-overflow: ellipsis might be part of your CSS arsenal for that. But it might also be throwing the baby out with the bath water. Worth asking whether losing that data is worth the cost of what that content is supposed to do before giving giving it a haircut.

While we’re talking about truncating text…



Oct 1, 2021

Line Clampin’ (Truncating Multiple Line Text)



Sep 20, 2021

Embracing Asymmetrical Design



Jul 21, 2020

Using Flexbox and text ellipsis together



Sep 4, 2019

Multiline truncated text with “show more” button

To Shared LinkPermalink on CSS-Tricks

Text-overflow: ellipsis considered harmful originally published on CSS-Tricks. You should get the newsletter.

Jump Into July (2022 Desktop Wallpapers Edition)

Starting off the new month with a little inspiration boost — that’s the motivation behind our monthly wallpapers series that we’ve been running for more then eleven years now. Every month, we invite you, our dear readers, to challenge your creative skills and submit your wallpaper designs to it. And, of course, it wasn’t any different this time around.

For this edition, creative folks from all across the globe took on the challenge and created beautiful and unique wallpapers to tell their story or, well, just cater for some good vibes on your screens. The wallpapers all come in versions with and without a calendar for July 2022 and can be downloaded for free. Thank you to everyone who shared their artworks with us — you’re smashing!

Last but not least, to make your July even more colorful, you’ll also find a little best-of from our wallpapers archives at the end of this post. Maybe you’ll rediscover one of your almost forgotten favorites in there, too? Enjoy!

You can click on every image to see a larger preview,
We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves.
Submit a wallpaper!
Did you know that you could get featured in our next wallpapers post, too? We are always looking for creative talent.

Melting July

“Welcome to the sweltering July — the month when it’s so hot that even the fruits are edgy. Our ice-creamy, vibrantly-colored monthly calendar is melting as the temperature rises, so make sure to download it as quickly as possible!” — Designed by PopArt Studio from Serbia.

with calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1440×900, 1440×1050, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440
without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1440×900, 1440×1050, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440


Designed by Ricardo Gimenes from Sweden.

with calendar: 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160
without calendar: 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160

Shave The Whales

Designed by Ricardo Gimenes from Sweden.

with calendar: 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160
without calendar: 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160

Meeting Mary Poppins

“This month we travel to London with Mary Poppins to discover the city. We will have great adventures!” — Designed by Veronica Valenzuela from Spain.

with calendar: 640×480, 800×480, 1024×768, 1280×720, 1280×800, 1440×900, 1600×1200, 1920×1080, 1920×1440, 2560×1440
without calendar: 640×480, 800×480, 1024×768, 1280×720, 1280×800, 1440×900, 1600×1200, 1920×1080, 1920×1440, 2560×1440

Free Flight Of A Bird

“Our designers can’t live without being affected by the war in Ukraine. Recent escalation and missile attacks on civilian objects made them reflect on that and as a result, they created this wonderful calendar in the colors of the Ukrainian flag. The bird represents the freedom that we sooner or later get through a long struggle. You can find more free calendars in our post. Thank you!” — Designed by MasterBundles from Ukraine.

with calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440
without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Aquatic Fresh

“I played with a shape looking like a starfish, this one is made with a mathematical formula. Then I put all the shapes on the screen, according to a Poisson disc sampling distribution. Poisson is the french word for fish, it’s also the name of a french mathematician. Finally, all this made me think of a pond with water lilies, a refreshing atmosphere for July.” — Designed by Philippe Brouard from France.

with calendar: 1024×768, 1366×768, 1600×1200, 1920×1080, 1920×1200, 2560×1440, 2560×1600, 2880×1800
without calendar: 1024×768, 1366×768, 1600×1200, 1920×1080, 1920×1200, 2560×1440, 2560×1600, 2880×1800

Buck Moon

“July is the month where the Buck Moon takes place, also known as the full moon. With the brightest light shining upon Earth’s night and the male deer’s antlers growing at their fullest.” — Designed by Linda Lin from the Netherlands.

with calendar: 1024×768, 1024×1024, 1280×800, 1280×1024, 1366×768, 1440×900, 1680×1050, 1920×1080, 1920×1200, 2560×1440
without calendar: 1024×768, 1024×1024, 1280×800, 1280×1024, 1366×768, 1440×900, 1680×1050, 1920×1080, 1920×1200, 2560×1440

Oldies But Goodies

Our wallpapers archives are full of timeless treasures that are just too good to be forgotten. So here’s a small selection of favorites from past July editions. Please note that these designs don’t come with a calendar.

Birdie July

Designed by Lívi Lénárt from Hungary.

without calendar: 800×600, 1024×1024, 1152×864, 1280×960, 1280×1024, 1600×1200, 1920×1080, 2560×1440

Summer Season

“I’m an avid runner, and I have some beautiful natural views surrounding my city. The Smoky Mountains are a bit further east, so I took some liberties, but Tennessee’s nature is nothing short of beautiful and inspiring.” — Designed by Cam Elliott from Memphis, TN.

without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160

Surfer Cat

Designed by Ricardo Gimenes from Sweden.

without calendar: 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160

The Ancient Device

Designed by Ricardo Gimenes from Sweden.

without calendar: 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 3840×2160

Summer Cannonball

“Summer is coming in the northern hemisphere and what better way to enjoy it than with watermelons and cannonballs.” — Designed by Maria Keller from Mexico.

without calendar: 320×480, 640×480, 640×1136, 750×1334, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1242×2208, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440, 2880×1800

Nightly Carnival

“July brings the yearly carnival near my hometown, so I decided to design a summer evening carnival.” — Designed by Bregje Damen from the Netherlands.

without calendar: 320×480, 1024×1024, 1920×1080, 1920×1200, 1920×1440, 2560×1440

A Flamboyance Of Flamingos

“July in South Africa is dreary and wintery so we give all the southern hemisphere dwellers a bit of colour for those grey days. And for the northern hemisphere dwellers a bit of pop for their summer!” — Designed by Wonderland Collective from South Africa.

without calendar: 320×480, 800×600, 1024×768, 1280×960, 1680×1050, 1920×1200, 2560×1440

Plastic Bag Free Day

“The objective of this date is to draw attention to the production and over-consumption of plastic bags worldwide, presenting alternatives to solve this serious environmental problem. It is urgent to change the behavior of all human beings regarding the use of plastic bags. For the preservation of the environment, we should use the same plastic bag for shopping, recycling or use paper bags. In this wallpaper I drew a plastic bag with a turtle inside it, as if it was imprisoned by its own bag, as if the ocean was reduced to a plastic bag, emphasizing the seriousness of this environmental problem, which has tortured both turtles and many others marine species.” — Designed by Carolina Santos from Portugal.

without calendar: 320×480, 640×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×800, 1280×960, 1280×1024, 1400×1050, 1440×900, 1600×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Summer Essentials

“A few essential items for the summertime weather at the beach, park, and everywhere in-between.” — Designed by Zach Vandehey from the United States.

without calendar: 1024×768, 1440×900, 1600×1200, 1920×1200, 2560×1440

Fire Camp

“What’s better than a starry summer night with an (unexpected) friend around a fire camp with some marshmallows? Happy July!” — Designed by Etienne Mansard from the UK.

without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1440×900, 1440×1050, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2048×1536, 2560×1440

Go To Holidays!

“It is July and the most awaited moment arrives… Holidays! We pack our bags and go to relax! Happy holidays!” — Designed by Veronica Valenzuela from Spain.


without calendar: 800×480, 1024×768, 1152×864, 1280×800, 1280×960, 1440×900, 1680×1200, 1920×1080, 2560×1440

It’s A Smashing Summer

“The car wash down the street. I went to get my car washed for free and when the car entered the tunnel, the soap and the lights created some colorful and gorgeous images. I photographed them all. Car wash businesses remind me of my family. My Dad owned gas stations and my brother used to wash cars when he was young. Plus, back where I am originally from, car washing is done frequently because we have warm weather all year around.” — Designed by Alma Hoffmann from Puerto Rico, US.

without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440

Eternal Summer

“And once you let your imagination go, you find yourself surrounded by eternal summer, unexplored worlds and all-pervading warmth, where there are no rules of physics and colors tint the sky under your feet.” — Designed by Ana Masnikosa from Belgrade, Serbia.


without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Taste Like Summer!

“In times of clean eating and the world of superfoods there is one vegetable missing. An old, forgotten one. A flower actually. Rare and special. Once it had a royal reputation (I cheated a bit with the blue). The artichocke — this is my superhero in the garden! I am a food lover — you too? Enjoy it — dip it!” — Designed by Alexandra Tamgnoué from Germany.

previewwithout calendar: 320×480, 640×480, 800×600, 1024×768, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1440×900, 1440×1050, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Tropical Lilies

“I enjoy creating tropical designs, they fuel my wanderlust and passion for the exotic. Instantaneously transporting me to a tropical destination.” — Designed by Tamsin Raslan from the United States.

without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1440×900, 1440×1050, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Keep Moving Forward

“Snails can be inspiring! If you keep heading towards your goal, even if it is just tiny steps, enjoy the journey and hopefully it will be worth the effort.” — Designed by Glynnis Owen from Australia.

without calendar: 320×480, 640×480, 800×600, 1024×768, 1152×864, 1280×720, 1280×960, 1600×1200, 1920×1080, 1920×1440, 2560×1440

Day Turns To Night

Designed by Xenia Latii from Germany.

without calendar: 320×480, 640×480, 800×480, 800×600, 1024×768, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Island River

“Make sure you have a refreshing source of ideas, plans and hopes this July. Especially if you are to escape from urban life for a while.” — Designed by Igor Izhik from Canada.

without calendar: 1024×768, 1024×1024, 1152×864, 1280×720, 1280×800, 1280×960, 1280×1024, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1680×1200, 1920×1080, 1920×1200, 1920×1440, 2560×1440

Only One

Designed by Elise Vanoorbeek from Belgium

without calendar: 1024×768, 1280×800, 1280×1024, 1680×1050, 1920×1200, 2560×1440

How I Chose an Animation Library for My Solitaire Game

There is an abundance of both CSS and JavaScript libraries for animation libraries out there. So many, in fact, that choosing the right one for your project can seem impossible. That’s the situation I faced when I decided to build an online Solitaire game. I knew I’d need an animation library, but which was the right one to choose?

In this article, I’ll go through which considerations I made, what to look out for and present you with some of the most popular libraries available. I’ll go through some real-world examples with you to illustrate my points, and in the end, hopefully, you’ll be better equipped than me when I first had to choose an animation library.

Your mileage with this advice may vary, of course. Everything I’m sharing here is specific to a thing I wanted to build. Your project may have completely different requirements and priorities and that’s OK. I think what’s important here is getting a first-hand account of thinking like a front-end developer with a particular goal.

Speaking of which, I do consider myself a front-end developer but my background is super heavy in design. So I know code, but not to the extent of someone who is a JavaScript engineer. Just wanted to clear that up because experience can certainly impact the final decision.

Here’s the goal

Before we get into any decision-making let’s take a look at the sorts of animations I needed to make in this CSS-Tricks-ified version of the game:

Crazy, right? There’s nothing exactly trivial about these animations. There’s a lot going on — sometimes simultaneously — and a lot to orchestrate. Plus, a majority of the animations are triggered by user interactions. So, that left me with a few priorities heading into my decision:

Smooth animations: The way animations are applied can have a big impact on whether they run smoothly, or display a little choppiness.Performance: Adopting any library is going to add weight to a project and I wanted my game to be as lean as possible.Convenience: I wanted a nice, clean syntax that makes it easier to write and manage the animations. I’d even trade a little extra convenience for a small performance cost if it allows me to write better, more maintainable code. Again, this bodes well for a designer-turned-developer.Browser support: Of course I wanted my game to work on any modern browser using some form of progressive enhancement to prevent completely borking legacy browsers. Plus, I definitely wanted  some future-proofing.

That’s what I took with me as I went in search of the right tool for this particular job.

Choosing between CSS or JavaScript animation libraries

The first thing I considered when choosing an animation library was whether to go with a CSS or JavaScript-based library. There are lots of great CSS libraries, many of them with excellent performance which was a high priority for me. I was looking to do some heavy-duty animations, like the  ability to sequence animations and get callbacks on animation completion. That’s all totally possible with pure CSS — still, it’s a lot less smooth than what most JavaScript libraries offer.

Let’s see how a simple sequenced animation looks in CSS and compare it to jQuery, which has plenty of built-in animation helpers:

CodePen Embed Fallback

The animations look the same but are created differently. To make the CSS animation, first, we have to define the keyframe animation in our CSS and attach it to a class:

.card.move {
animation : move 2s;

@keyframes move {
0% { left: 0 }
50% { left: 100px }
100% { left: 0 }

We then execute the animation using JavaScript and listen for a CSS callback on the element:

var cardElement = document.getElementsByClassName(“card”)[0];
var statusElement = document.getElementsByClassName(“status”)[0];

statusElement.innerHTML = “Animating”

var animationEndCallback = function() {
statusElement.innerHTML = “Inactive”

cardElement.addEventListener(“webkitAnimationEnd”, animationEndCallback);
cardElement.addEventListener(“oAnimationEnd”, animationEndCallback); 
cardElement.addEventListener(“antionend”, animationEndCallback);

Having things happen in different places might be fine in a simple example like this, but it can become very confusing once things get a bit more complex. 

Compare this to how the animation is done with jQuery:

$( “.card” ).animate({
left: “100px”
}, 1000);
$( “.card” ).animate({
left: 0
}, 1000, function() {

Here, everything happens in the same place, simplifying things should the animations grow more complex in the future.

It seemed clear that a JavaScript library was the right way to go, but which was the right one to choose for my Solitaire game? I mean, jQuery is great and still widely used even today, but that’s not something I want to hang my hat on. There are plenty of JavaScript animation libraries, so I wanted to consider something built specifically to handle the type of heavy animations I had in mind.

Choosing a JavaScript animation library

It quickly became apparent to me that there’s no lack of JavaScript animation libraries and new, exciting technologies. They all have benefits and drawbacks, so let’s go through some of the ones I considered and why.

The Web Animations API is one such case that might replace many JavaScript animation libraries in the future. With it, you’ll be able to create complex staggered animations without loading any external libraries and with the same performance as CSS animations. The only drawback is that not all browsers support it yet

The <canvas> element presents another exciting opportunity. In it, we can animate things with JavaScript, as we would with the DOM, but the animation is rendered as raster, which means we can make some high-performance animations. The only drawback is that the canvas element is essentially rendered as an image in the DOM, so if we’re looking for pixel-perfection, we might be out of luck. As someone acutely in tune with design, this was a dealbreaker for me.

I needed something tried and tested, so I knew I probably had to go with one of the many JavaScript libraries. I started looking at libraries and narrowed my choices to Anime.js and GSAP. They both seemed to handle complex animations well and had excellent notes on performance. Anime is a well-maintained library with over 42.000 stars on GitHub, while GSAP is a super popular, battle-tested library with a thriving community.

An active community was critical to me since I needed a place to ask for help, and I didn’t want to use a library that might later be abandoned. I considered this as part of my convenience requirements.

Sequencing animations and callbacks

Once I had my choices narrowed down, the next step was to implement a complex animation using my two libraries. A recurrent animation in a solitaire game is that of a card moving somewhere and then turning over, so let’s see how that looks:

CodePen Embed Fallback

Both animations look great! They’re smooth, and implementing both of them was pretty straightforward. Both libraries had a timeline function that made creating sequences a breeze. This is how the implementation looks in AnimeJS:

var timeline = anime.timeline({
begin: function() {
complete: function() {

targets: ‘.card’,
left: [0, 300],
easing: ‘easeInOutSine’,
duration: 500
targets: ‘.card .back’,
rotateY: [0, 90],
easing: ‘easeInSine’,
duration: 200
targets: ‘.card .front’,
rotateY: [-90, 0],
easing: ‘easeOutSine’,
duration: 200

Anime’s timeline() function comes built-in with callbacks on beginning and ending the animation, and creating the sequence is as easy as appending the sequential animations. First, I move the card, then I turn my back-image 90 degrees, so it goes out of view, and then I turn my front-image 90 degrees, so it comes into view.

The same implementation using GSAP’s timeline() function looks very similar:

var timeline = gsap.timeline({
onStart: function() {
onComplete: function() {

timeline.fromTo(“.card”, {
left: 0
}, {
duration: 0.5,
left: 300
}).fromTo(“.card .back”, {
rotationY: 0
}, {
rotationY: 90,
ease: “power1.easeIn”,
duration: 0.2
}).fromTo(“.card .front”, {
rotationY: -90
}, {
rotationY: 0,
ease: “power1.easeOut”,
duration: 0.2

Decision time

The main difference between Anime and GSAP appears to be the syntax, where GSAP might be a little more elaborate. I was stuck with two great libraries that had very similar functionality, were able to deal with complex animation, and had a thriving community. It seemed like I had a tie race!

PriorityAnimeGSAPSmooth animations✅✅Performance✅✅Convenience✅✅Browser support✅✅

So, what made me choose one library over the other?

I was very concerned about how the library would act under pressure. Having laggy animations in a game like Solitaire can greatly impact how fun it is to play the game. I knew I wouldn’t be able to fully see how the library performed before I created the game. Luckily, GSAP had made a stress test that compared different animation libraries to each other, including Anime.

CodePen Embed Fallback

Looking at that, GSAP certainly looked to be the superior library for dealing with loads of complex animations. GSAP was giving me upwards of 26 frames per second on a crazy heavy animation that Anime was only able to top out at 19.  After reading up on GSAP more and looking into their forums, it became clear that performance was of the highest priority to the guys behind GSAP.

And even though both GSAP and Anime have been around a while, Anime’s repo has been sitting somewhat dormant a couple of years while GSAP had made commits in the past couple of months.

I ended up using GSAP and haven’t regretted my decision!

How about you? Does any of this square with how you evaluate and compare front-end tooling? Are there other priorities you might have considered (e.g. accessibility, etc.) in a project like this? Or do you have a project where you had to pare down your choices from a bunch of different options? Please share in the comments because I’d like to know! 

Oh, and if you want to see how it looks when animating a whole deck of cards, you can head over to my site and play a game of Solitaire. Have fun!

How I Chose an Animation Library for My Solitaire Game originally published on CSS-Tricks. You should get the newsletter.

Help Shape the Future of CSS-Tricks!

Hey, so it’s been a minute since we announced that CSS-Tricks is now part of the DigitalOcean family. Things are pretty much business as usual and hopefully it feels that way to you, too. Now that we’re getting settled, we’re eager to start poking at the future of this site.

What sort of things are we poking at? Well, that’s where you come in. You see, there’s no shortage of ideas for CSS-Tricks, but we only want to work on things that continue to make CSS-Tricks one of the spots you come to time and again for all things front-end (including actual CSS tricks).

So, we put together a short little survey for you. Nothing crazy, just a few questions to help us vet those ideas and ultimately shape the future of CSS-Tricks.

Thanks so much for your help! And while I have you, thanks for continuing to hang with us. In the seven years I’ve been working here at CSS-Tricks, I know this site wouldn’t even be here today without y’all. Here’s to the future of CSS-Tricks and learning together!

CSS-Tricks Newsletter

Oh, and one more update for all of you who miss the newsletter: it will be back! But we had to drop a ton of you off the list (seriously, like 80% of all subscribers) to be compliant with legal stuff that’s over my head. No worries, though, because you can re-subscribe right down here with your email address.

Help Shape the Future of CSS-Tricks! originally published on CSS-Tricks. You should get the newsletter.

My Dumbest CSS Mistakes

We all make mistakes in our code. It happens! I know if I had one of those “Days Since Last Mistake” signs hanging over my desk, a big ol’ goose egg would be hovering above me all the time. It doesn’t have to be big mistakes, either. My clumsy self has committed small errors to repos ranging from typos all the way to complete npm module directories.


That’s one of the things I really love about CSS: it’s forgiving as heck. If it doesn’t understand a typo, it keeps looking up the cascade in search of a match. None of that stuff where one out of place characters breaks a site and takes no prisoners. But it’s still embarrassing when CSS mistakes pop up!

Like this one I find myself making way more times than I’d like to admit:

.element {
display: flexbox; /* 🤦‍♂️ */

Or when I try setting a gradient without a background property:

.gradient {
linear-gradient(45deg, rgb(50% 100% 90%), rgb(62% 85% 93%));

I hate how close X and C are on a keyboard because I can’t count how many times I’m blazing through something and mistake px for pc units.

.element {
font-size: 16pc; /* I meant pixels! */

Another CSS mistake I catch every so often is one I know many other folks make because I spot it too often in blog posts with code snippets:

// This is not a CSS comment.
.element {
/* This is a CSS comment. */

Have you ever forgotten to use var() around a CSS variable? I sure have.

.element {
color: –primary-color;

Speaking of CSS variables, naming them is hard (like everything else) and I often use some incorrect version of a variable that I named!

:root {
–color-primary: #FF5722;
–color-secondary: #3E2723;

/* Much later on… */

.element {
color: var(–primary-color); /* 🙃 */

Yes, I have indeed copied a snippet of CSS before only to have fancy quotes get in the way of making it work:

.element::before {
content: “”; /* Should be “” */

And, yes, I have spent way too long figuring out those quotes were the culprit.

Looking at that last one reminds me that I sometimes forget to set the content property when I’m working with ::before or ::after. Which reminds me of how I’ve forgotten to set an element’s position before trying to offset it or change its z-index. Seriously, these things happen!

It’s hard talking about mistakes

Have you ever finished reading some blog post sharing some amazing trick and felt some sort of Imposter Syndrome? I think that’s largely because blog posts often mask the real work — and failures — that go into amazing tricks. As someone who reads posts like that for a living, I can tell you that many, if not the vast majority, go through many rounds of editing where potentially embarrassing mistakes are weeded out and smoothed over.

Even those ridiculously awesome articles have to fail before they get all those ooooos and ahhhhhs.

The same is true of any app, website, demo, or whatever you happen to come across. The chances any of them came out perfect the first time is next to nothin’.

But if I’m being totally honest with you, I’m often more amazed (and interested) in the journey it takes to accomplish something, warts and all. The journey is a glimpse into what it’s like to think like a front-end developer. That’s where real (and most valuable) learning happens.

And all of this is merely building up to what I really want to ask…

What are your dumbest CSS mistakes?

C’mon, we all know you’ve made some! Let us learn from them!

My Dumbest CSS Mistakes originally published on CSS-Tricks. You should get the newsletter.

Smashing Podcast Episode 48 With Stephanie Eckles: Is Sass Still Relevant?

In this episode, we ask if Sass is still relevant in 2022 and if it adds any value modern CSS workflows. Vitaly talks to expert Stephanie Eckles to find out.

Show Notes

Stephanie’s personal website
Stephanie on Twitter
Modern CSS
Level-Up With Modern CSS workshop at SmashingConf

Weekly Update

Things I Wish I’d Known Earlier In My Career written by Vitaly Friedman
How To Test Your MVP Within 2 Weeks (Or Less) written by Sergey Krasotin
How To Create A Vanilla JavaScript Gantt Chart: Adding Task Editing Features written by Anna Prenzel
Voice Control Usability Considerations For Partially Visually Hidden Link Names written by Eric Bailey
Demystifying The New Gatsby Framework written by Juan Diego Rodríguez


Vitaly Friedman: She’s a software engineer focused on front-end and she creates front-end learning and development resources with an emphasis on CSS, accessibility, and 11ty. She’s a writer, teacher, and consultant. And she also hosts the podcast Word Wrap, where she and Claire Lipskey talk about a bunch of stuff related to what it even means to be a developer in 21st century. She’s also an advocate for accessibility, scalable CSS and Jamstack. And offline, she’s a mom to two girls and a Cava-corgi, and she enjoys baking. So we know she’s an expert in CSS and accessibility, but did you know that she absolutely loves hip-hop and dancing, occasionally, of course. My Smashing friends, please welcome Stephanie Eckles. Hello, Stephanie, how are you today?

Stephanie: I am smashing.

Vitaly: Oh, that’s wonderful to hear. It’s wonderful to see you as well because you’re writing so many articles. You’re writing so many tutorials and courses and tools. Everything is out there. Just really incredible to actually have an opportunity to just talk to you every now and again, this is wonderful. But I always have to ask, I’m just really, really curious at this point. Stephanie, you create so many tools for people out there to use. And I always think about HTML Recipes and Button Buddy and 11ty Rocks, and so many articles in CSS and trainings and workshops, and you have your own podcast and you’re also a mom. Where do you find time for it? Are you super organized? How does it work?

Stephanie: So I’m not super organized, but if anything about becoming a mom, becoming a parent, or any sort of caregiver, is the time that you do have is more precious and also you are sort of forced to be more efficient. So, when you have different goals, it’s just something that’s important to me to include in my day or make time for.

Vitaly: Yeah, that makes sense. It’s actually quite interesting because the less time you have, the better you get around to your time, the more you optimize your time and all. So, that’s incredible to hear that.

Vitaly: Well, Stephanie, today’s an important day. It’s a very important day, isn’t it? Well, do you know what I’m hinting at, by any chance?

Stephanie: I believe there’s a certain milestone for web developers that we’ve been excited about.

Vitaly: Yes. Isn’t it very exciting? Dear listeners, as we’re recording this interview today, it’s June 15th and this is going to be going in the history for calendars designed and created for web developers for, I don’t know, centuries, maybe? Do you think we’ll still be developing websites in a century? Stephanie?

Stephanie: I do believe that actually.

Vitaly: Okay. So then we will probably be celebrating this day because it’s a day when Microsoft officially ends support for the Internet Explorer desktop application. Are we feeling a little bit nostalgic today, Stephanie? Do you remember any quirks and bugs from IE?

Stephanie: Yes. You know, over my all 15 plus year career history, definitely it’s something I’ve had fondness and other feelings about throughout that history. So yeah, it’s a big day. It’s one we’ve, like you said, marked on the calendars, but yeah, I remember particularly staying up late at an advertising agency I worked at. At the time we were on IE 7 and I could not get a border to show up, of all things. I will always remember that day.

Vitaly: Yes, of course. It’s interesting actually thinking back about, let’s say 15 years, you said, maybe you could just share a bit of light. How did you actually fall in love with the web? I hope you didn’t fall in love with Internet Explorer because then it would be very sad day today. But how did you actually even get to the web? Tell us a little bit of your backstory, if you can.

Stephanie: Absolutely. So I started with Flash, Macromedia Flash, not Adobe Flash. Got that at a summer camp that I had gone to as a teenager. And it was sort of my gateway. I wanted to put my “art”, as it were, on the web, very big quotes around art. So I fell in love with the keyframe animation at that time. And that led to figuring out how to get it on the web, that led to learning a little, tiny, tiny bit about HTML. I remember visiting a forum to get all of my HTML and Flash questions answered. And then I found WordPress and WordPress was just getting out the gate. It was a couple years old when I learned about it as a tool. And spent a decade of my career with WordPress, actually. My degree is in advertising, so, huge part of my career was working as a developer in marketing and advertising. And, that’s kind of the base evolution of how I got into it and throughout that time, front-end development has always been my specialty.

Vitaly: Right, right. That’s exciting. That’s incredible. I’m also thinking about all this times back when I was really playing with all this quirks around Internet Explorer and just in general. And it’s one thing that really excites me, I think, about all of this or excited me back then is that you could actually just go ahead and present something to the entire world and the entire world would come and see it. This is how I ended up creating my own football club website for a club that didn’t exist, which was kind of fun, I guess. And I had maybe 44 visitors over a year. That was very exciting for me at the time.

Vitaly: And I think about this now and I feel like sometimes it’s becoming just incredibly difficult for people to be able to do that. And it feels like you need to learn so much to even be able to publish “hello world” on a page. Do you think this is just how things turned out, we just have become more mature? Or do you think it actually has become a bit more easy, maybe, over the last years because we have browser inconsistencies gone. Tooling has never been better. What’s your take on this?

Stephanie: Yeah. So, in my early days, and I’m sure you experienced this plenty of times as well, you did have to worry about the server. You did have to worry about FTP, which might be a lost acronym for some folks these days. Very early, we didn’t have version control or at least it wasn’t something I certainly knew about not having grown up in a highly technological area. And I think that’s an important point here is it really depends how you’re introduced to the web. If you come in straight from a bootcamp, you’re going to have a very different lens and a very different idea of how to get things on the web than maybe if you’re casually looking around having an interest, trying to find whatever resources.

Stephanie: And I think even then it depends what your goals are. So I think it can be very easy and approachable, but it can also seem extremely complicated and definitely more complicated in a lot of ways because of the tooling. The tooling can either help or hinder that process, for sure. That’s kind of why I’m fond of Jamstack. I think that is a lower level, easier way to get introduced and get your first things on the web, if that’s the goal.

Vitaly: Right. And that’s also wonderful because you’ve been publishing so many tutorials around Jamstack and 11ty, and maybe you could tell us where do you see 11ty, for example, being extremely useful? What kind of projects would it be a default, let’s say, where you would say, “Yeah, that’s probably going to be working best with Jamstack and 11ty.” And where would be its boundaries.

Stephanie: Yeah. Great question. So 11ty is a static site generator and the difference about it versus some other ones is there’s no client-side JavaScript required. You can build from truly flat files, HTML as well as several templating languages, the common ones being Markdown or Nunjucks or Liquid, as well as JavaScript as a templating language. And so it’s very approachable again for different mindsets, so that makes it a great tool, I think, to introduce to teams with different backgrounds, different interests in building a website.

Stephanie: But to your question about when would you choose it or where are the boundaries? So it is great for any time that you, as a starting point, when you don’t have any need for dynamic content. Which isn’t to say that you can’t bring it in, you absolutely can. And in fact, that is something they’re actively working on, is stepping into the idea of Islands architecture and things of that nature.

Stephanie: There’s other tools that are built on top of it, where you can easily bring in a framework that you’re comfortable with like Vue. So there are absolutely ways to expand it. That’s actually why I love it is because you can start at a real simple baseline and just build up as you go. I haven’t found a lot of boundaries. In fact, I’m even doing a project that I am sort of working on secretly dealing with user authentication, and that doesn’t sound like something you could do with static. But with the combination of edge functions and serverless functions, which are super easy to incorporate in, I think that the boundaries are being pushed farther and farther out at this point.

Vitaly: Yeah. That’s very exciting to hear just because when were moving from WordPress to Jamstack back in the day, it feels like it was a century ago now, although it was just five years ago, I believe. It was kind of a, “Wow, how do we do this?” Because we have the shop, the membership and well authentication then of course then as well. And so many other moving parts and the comments, all search and so on. And yeah, in fact, I think that, in many ways, Jamstack has been this really good compromise. I remember vividly this excitement that everybody had with fully client-side rendered applications. And that was the time when it felt at least like a revolution, really. And then it was pushed back. Would you say that Jamstack is kind of that push back somewhere to the server? Not too far away from the client. How do you feel about Jamstack? Is it the golden center for the universe of web development?

Stephanie: Yeah. You know, I’m definitely biased at this point. I’ve been working with it for a little over two years now, and so I’ve seen some of that evolution happening. And, again, having that history with WordPress, it’s one of the reasons I really enjoyed 11ty in particular, having that templating ability, but having that static rendered, you don’t have to worry about SSR, it’s just simply static. Your homepage likely is always static. Your marketing website, largely is static.

Stephanie: But, being that center, I really do think it is because you also have… You’re not prevented from incorporating a CMS, for example. You can bring that in. You can still of course add whatever other, as I mentioned, flavor of JavaScript that you need. It doesn’t have to be truly 100% static, but that’s your baseline. And we all know that’s where we put an emphasis on semantics, accessibility, progressive enhancement. And I think that’s another thing you’ll find in the community if you haven’t quite yet gotten into Jamstack and 11ty, in particular, is a focus on returning to that way of building. And I think that’s the part I see a quote unquote “return” to, is caring about those things.

Vitaly: Absolutely. Absolutely. It all fits in nicely then, somehow, with like you mentioned accessibility, of course, and CSS is just something that we both have in common. That we just have an incredible admiration and love and passion for. And every time I read an article that you’re writing, I feel like, “oh, you can do that with CSS now. That’s wonderful to see.”

Vitaly: So maybe you could shed some light on how do you work with CSS? Do you have a particular methodology that you tend to rely on now? Or the way of structuring things? The way of naming things? Of course naming is the hardest part of it all. What seems to be working best for you, for your work, for your projects in terms of building things, in terms of, maybe just to simplify, how do you even start working on a project when it comes to CSS? The folders, the naming, the methodology and stuff like that?

Stephanie: Yeah, absolutely. So I still use Sass. I will continue to use Sass strictly because it allows that organization and I think that’s really critical. I think that’s where a lot of folks begin to have a less than pleasant relationship with CSS, is trying to figure out how to organize. And so Sass for me is that bridge, it’s very critical in my tool belt.

Stephanie: Alongside that, I do tend to use BEM. I’m not always completely strict on it. I don’t always completely rely on even having classes. I think it’s very powerful to focus on the semantics. And I also, I think it’s important to know where I’m coming from. So part of my history involves working on design systems. And so, through that, I’ve become a big proponent of creating components, whether that’s a formal design system or just the way that you’re approaching and organizing and architecting your styles.

Stephanie: I find that to be helpful for me to think of my system as components and to think of my system as having, some folks might know as design tokens, but having like a series of colors and these other, primitive variables, would be another common term, where those are leading into the system. I’m definitely using custom properties. That’s been a huge game changer in how I approach writing styles, both from… Folks might be used to opening up a site, looking at the HTML element and seeing just a whole laundry list of custom properties. I keep mine a little more focused, like I said, colors and really high up global tokens. But an important way that I write my styles and my components is really leaning on custom properties to allow very easy variations of those, very scalable variations of those.

Stephanie: And so, you mentioned my workshop earlier, that’s something we really go into because when you are starting to incorporate those things, you start to… I think it was kind of a light bulb moment for me, learning about these things where my styles became so much more simple, so much more efficient, so much less repetitive, being able to use things like custom properties. So Sass, custom properties, a little sprinkle of BEM, and also, in some cases, relying on particular element selectors that directly hook into accessibility features. So it’s kind of a combination of those things, but it all starts for me at the HTML level. And then I go to my CSS. So, that’s also an important part of my process.

Vitaly: Sure. Of course. Yeah. I also remember vividly that moment when we actually ended up getting custom properties in all the browsers, and I was like, “Wow, you can now do custom kind of variables?” CSS variables, dynamic variables now in the browser. That was incredible.

Vitaly: That also brings me to this notion of… This is a conversation that I keep having with some folks, just thinking about what is the role of Sass today and how is it going to evolve? Just to bring it a little bit more in the context, we now have custom properties for years now. But we also have these proposals for scoping and for nesting, which might be coming up soon. But then on top of that… I’m really excited about that, by the way, just because right now, every time you’re using Sass, we have to produce this humongous chain of classes, if you do nesting, nesting, nesting, nesting.

Vitaly: But if it is actually just written in CSS and just clean and beautiful on how it should be. Plus on top of that, of course, cascade layers, which are already well supported. So I’m wondering at this point, of course, not to mention… I mean, so many things coming up, it’s incredible in CSS, the color mix, color contrast, lighten, darken, all those things that are also coming to native CSS. So I’m wondering just about your take, where do you see now, Sass moving? Is it going to be more for literally processing for things like Mixins, functions, those kind of things? And where would you say this should be in CSS?, and that should be probably staying Sass?

Stephanie: Yeah. So all of those are super valid comparisons to how features and tools such as Sass has informed or helped inform the evolution of CSS as a language. And for sure, I’m excited for those things to come and be native. As I mentioned, organizations is still a huge reason I’ll continue to use Sass to compile my style sheets and still have that separation, like I said, of my components or whatever other parts that are coming together.

Stephanie: Also in a design systems context, or other contexts where you are creating a reusable system and you want to have a little bit better management of your, again, whether you call them tokens or whatever you call those sort of baseline configuration, of how the different customizations enter that style sheet is, I believe still where Sass is going to shine.

Stephanie: And like you said, functions, Mixins. I’m finding myself using less Mixins these days, because, like I said, custom properties gap fills what I was using Mixins for, in some cases. But I still use Sass for functions. Absolutely. So, whether that’s looping through my tokens to spit out automatically different utility styles. To me, that’s still plenty useful enough that I’ll continue to use Sass and that’s functionality that we don’t see in the horizon for CSS.

Stephanie: But yeah, I definitely have changed some of the ways I’ve used Sass. Using :is() and :where(), sometimes those help simplify my selectors in a way that maybe was using Sass for before. So yeah, I’m absolutely a fan of switching over the functionality that should belong in the browser to the browser, but still finding the organization and functions, in particular, to be useful in Sass for me.

Vitaly: Yeah, absolutely. It’s interesting because you mentioned BEM previously and I just recently had a conversation with a few JavaScript developers and the conversation went in a very unusual way for me, because usually I would be comfortable using BEM. I mean, just like you, not the dogmatic traditional the big BEM, but the small BEM. And I do like my hyphens and I do like my underscores, so don’t judge me on that.

Vitaly: But I heard this notion of, BEM, is it still a thing?Isn’t it like from 2017 or ’18 something? Why would you use BEM today, if you have Tailwind and you have CSS and JS if needed? Why do you work so hard to have the naming and have this relationship, which could be potentially just, create user using atomic classes or just writing some CSS and JS.

Vitaly: And I had my arguments about why I would still prefer BEM, but I see that many people feel like, isn’t BEM outdated? And, isn’t Tailwind the thing now? So what are your thoughts on that? And maybe specifically on Tailwind that would be probably quite relevant.

Stephanie: So for me, it’s not the right tool and that has to do with the way that I work, but also the team conventions that I have. And that’s usually what I tell folks, is it depends what kind of project you’re working on. It depends on the makeup of your team, your skillset, your project architecture, just like anytime you choose a tool, all of these things play a part.

Stephanie: As I mentioned, I’m a proponent of components. And so an important thing to remember is that not everybody is using a JavaScript framework. In fact, if we look at global stats, that’s actually a pretty minor part of the web. I know it feels like everybody is using React or whatever other tool, but it’s actually not true in practice. And especially if you’re coming into an established team that is not the latest. A new startup or something. You may not find Tailwind.

Stephanie: And so that’s fine. But the point is that some of these methodologies aren’t as transferable across projects either. So if you’re solely producing one type of project, one application, one product, it’s easier to make a decision towards something like Tailwind, rather than if you’re working on a project that’s intended to be used across multiple outcomes. Maybe I’m using it on my 11ty static site where I’m writing in Nunjucks. But I also need to share it to a back-end application that’s built in React. So my style sheet is going to be a lot more portable if doesn’t rely on CSS and JS, or if it’s not completely wrapped up already in React components. And, teams have found ways to overcome that. And again, your experience is going to heavily weigh into what choice you make here.

Stephanie: Another big one that comes up for folks is the issue of documentation and I absolutely respect that. Where it’s easier sometimes to pick up a tool that has ready-made documentation. So, that’s absolutely consideration in making that decision. I wouldn’t say that BEM is outdated. It’s just a naming convention where I think, as I said, it lends to being a little more portable. The intent of it is to be able to identify what set of styles go together. So we can apply that in multiple locations and have a good idea. I think perhaps in some instances it might be a little more memorable if you don’t have a system where you are able to create and template out components, because again, that’s not every environment that folks are practically working in.

Vitaly: Absolutely. Yeah, of course. It’s also fun to be just talking, thinking about all the things you could do with CSS and moving back to what we talked about briefly before, so many powerful things coming up, it seems like. Just a recent announcement of all the features coming to Safari 16. This is just unbelievable. It’s like Christmas coming in before Christmas. And then of course we have all the wonderful things coming up in Chrome 103 and it’s just all wonderful. Incredible. What are you most excited about of all of those things? Is there anything where you say, “okay, this is life changing for me, this is changing everything that I’m doing with CSS.”

Stephanie: For me, it’s the one, two punch of container queries and :has(). I am excited for both of those to be stable. And again, coming from the design system context in particular, I just think we’re going to be able to create the most robust and scalable components we literally haven’t been able to achieve before. So I’m very excited about that as my top two picks coming up here.

Vitaly: Okay, well maybe we should be expecting some articles from you on them, although maybe you have written them already, who knows? I think you might have. Do you find yourself writing as much as you used to be or do you have a lot of writing coming up in the months to come?

Stephanie: Yeah. So writing’s taken a tiny bit of a backseat just because I’ve been working on a project a little more longer term, that’s a build out of a new side project here. So yeah, it makes it tough because I have a backlog definitely of writing ideas, so, hope to get back to that soon.

Vitaly: I hope we’ll get there as well. Well maybe, quickly a few questions to also slowly wrap up. Do you think you have a dream feature that you would love to CSS to have? Frankly, I don’t know, to be honest, if I had to answer that question, I’d be probably out of ideas because I always wanted the parent selector, well, :has() is much more than that, but we have that. And I always wanted container queries. Well, we have that and I always wanted subgroup, well, we kind of have it coming. What else should I wish for? I don’t know. Do you have any dream features that CSS desperately needs?

Stephanie: I think I’m similar as you, at this point, it’s waiting for certain things to land. A year or two ago. I probably would’ve said color contrast in the browser, but that’s even coming. So yeah, the list is definitely shortening of what, we still are waiting for. Another one for me, would’ve been a more native way to do fluid typography and we are also getting that once container queries hits because of container units, we’ll be able to do that.

Stephanie: So yeah, I think the last thing for me is, we have media queries related to Viewport. We’re going to get the container ones. The last thing for me would be expanding that a bit to a few more contexts, like a user browser zoom context would be useful to me. And I’m sure there’s some other device features, and things in that area might be the remaining area to grow a little bit. Sometimes there’s privacy concerns, hardware limitations, these things that prevent those particular features. But yeah, that’s what I kind of have my eye on.

Vitaly: Excellent. Sounds good. Sounds exciting. I’m just really excited to see what is coming up next. It just always keeps me busy. Sometimes I would find myself just going to something like Chromestatus.com just to see, is there anything new on the horizon? Just because I’m curious. Usually it takes a little bit longer than just a couple of days to see something new showing up though. But yeah, this is how excited I am.

Vitaly: Well, so we’ve been learning a little bit about CSS in this episode today. So what have you been learning about lately, Stephanie? Maybe any podcasts that you can recommend? Any books, any, I don’t know, TV shows, anything that’s really got your interest or attracted your interest over the last few months or so?

Stephanie: Yeah, so an area I unexpectedly found myself enjoying is watching developers on Twitch. So I’ve been learning all kinds of stuff from some fabulous streamers. Folks might already know, but White Panther whose Salma Alam-Naylor is excellent. And also I’ve really enjoyed Alex Trost who runs the Frontend Horse community. So if you’re looking to learn maybe some unexpected things in a little different format, that’s what I encourage folks to do. Kind of shake up where you’re getting your inspiration.

Vitaly: Excellent. Well, if you’d like to learn a bit more from Stephanie, we have an upcoming Smashing workshop, which is going to look into all kind of things CSS. probably also Sass, probably also BEM, and probably also 11ty, if I’m not mistaken. This is taking place on July 11-25th. And of course there are a few tickets left, so please do take a look and join in. And if you, dear listener, would like to hear more from Stephanie altogether in general, you can also find her on Twitter where she’s @5tp3h or Steph and on her website at https, of course, thingdobecreate.com.

Vitaly: Well, thanks for joining us today, Stephanie. Do you have any parting words with the wonderful community? Things that will remain in somebody’s memories centuries after they hear it here today?

Stephanie: Big responsibility. Experiment, play and share what you know.

Great (and Free!) Web Development Books You Can Get Online

Right after “Where is the best place to learn?” perhaps the most commonly asked question I hear from folks getting into code is “What web development books should I get to learn?” Well, consider this an answer to that question as I’ve curated a list of books that are not only great for getting into front-end development but also freely available.

Books on CSS

This is the bulk of where we’re going to hang out because, well, this is a site mostly about CSS!

The Magic of CSS by Adam Schwartz

Perfect for: Next steps in your CSS journeyLearning level: IntermediateRequires: Some basic understanding of CSS

Adam Schwartz covers six CSS concepts in this book, including the box model, layout, tables, color, typography, and transitions. These are things even stump some seasoned CSSers, some of these concepts might be confusing. Adam has gone to a great length to demystify each.

In addition to the book being a great primer on complex CSS concepts, I love how each of the CSS properties mentioned throughout the book is clickable so you can always click on them to see how each is applied. There are many illustrative examples and recommendations for further reading, should you desire to learn more about each chapter.

I found the chapter on colors very interesting not only because it gets into the best practices for using color accessibly, but also because there’s super practical applications, like when Adam gets into using CSS to support an organization’s branding.

Resilient Web Design by Jeremy Keith

Perfect for: Developing strategies for writing codeLearning level: IntermediateRequires: Some basic understanding of CSS

Straight from the introduction:

You won’t find any code in here to help you build better websites. But you will find ideas and approaches. Ideas are more resilient than code. I’ve tried to combine the most resilient ideas from the history of web design into an approach for building the websites of the future.

What Jeremy does so well is describing soft skills, like planning, outlining, and approaches for writing code. So, rather than dropping in code snippets throughout the book, what you’ll find are details about code strategies, such as progressive enhancement, deciding on what tooling to use, and the challenges of writing future-friendly code.

And for those of you who have not had the pleasure of listening to Jeremy narrate content (like he does in the Web History series), there’s an audio file available to download.

Beginning CSS Web Development: From Novice to Professional by Simon Collison

Perfect for: The fundamentals of CSSLearning level: Absolute beginnersRequires: Nothing but time and motivation

It may be written in 2006, but Simon’s coverage of web standards and accessibility is timeless and relevant today. He provides an understanding of interoperability as well as approaches for building web applications, including the early planning phases that often go overlooked.

The book has two broad parts which are further divided into 16 chapters. Part 1 covers CSS topics, like working with text, links, lists, backgrounds, images, tables, and forms. It really doesn’t skimp on the details either.

Part 2 is all about layout, shedding light on usability and layout manipulation, plus a handy case study. The chapters are arranged in such a way that one chapter naturally flows into the next. Each chapter also contains a concluding section that highlights all the important concepts covered in the chapter.

Indeed, the book provides novice developers a solid background in CSS and helps them gradually with more advanced concepts. It will make your CSS journey easier.

Books on HTML & CSS

CSS and HTML are often taught together, which can be especially helpful when you’re writing your first lines of code and want to know how the two languages interact with one another.

Learn to Code HTML & CSS by Shay Howe

Perfect for: Starting your front-end journeyLearning level: BeginnersRequires: No prior experience at all

Shay refers to this book as a simple and comprehensive guide dedicated to helping beginners learn HTML and CSS. He does this by focusing on common elements of front-end design and development. Some of the lessons covered are Box Model, Positioning, Typography, Background and Gradients, Lists, Media, Forms, and Tables. In the first chapter *Building Your First Web Page, Shay analyzed the contents of a typical website including elements, attributes and setting up the HTML document structure, code validation, selectors and CSS resets. I find the book very instructive especially as it went beyond the surface to address many key concepts with code samples, which you can follow along.

One profound thing about this great book is that, Shay built a complete project from scratch throughout the 12 lessons and at the end of each lesson, he provided a summary and links to the current state of that website (so you can compare with yours if you follow along) and the source code at every stage of the lessons.

If you’re a learner who learns by doing, you will find this material very useful and by the time you’re done, you will have developed a multi page functional website.

An advanced sequel of the course is also available free via the same link.

HTML & CSS: Learn the Fundamentals in 7 Days by Michael Knapp

Perfect for: Starting your front-end journeyLearning level: BeginnersRequires: No prior experience at all

Can you possibly learn everything there is to know about the HTML and CSS in seven days? Probably not, but that’s why this 2017 book by Michael Knapp is focused straight on the fundamentals. Michael delves into a brief history lesson before launching into HTML and CSS structure, logic, and presentation. You’re going to get all up to speed to the point where you should feel pretty confident about putting a basic webpage together, plus a few extras along the way as the book touches on SEO and analytics.

The book is comprised of simple programs that you can run on your computer if you wish to follow along.

The ebook version is available for free on Apple Books, but there is a Kindle version as well if you already have a subscription there.

The Greatest CSS Tricks Vol. 1 by Chris Coyier

Perfect for: Marveling at what CSS can doLearning level: IntermediateRequires: Some CSS experience

Did you know that CSS-Tricks has a book on CSS too? It would be silly to leave that off this list because what you get is a collection of classic CSS trickery that’s explained by none other than Chris Coyier. In fact, Chris handpicked all of the examples covered in the book from his many, many (many!) years running this here site from the plentitude of tricks that have crossed his desk.

Each trick solves a particular pain point. For instance, the first “Pin Scrolling to Bottom” trickdemonstrates how the overflow-anchor CSS property can be used to create the same chat-like interface of a tool like Slack, where the screen is anchored at the bottom in a way that feels as though the page is scrolling for you as new items are added.

Books on process

Code is just as much about how we write code and collaborate on projects with others as it is about the actual code we write. The following books are great starting points for everything from planning and project management to communicating and collaborating with others.

Collaborate: Bring People Together Around Digital Projects by Ellen De Vries

Perfect for: Being a better collaboratorLearning level: N/ARequires: An open mind to working well with others!

Ellen addresses something in this book that we all have to deal with: collaborating with others. And it’s no small deal — the book is divided into four parts that go super deep into things we can go to work well with others:

Know how to prepare the ground and create the right conditions for collaboration.Nurture the group culture in the early stages of collaboration.Maintain a healthy collaborative process.Reap the rewards of a collaboration.

As a content strategist, Ellen has the right kind of experience to help anyone be part of a collaborative project, or get the most from a collaboration.

The Modern Web Design Process by webflow

Perfect for: Senior designers, project managersLearning level: N/ARequires: Some basic understanding of CSS

This free ebook features a seven-step design process that’s meant to help define the workflow for today’s brand of web design.

That includes:

Setting goalsDefining scopeSitemaps and wireframesWorking with contentHandling visual elementsTestingShipping

Anyone starting a new design project or in the middle of a design project will find the invaluable insights throughout the book. And what’s most remarkable is how this is written in a way that almost feels as though you are being hand-held through an entire project from concept to completion.

Designing for the Web by Mark Boulton

Perfect for: Learning to work with clientsLearning level: BeginnersRequires: A genuine interest in design

It seems many organizations tackle design differently. But author Mark Boulton documents a thorough design workflow in Designing for the Web that de-mystifies many challenges and covers everything you need to know.

What’s unique about this book is that it’s really about work. Sure, there’s a bunch of hugely valuable information on design best practices for things like typography, color, and layout, but what you’re really going to take away from this book is how these fit into a design workflow. It teaches you how to research, the technologies we have to implement ideas, and ultimately, how to work with others as well as clients — perfect fodder for folks including design leads, project managers, freelancers, or anyone who’s involved in the project delivery process.

Learn Version Control with Git by Tower

Perfect for: Mastering GitLearning level: All levels welcomeRequires: No prior knowledge at all

In this book, the team behind the popular Tower client for Git introduce learners to the crux of version control system using Git. Developers who work in teams will particularly find this very useful, as it helps in effectively collaborating with team members building different features of a project even when you’re thousands of miles apart. That said, it’s still really great for anyone who might be shy of the command line and wants to build confidence there.

And since the book is by the maker of an application that interacts with Git, you’re going to get a nice dose of using Tower as a GUI in addition to working directly on the command line.

So, whether it’s committing, branching, merging, pull requests, forking work, or handling merge conflicts, you’re going to get a whole lot from this book.

Books on JavaScript

Learning JavaScript always seems to be en vogue. In fact, Jason Rodriguez wrote about the JavaScript learning landscape in 2018 and provided a nice list of free books. Not too much has cropped up since then, but here are my thoughts on the following books.

Eloquent JavaScript by Marijn Haverbeke

Perfect for: Getting better at writing JavaScriptLearning level: Intermediate to seasoned developersRequires: Prior JavaScript experience

Eloquent JavaScript really lives up to its name. Personally, I consider this one of the best-written JavaScript books I have ever come across. Marjin’s writing style is engaging, especially with how he introduces programming concepts and carries the reader along. In his words, the book is simply about instructing computers and making them do what you want them to do.

The book is a deep dive into JavaScript spread across three parts and 21 chapters. You’re going to read a bunch about basic programming concepts, such as values, types, operators and functions, to advanced concepts like regular expressions, modules, the DOM, and asynchronous programming. He starts every chapter with a somewhat philosophical quote to prepare the reader for what lies ahead and then dives straight into the topic.

Plus, there’s three projects to help you practice your newfound skills.

Understanding JavaScript Promises by Nicholas C. Zakas

Perfect for: Those who want to learn all about asynchronous programming with promises in JavaScript.Learning level: IntermediateRequires: Basic JavaScript chops

JavaScript promises were introduced in 2015 as part of the ES6 specification to handle asynchronous functions in JavaScript. According to MDN:

A promise is an object representing the eventual completion or failure of an asynchronous operation

In this 51-page book, Nicholas explains the concept of Promises over three chapters: Basics, Chaining Promises, and Working with Multiple Promises. Although the link to the book we’re providing is the free community version, the full version (available on Amazon) has two more chapters on Async Functions and Unhandled Rejection Tracking. Nicholas simplified the concept of Promises with several illustrations and examples. You will learn how to use then(), catch(), and finally() and understand how to chain multiple promises together. Nicholas also covers the assignment of rejection and settlement handlers. You may want to give the book a read to solidify your understanding of the topic.

Nicholas is a veteran JavaScript book author who has been writing about JavaScript for over 15 years. He brings his wealth of experience to bear in this book (just as he has in his work here at CSS-Tricks).

Speaking JavaScript by Alex Rauschmayer

Perfect for: Leveling up from beginning JavaScriptLearning level: IntermediateRequires: Knowledge of object oriented programming

This book is presented in four chapters covering more than 30 topics. Here’s how it breaks down:

The first chapter is a nice refresher on syntax, variable types, functions and exception handling.The second chapter offers historical perspective into JavaScript as a prelude for the types of features covered throughout the rest of the book.Chapter 3 is presented as more or less a reference book with short, clean examples.The final chapter outlines tips, tools and libraries to help write better JavaScript and follow best practices.

Secrets of the JavaScript Ninja by John Resig and Bear Bibeault

Perfect for: Creating a cross-browser JavaScript library from the ground upLearning level: IntermediateRequires: Some prior programming experience

There’s actually a newer edition of this book, but the 2012 edition is the one that’s free. Either way, it’s a good opportunity to learn from John Resig; you know, the guy who created jQuery.

The techniques covered here include closures, functions, the DOM, object orientation with prototypes, and cross-browser strategies. One nice perk is that each chapter is followed by a brief recap that’s perfect for a reference once you’ve finished the book.

Learning JavaScript Design Patterns by Addy Osmani

Perfect for: Learning to write more efficient JavaScriptLearning level: IntermediateRequires: A decent level of JavaScript experience

The concept of design pattern refers to a reusable solution to a commonly recurring problem in application development. In this book, Addy Osmani covers the implementation of common design patterns using ES6 and beyond, as well as React-specific design patterns, which can be super handy when working on complex React apps where maintainability is a primary goal.

Some of the patterns covered include Singleton, Proxy, Provider, Prototype and Observer patterns. In some cases, Addy includes pros and cons of using some of these patterns and how they may affect the performance of your application.

You Don’t Know JS by Kyle Simpson

Perfect for: Mastering JavaScriptLearning level: BeginnerRequires: Little or no prior programming experience

While the title might be a bit provocative, what Kyle is implying here is that he writes this book assuming you have no prior JavaScript experience whatsoever.

Kyle begins starts by going through the rudiments of programming as seen through the lens of JavaScript. He then proceeds, in subsequent chapters, to introduce more advanced concepts like scope and closure, the this keyword, object prototypes, async, and performance.

There’s a lot of excellent details and explanations in here, and Kyle makes it super easy to understand by avoiding super technical jargon. There is also many exercises designed to reinforce your learning. This book will definitely get you up to speed with JavaScript. There’s second edition of the book in the works that you can track in GitHub.

The JavaScript Beginner’s Handbook by Flavio Copes

Perfect for: A beginner’s referenceLearning level: Just getting startedRequires: Email sign-up, maybe some prior experience

Flavio has put together a very useful JavaScript reference for those just starting out. It’s more like a quick reference guide than a textbook, so those of you just starting out might want to consider this as something you keep on your desk rather than something you sit with for long periods of time.

JavaScript for Data Science by Gans, Hodges & Wilson

Perfect for: Getting into data visualizationsLearning level: Intermediate to advancedRequires: A decent handle on JavaScript

The authors cover core features of modern JavScript, including callbacks, promises, inheritance, objects and classes. They also get into testing using Mocha, React, and data vizualization, all of which are great for anyone looking to level up their code and how its written. The book doesn’t get as deep into many the concepts as some of the other books, but it really shines when it gets into data science.

The book uses Data-Forge; a JavaScript library designed for working with tabular data. There are numerous exercises to help readers keep up to speed with the subject of discussion. The last chapter also includes a capstone project that pulls everything together.

Wrapping up

I sure hope this collection of books help you, whether you’re taking your first steps in front-end web development, have a dozen years under or belt, or you fall somewhere in between. I know how hard it is to get into something new for the first time and the feeling of not knowing where to look. I also know how it feels to hit a plateau and need something to level me up. There should be something for everyone here, regardless of where you are in your learning journey.

And, hey, if you have any other books that are available to snag for free online, please share them in the comments! I bet we can get an even bigger list going.

Great (and Free!) Web Development Books You Can Get Online originally published on CSS-Tricks. You should get the newsletter.

Demystifying The New Gatsby Framework

After the release of Gatsby 4, the Gatsby team saw the biggest rise in signups on Gatsby Cloud. According to Gatsby co-founder Kyle Mathews:

“Gatsby 4 is the most powerful version of Gatsby yet. We’ve made Gatsby 10x faster to build and deploy by opening up two new rendering modes, adding support for Parallel Query Processing, and making a host of other optimizations and improvements.”

— Kyle Mathews

Until a few months ago, Gatsby.js was best suited to make not-so-big Jamstack websites, but with the release of Gatsby 4, how well does Gatsby work with big and rapidly-changing pages? And how will it compare to other frameworks like Next.js? We will hopefully answer these questions in the next article!

New Gatsby 4 Features

Gatsby 3 had a lot of useful features, and it stood out among other pre-rendering frameworks due to being extremely fast when using Static Site Generation. However, it lacked the tools of other frameworks — mainly Next.js — to render pages on request using Server-Side Rendering. Gatsby heard its community, and besides a lot of optimization features, Gatsby 4 brought two more rendering options: Deferred Static Generation (DSG) and the good old Server-Side Rendering (SSR).

Deferred Static Generation (DSG)

One of the problems that a lot of people had with Gatsby was its very long build times. When using SSG, building the pages and all the heavy lifting had to be done on the server, which led to longer build times as pages in your site grew. To solve this, Gatsby started to use incremental building only to build new or changed pages and keep the other ones in the cache. However, the first build without cache always took a long time to finish. The incremental building is very helpful, but it didn’t tackle the roots of the problem, and that’s where Deferred Static Generation comes in.

Deferred Static Generations is very similar to what SSG achieves, but it is more efficient and has a different method of delivering pages. In DSG, you can choose pages to “delay,” which means not to build with the rest of the pages but once a user requests them. After the first request, the page will be available in the CDN and will be the same as any other page generated with SSG. This is very useful when a site has old and unvisited pages that aren’t worth building on each production build.

If you are worried that DSG can tank your page’s SEO, remember that pages built using DSG only behave as a Server-Side Rendered the first time they are requested, and then they act just like any other SSG page. So, according to Gatsby, your page will act as an SSG 99.9% of the time, and Google will analyze its SEO that way.

As you may notice, DSG requires a running server to listen for user requests and build the requested page for every other user onwards. It is a game-changing feature in Gatsby since Gatsby was known for being a server-less SSG framework, but now you can combine SSG with other rendering options involving a server. Even though it changes the backend structure — only if you use DSG or SSR — it gives developers more flexibility to work with Gatsby.

Server-Side Rendering (SSR)

If DSG uses a server to work, does that mean that Gatsby can use a server to render all pages on request time? Absolutely yes. This was the most long-awaited feature in Gatsby and the only one that made a lot of developers choose other pre-rendering frameworks over Gatsby. In case you don’t know, Server-Side Rendering consists in building a page each time a user requests it. And it’s very useful when the page content depends on the user that requested it, so we can deliver a static and customized page to each user.

SSR is a well-known feature used daily in frameworks like Next.js, which Gatsby finally implemented. Now developers using Gatsby have an enormous range of options to deliver pages to users, either with Static Site Generation, Deferred Site Generation, Server-Side Rendering, or even — if you are brave enough — with Client-Side Rendering.

Parallel Query Running

Besides the new rendering options, Gatsby still brings a lot of other features to improve performance and developer experience. As previously mentioned, one of the major drawbacks JAMstack and static sites had was their long building times. In addition to incremental building and DSG, Gatsby 4 introduces Parallel Query Running to diminish build time even more.

As you may know, Gatsby uses a data layer to group external data and then query it onto your site. Sourcing the data from your content sources into the data layer is relatively easy and fast. However, the process of querying the data from the data layer and querying it into the pages is pretty time-consuming. This step is called query running, which happens in the middle of the build and is the longest by far, taking around 40% of the build time.

Query running only was able to use one of the cores of the CPU, so all the queries had to be done one at a time. But in Gatsby 4, the entire way data was handled was changed since it migrated from Redux to its own in-memory data store and switched to lmdb-js.

“Lmdb-js is an ultra-fast NodeJS and Deno interface to LMDB; probably the fastest and most efficient key-value/database interface that exists for storage and retrieval of structured JS data.”

With this new architecture, all queries can be done across all available cores, which leads to immensely faster build times.

Build Time Optimization

Lastly, both a little and big change that may pass unnoticed between all the prior features is all the configurations and tweaks made to improve build times. One of the major reasons build times and even developer server starts were slow was due to an incorrect configuration of the local development environment or when Gatsby’s sites were deployed anywhere other than Gatsby Cloud.

The Gatsby team has changed several critical parts of Gatsby’s infrastructure across Gatsby 3 minor updates and is now in Gatsby 4 to reduce build and development times. I consider reducing development times a key change to enhance developer experience since it becomes tedious to restart and wait for the developer server each time you make a change that requires a restart to take effect.

Gatsby Cloud

What’s Gatsby Cloud

Even though Gatsby is known for being a framework, the Gatsby team offers other great products like Gatsby Cloud. Gatsby Cloud is a deployment service with an edge network dedicated uniquely to deploying Gatsby sites in a matter of minutes. It has been around for a long time and is very similar to Netlify. The service has been optimized only to build and host Gatsby sites, which means you can’t host Next.js, Vue, Angular, or Vanilla JS sites, but in exchange, Gatsby Cloud offers greatly faster build times for Gatsby sites.


The main advantage of using Gatsby Cloud to host your Gatsby project is the little to no configuration you need to start hosting it. It can host and run a Gatsby Project without configuration and supports all Gatsby’s new rendering features and more out of the box. As long as they are declared in your code, the server won’t have problems understanding and hosting your project. So, if you want to migrate from Gatsby 3 to 4, you may consider switching to Gatsby Cloud for your migration.

Build And Deployment Time

As said before, a lot of people didn’t prefer Gatsby due to its long build times. But Gatsby Cloud brings even more features to make build times faster, and it has been configured to use all optimization features like incremental buildings, parallel querying, caching, and support pages using DSG to the point where a CMS update from Contentful on Gatsby’s 10,000-page site took around 10 seconds on average.

Besides build time, another aspect that has been drastically improved with Gatsby Cloud is deployment time. Deployment time is the time it takes to push your site onto the edge of the CDN, and it accounts for the final time between triggering a build and releasing your site to the world. It can take as much time as build time, to the point that deployment times for a medium-size static site of around 10,000 pages can take 2 to 10 minutes. But the same medium-size site takes, on average, a surprising 2-5 seconds in Gatsby Cloud.


Similar to Netlify, Gatsby Cloud workflow is based on Github, Gitlab, or BitBucket repositories. Gatsby Cloud fetches a Gatsby project from a repository, builds the site, and/or runs the server. And like many other services, you can enable automatic deployment when a branch changes in your repository. In case external data from a source like a CMS changes, Gatsby Cloud offers a build webhook to trigger a production build.

Other small workflow features I really liked were:

It lets you create a preview site with all your changes and a shareable URL.
Lighthouse Support
It gives you a Lighthouse report every time a build is finished.

Gatsby Functions

Lastly, we will see Gatsby’s serverless functions in action. They aren’t completely part of Gatsby Cloud since they can be deployed in Netlify too, but deploying Gatsby Functions is more straightforward in Gatsby Cloud. Now, what are Gatsby’s Functions? In simpler terms, they let you add an express-like backend to your Gatsby project to create an API, authenticate users, or submit forms.

Why would I want to create a backend in my Gatsby project? Most Gatsby use cases don’t require creating a backend or API. Still, in cases where there is more than one frontend application using the same data, it is a very good idea to decouple your data from your main frontend and make it accessible through an API, so it is accessed the same way with the same logic through all frontends. The power of Gatsby Functions is to have your backend hosted in the same place as your frontend, but they communicate headlessly through an API.

Gatsby Cloud vs. Netlify

After seeing all the features offered by Gatsby Cloud, there isn’t a decisive factor in choosing one over another. Both of them offer pretty similar services and functionalities, and they come in a free tier, too. The main difference is that you can only host a Gatsby project in Gatsby Cloud, but with Netlify, you can host projects using almost any library or framework you want, such as Next.js, create-react-app, Vue, Angular, etc. So, in case you want to host a Gatsby project, I would recommend Gatsby Cloud since it is amazingly optimized and guarantees good results.

Gatsby 4 vs. Next.js

In the SSR ecosystem, the clear dominant player has been Next.js, and many comparisons between Gatsby and Next.js ended by saying that Next.js offered SSR and Gatsby did not. And even though Gatsby was still extremely useful and effective, the fact that it didn’t support SSR was a decisive factor when choosing a framework to use. But the introduction of Gatsby 4 changed the game completely.

Since this article is dedicated to Gatsby’s new features, I will try not to focus too much on Next.js features. Still, I will say that Next.js and Gatsby currently offer similar functionality, and we can achieve almost the same results with both frameworks. However, there are still a lot of factors and features to consider when choosing one framework or the other. Gatsby offers features that Next.js doesn’t, like Deferred Static Generation, a data layer, and an enormous plugin library. On the same note, Next.js offers Incremental Static Regeneration and Server Components which is currently on alpha.

You can achieve the same user experience with both frameworks, and they will help you make beautiful websites. So, to choose a framework, I strongly believe the developer experience is the decisive factor. I feel Gatsby offers a better DX due to its awesome data layer that lets developers source their data and keeps it all in the same place, so it can be queried the same way. Another reason is its plugin library, which lets you add out-of-the-box support to CMS, internalization, e-commerce, analytics, offline support, et cetera. These are life-saving features that have helped me quickly start working on a new project.


After seeing all the new features of Gatsby 4, we can confidently say that the future of Gatsby is already looking great! It is clear that the Gatsby team has been pretty self-critical and has heard its community since all Gatsby 4 features were wanted by the community for a long time. Therefore, I am pretty confident that Gatsby will keep following this path, and we will have many other cool features in the future.

Even though I might sound like a Gatsby salesman, I don’t consider it the best framework, just one that is completely worth experimenting with. Next.js is vastly more used among the SSR ecosystem, and the community believes it gives a better developer experience than Gatsby, but with Gatsby 4 this trend may change a little. It isn’t putting Next.js out of business any time soon, but thanks to its new rendering options, Gatsby 4 will clearly be on your list of frameworks to try out on your next project.

Single Element Loaders: The Bars

We’ve looked at spinners. We’ve looked at dots. Now we’re going to tackle another common pattern for loaders: bars. And we’re going to do the same thing in this third article of the series as we have the others by making it with only one element and with flexible CSS that makes it easy to create variations.

Article series

Single Element Loaders: The SpinnerSingle Element Loaders: The DotsSingle Element Loaders: The Bars — you are hereSingle Element Loaders: Going 3D — coming July 1

Let’s start with not one, not two, but 20 examples of bar loaders.

CodePen Embed Fallback
CodePen Embed Fallback

What?! Are you going to detail each one of them? That’s too much for an article!

It might seem like that at first glance! But all of them rely on the same code structure and we only update a few values to create variations. That’s all the power of CSS. We don’t learn how to create one loader, but we learn different techniques that allow us to create as much loader as we want using merely the same code structure.

Let’s make some bars!

We start by defining the dimensions for them using width (or height) with aspect-ratio to maintain proportion:

.bars {
width: 45px;
aspect-ratio: 1;

We sort of “fake” three bars with a linear gradient on the background — very similar to how we created dot loaders in Part 2 of this series.

.bars {
width: 45px;
aspect-ratio: 1;
–c: no-repeat linear-gradient(#000 0 0); /* we define the color here */
var(–c) 0% 50%,
var(–c) 50% 50%,
var(–c) 100% 50%;
background-size: 20% 100%; /* 20% * (3 bars + 2 spaces) = 100% */

The above code will give us the following result:

Like the other articles in this series, we are going to deal with a lot of background trickery. So, if you ever feel like we’re jumping around too fast or feel you need a little more detail, please do check those out. You can also read my Stack Overflow answer where I give a detailed explanation on how all this works.

Animating the bars

We either animate the element’s size or position to create the bar loader. Let’s animate the size by defining the following animation keyframes:

@keyframes load {
0% { background-size: 20% 100%, 20% 100%, 20% 100%; } /* 1 */
33% { background-size: 20% 10% , 20% 100%, 20% 100%; } /* 2 */
50% { background-size: 20% 100%, 20% 10% , 20% 100%; } /* 3 */
66% { background-size: 20% 100%, 20% 100%, 20% 10%; } /* 4 */
100% { background-size: 20% 100%, 20% 100%, 20% 100%; } /* 5 */

See what’s happening there? Between 0% and 100%, the animation changes the background-size of the element’s background gradient. Each keyframe sets three background sizes (one for each gradient).

And here’s what we get:

CodePen Embed Fallback

Can you start to imagine all the possible variations we can get by playing with different animation configurations for the sizes or the positions?

Let’s fix the size to 20% 50% and update the positions this time:

.loader {
width: 45px;
aspect-ratio: .75;
–c: no-repeat linear-gradient(#000 0 0);
background-size: 20% 50%;
animation: load 1s infinite linear;
@keyframes load {
0% { background-position: 0% 100%, 50% 100%, 100% 100%; } /* 1 */
20% { background-position: 0% 50% , 50% 100%, 100% 100%; } /* 2 */
40% { background-position: 0% 0% , 50% 50% , 100% 100%; } /* 3 */
60% { background-position: 0% 100%, 50% 0% , 100% 50%; } /* 4 */
80% { background-position: 0% 100%, 50% 100%, 100% 0%; } /* 5 */
100% { background-position: 0% 100%, 50% 100%, 100% 100%; } /* 6 */

…which gets us another loader!

CodePen Embed Fallback

You’ve probably got the trick by now. All you need is to define a timeline that you translate into a keyframe. By animating the size, the position — or both! — there’s an infinite number of loader possibilities at our fingertips.

And once we get comfortable with such a technique we can go further and use a more complex gradient to create even more loaders.

CodePen Embed Fallback

Expect for the last two examples in that demo, all of the bar loaders use the same underlying markup and styles and different combinations of animations. Open the code and try to visualize each frame independently; you’ll see how relatively trivial it is to make dozens — if not hundreds — of variations.

Getting fancy

Did you remember the mask trick we did with the dot loaders in the second article of this series? We can do the same here!

If we apply all the above logic inside the mask property we can use any background configuration to add a fancy coloration to our loaders.

Let’s take one demo and update it:

CodePen Embed Fallback

All I did is updating all the background-* with mask-* and I added a gradient coloration. As simple as that and yet we get another cool loader.

So there is no difference between the dots and the bars?

No difference! I wrote two different articles to cover as many examples as possible but in both, I am relying on the same techniques:

Gradients to create the shapes (dots or bars or maybe something else)Animating background-size and/or background-position to create the loader animationAdding mask to add a touch of colors

Rounding the bars

Let’s try something different this time where we can round the edges of our bars.

CodePen Embed Fallback

Using one element and its ::before and ::after pseudos, we define three identical bars:

.loader {
–s: 100px; /* control the size */

display: grid;
place-items: center;
place-content: center;
margin: 0 calc(var(–s) / 2); /* 50px */
.loader::after {
content: “”;
grid-area: 1/1;
.loader::after {
height: var(–s);
width: calc(var(–s) / 5); /* 20px */
border-radius: var(–s);
transform: translate(calc(var(–_i, 0) * 200%));
.loader::before { –_i: -1; }
.loader::after { –_i: 1; }

That gives us three bars, this time without relying on a linear gradient:

Now the trick is to fill in those bars with a lovely gradient. To simulate a continuous gradient, we need to play with background properties. In the above figure, the green area defines the area covered by the loader. That area should be the size of the gradient and, if we do the math, it’s equal to multiplying both sides labeled S in the diagram, or background-size: var(–s) var(–s).

Since our elements are individually placed, we need to update the position of the gradient inside each one to make sure all of them overlap. This way, we’re simulating one continuous gradient even though it’s really three of them.

For the main element (placed at the center), the background needs to be at the center. We use the following:

.loader {
/* etc. */
background: linear-gradient() 50% / var(–s) var(–s);

For the pseudo-element on the left, we need the background on the left

.loader::before {
/* etc. */
background: linear-gradient() 0% / var(–s) var(–s);

And for the pseudo on the right, the background needs to be positioned to the right:

.loader::after {
background: linear-gradient() 100% / var(–s) var(–s);

Using the same CSS variable, –_i, that we used for the translate, we can write the code like this:

.loader {
–s: 100px; /* control the size */
–c: linear-gradient(/* etc. */); /* control the coloration */

display: grid;
place-items: center;
place-content: center;
content: “”;
grid-area: 1/1;
height: var(–s);
width: calc(var(–s) / 5);
border-radius: var(–s);
background: var(–c) calc(50% + var(–_i, 0) * 50%) / var(–s) var(–s);
transform: translate(calc(var(–_i, 0) * 200%));
.loader::before { –_i: -1; }
.loader::after { –_i: 1; }

Now, all we have to do is to animate the height and add some delays! Here are three examples where all that’s different are the colors and sizes:

CodePen Embed Fallback

Wrapping up

I hope so far you are feeling super encouraged by all the powers you have to make complex-looking loading animations. All we need is one element, either gradients or pseudos to draw the bars, then some keyframes to move things around. That’s the entire recipe for getting an endless number of possibilities, so go out and starting cooking up some neat stuff!

Until the next article, I will leave you with a funny collection of loaders where I am combining the dots and the bars!

CodePen Embed Fallback
CodePen Embed Fallback

Article series

Single Element Loaders: The SpinnerSingle Element Loaders: The DotsSingle Element Loaders: The Bars — you are hereSingle Element Loaders: Going 3D — coming July 1

Single Element Loaders: The Bars originally published on CSS-Tricks. You should get the newsletter.