📝 CSS-Tricks 239: New CSS Tricks and Design Engineers

View this newsletter on the web.

First up this week, Andy Bell wrote this fantastic piece where he dives into a ton of new CSS features that we can use today:

CSS is great and getting better all the time. Over recent years, especially, it has evolved really fast, too. Understandably, some of the really handy powers CSS gives you might have slipped you by because of this, so in this article, I’m going to show you some really handy stuff you can do with modern CSS today, and also share some stuff that we can look forward to in the future.

This is a shocking post to me because there’s just so much stuff that’s been going on in the world of CSS. Here’s a quick list of new-ish features from Andy’s post (I’ve added links that dive into each of these features if you’d like more info):

That’s a lot of new features to keep up with. Most of these I have a pretty good handle on, I think, although I’m probably unaware of the coolest tricks we can pull off with min, max, and clamp. The main thing I was unaware of here was the ex unit, which Andy describes like this:

The ex unit is equal to the height of the lowercase x character — also known as the “x-height” in more traditional typography. This is really useful for working accurately and responsively with the vertical axis of your typography. One really handy use case for this is making an SVG icon the same height as your text.

All of these new abilities that have been added to the CSS language over the past year or so feel like small but important improvements. The way I tend to think of CSS is a language with these big gaps in some places—for example, layout was one of those enormous gaps until CSS Grid shipped and filled it in.

What does the future of CSS look like and where are those gaps today? Well, I think CSS needs container queries but it looks like the hard work of folks like Miriam Suzanne is starting to pay off there; container queries are on the horizon, and I think they’ll change my job as a front-end developer more than any other thing in the next couple of years.

📝 CSS-Tricks 238: Responsible Web Applications

View this newsletter on the web.

Changing list bullet styles

Yep, you can do that now without hacks or employing the somewhat awkward combination pseudo-elements and counters. Your best bet? The ::marker pseudo-element. We just updated the Almanac entry on that for your reference pleasure.

ul li::marker { font-size: 150%; font-weight: bold; color: lightgreen; }

You can also control the text of the marker itself, meaning you can swap out bullets for emoji, or numbers for custom counters. Manuel Matuzović made note of this week that it was just a few years ago this was much more difficult. Go CSS!

Support is pretty darn good and it’s been around for a little while but I always tend to forget about :marker so this is a good reminder to use it more often.

📝 CSS-Tricks 237: The Dreaded Homepage Redesign

View this newsletter on the web.

[Robin]: Designing the homepage of a website is harder than learning a new framework, more difficult than building an enormous website, and more challenging than memorizing all the values and properties of CSS. In short, the absolute worst thing about the entire field of web development is designing the homepage. It’s just the worst.

Why? Well, introductions are hard. If you’re a front-end engineer then you probably want to lead with that and maybe where you’re from. But everyone’s website has that stuff! And they all sound relatively the same:

My name’s X and I’m from Y. I like front-end development, interesting activity Z, and coffee.

I’m not trying to make fun of anyone here—my own website is like this, too. I’m simply underlining how difficult this process is. How do we introduce ourselves? How do explain who we are and what we do without sounding like an absolutely unbearable jerk? How do we make our websites unlike anyone else’s and give a brief peek into who we are and what makes us tick?

My advice (to myself) is this: show me what you care about! That sounds kinda dumb and obvious but I’ve found it to be extremely tricky. Looking at examples can help us though.

I’ve mentioned Cassie’s website multiple times because I think it captures her personality and focus extremely well:

You can tell right off the bat that Cassie cares a lot about SVG and animation. You can tell that she likes the nitty-gritty details of web design and UI development and by the writing you can see that she doesn’t take herself too seriously.

Another example I love is Sarah’s website where she kinda kicks in the door right away and doesn’t faff about:

I like how bold and exciting this is, and it certainly doesn’t feel like I’ve seen a website like this before. I guess that’s what’s exciting about it to me; having to scroll down a bit to see who this person is, and not being told right away.

Another homepage that springs to mind is Michelle Barker’s CSS in Real Life where she writes about front-end topics. I like this one because it’s not about fancy animations or beautiful illustrations but because of that color, that luminescent pink that hops off the page and just sticks in my mind.

A lot of sites are pretty forgettable and the choice of using a

Alternatively, I like the story-based approach of Danielle Baskin’s website that shows everything that she’s been working on lately. The sheer amount of white space is also pretty great and gives you plenty of breathing room to enjoy those lovely typefaces:

These sites are inspiring and worth checking out not because we should copy them though, I just want to make that super clear. Instead we need to ask that super annoying question again: what do I care about? And then, harder still: how do I show folks that I care about that?

I could say “I like typography” in a paragraph but how do we show folks that without necessarily telling them? Probably: beautiful fonts, an interesting layout, attention to small typographic details.

So as I’m designing the homepage of my website I think that I need to take my own advice here. Earlier this weekend I popped open Figma and each time I started to riff on a new idea I would make a new frame and copy my previous design, just like this:

These are all different designs of the same page, with big grey blocks signifying images or UI elements that I don’t need to draw right now. I can’t quite remember when I learned this design “hack” but it’s great because after 30 minutes of trying different ideas you can quickly see how you got to where you are now. (In the past I would constantly move UI elements around the page and often retry things that I’d experimented with a dozen times before—this is a time saver).

All this homepage design work is scary and annoying but also fun at the same time. At least, once you realize that you can be smart about how you show yourself off, you can begin to play with typography and animation and layout. You can begin to think about all the CSS properties and weird things you can experiment with. You can begin to make something magic.

Wait, I have to go build the thing now? Wow, sorry dad.

📝 CSS-Tricks 236: Initialisms and Layout Shifts

View this newsletter on the web.

[Robin]: “Unnecessary initialisms are exclusionary” writes Jeremy Keith in this particularly excellent blog post about performance, web design, and how initials for terms such as CLS make thing much more difficult for everyone to understand:

I feel sorry for anyone trying to get into the field of web performance. Not only are there complex browser behaviours to understand, there’s also a veritable alphabet soup of initialisms to memorise. Here’s a really good post on web performance by Harry, but notice how the initialisms multiply like tribbles as the post progresses until we’re talking about using CWV metrics like LCP, FID, and CLS—alongside TTFB and SI—to look at PLPs, PDPs, and SRPs. And fair play to Harry; he expands each initialism the first time he introduces it.

But are we really saving any time by saying FID instead of first input delay? I suspect that the only reason why the word “cumulative” precedes “layout shift” is just to make it into the three-letter initialism CLS.

I think initialisms make things easier for the writer to type out but makes things way more difficult for readers. And I hadn’t really thought about this until the other day when I tried to remember what the Core Web Vital CLS and FID stood for. And yet I’ve probably read somewhere in the region of ten billion blog posts about this stuff.

Cumulative Layout Shift and First Input Delay. Ugh.

Lately I’ve also noticed how UIs are starting to throw these web perf metrics around the place with initialisms alone and with no further explanation. This is sort of funny since ideally the whole point of web performance is all about access—making sure that everyone can view a website without having to jump through unnecessary hurdles.

This isn’t just about performance though; initialisms creep into our work from all sorts of directions. And I think that, like Jeremy, from here on out I’m going to be a bit of a jerk about things and push folks to stop speaking in riddles. Because if we really care about performance and making sure the web is for everyone then we need to ensure the words we use to describe our work aren’t masked in complexity, too.

<End of Rant />

📝 CSS-Tricks 235: Animations, Animations, Animations!

View this newsletter on the web.

Robin: This week I’ve been thinking a lot about Framer Motion. It’s a library designed to make beautiful and complex animations on the web much easier than they would be otherwise. It’s also worth taking a look at the website because, just gosh darn, it is beautiful.

I haven’t built anything with it yet but some of my pals at Sentry have been redesigning our onboarding flows and they used Framer Motion to create some absolutely drop-dead gorgeous animations when combined with our ever-so-lovely illustrations. In fact, all this almost makes me mad because of how good it is.

A few elements appear when the page loads, while the top and bottom sections snap in from the sides. Once that’s done, the light in the corner begins to swing from side to side and then, once you click the button, everything flies up and away. On the next page, the title swishes into view and the text beneath it clicks up satisfyingly.

There’s so much going on with these animations and yet somehow it isn’t annoying at all. To me, these animations makes it feel as if I can trust Sentry— if folks are willing to spend time on the tiny details like this then I’m more likely to trust them with the product, too. Anyway, I didn’t work on this project at all but I was fascinated by how the team built this thing. Evan Purkhiser, the engineer at Sentry that built it, walked me through why he decided to use Framer Motion in the first place and what made it so helpful.

Chris did a video on Framer Motion with creator Matt Perry a while back.

Evan first pointed to the fact that it’s extremely difficult to tie animations together with CSS alone. A lot of the time when we trigger an animation we want another completely unrelated thing to fire at the same time. With CSS all we have are keyframe animations.

First you define the animation:

@keyframes pop { 0% { transform: scale(0); } 100% { transform: scale(1) } }

Then you apply it to an element:

.element { animation: pop 1s ease infinite forwards; }

This covers a lot of animation use cases (and we even have a mini guide just about animations that goes into a lot more detail). But! What if we want to make another element start an animation once this one ends? Well, that’s where things get a bit bonkers in CSS — we’d have to add animation-delay all over the place and that becomes unmaintainable (although… you might wanna take a look at Mads Stoumann’s ideas with CSS custom properties and animations, which might open some doors here).

The magical thing about Framer Motion is that it’s relatively easy to make one animation begin when another one ends. Not only that, but you can control the animations of child elements and how they stagger via the parent element. This is something that’s just impossible with CSS today.

Here’s how you create a Framer Motion component. Let’s say you have a component in /components/Card.js that looks like this:

import { motion } from "framer-motion"; export default function Card() { return ( <motion.div animate={{ scale: 1.1 }}> This is a card </motion.div> ); }

See that <motion.div> bit? That’s how you tell Framer Motion that this is an animatable element and also what HTML element you want to render. It looks weird, but you get used to it after a while. Also, that animate prop attached to it tells the Motion component to immediately scale by 1.1. But we could make it do that on hover or on tap instead:

export default function Card() { return ( <motion.div whileHover={{ scale: 1.1 }}> This is a card </motion.div> ); }

I really like this syntax and it reminds me somewhat of Vue’s attributes. But anyway, I’m going to keep experimenting with Framer Motion and write a more in-depth post about how to get started, as well as how to tie different animated child elements together because that’s where the real magic lies.