#248: Unlearning CSS

[Robin]: Imagine you could jump into the future — let’s say ten years — and watch how you write CSS. What would that look like? How much of the language do you expect will change over that period of time? How weird would the language now be?

I’ve been asking myself that question a lot this week, and it all started when I spotted a now-deleted tweet from Craig Mod where he asked why CSS Grid feels so unintuitive. “It gets much easier over time” I replied, “since it kinda requires you unlearn CSS to get to grips with it.” That sounds like a really pretentious answer to a straightforward question but I think it’s an honest one.

What does unlearning CSS mean though? And how does that apply to Craig’s frustration with CSS Grid being weird?

Well, if you’re used to the old model, and you came across some CSS Grid code using named areas, that might look mighty confusing.

.container {
  display: grid;
  grid-template-areas: 
    "a a a"
    "b c c"
    "b c c";
}

What the what? What does this have to do with floats and clearfixes? What does this have to do with absolute positioning? Where are the negative margin hacks?

Well, sorry about that, but CSS now has an extremely flexible system of coordinates that you can now pinpoint with expert precision. It doesn’t map to the old mental model at all. But! If you’re new to CSS then the code above makes a lot more sense. You have an element, you create a grid, then you literally draw where you want those columns and rows to go. You can see how the interface will look, just from a glance at the code.

It might be that the only reason the above code looks unintuitive is that your intuition is bogged down with the history of micro-clearfixes and table layouts and other hacks from a bygone era. And the reason why I mention this is because it shows CSS is a language unlike any other on the web: it requires you to unlearn when things change.

For example: HTML is mostly additive. Every once in a while new tags get added to the existing bunch but you don’t have to rethink things. For the past decade HTML has remained mostly the same and I think for the next decade HTML will look pretty much identical. That’s a feature though, not a bug.

JavaScript has frameworks and new jQuery-esque syntaxes, sure. There’s node and npm dependencies. But if you learn the basic tenets of how JavaScript-the-language functions then those are all additive tools and skills that can be tacked on. You don’t have to go back and throw all that knowledge away to create a React app.

But CSS is a much more complex system because it does, from time to time, require that you unlearn what you know. Think about how we wrote CSS ten years: no grid, no variables, no filters, no libraries like emotion. It was a wildly different language and community back then and the language solved a different set of problems than those it does today.

Now, with container queries on the horizon, things are bound to look pretty different just within the next year or so.

My point here is that CSS is a language unlike any other because to unlock its true power, every couple of years you must unlearn it. You have to sit down at your keyboard and try to think like a beginner, like someone who has never seen CSS before.

With that said, I don’t think that in a decade CSS will look entirely foreign to us but I do think that the way all its properties interact with one another will be novel and weird as heck. And I’m saying this knowing that the basics of web design will always be the same: accessibility, performance, great typography, etc. are the kind of skills that will be needed forever.

But this specific way we do this one thing with CSS is likely to change. That’s why you have to unlearn it, and that’s what makes CSS so dang exciting to me.


Eliminating five top compatibility pain points on the web

Robert Nyman and Philip Jägenstedt from Google announced a new initiative where browser makers are going to work together to tackle some compatibility problems on the web and make things more consistent and reliable:

The goal in 2021 is to eliminate browser compatibility problems in five key focus areas so developers can confidently build on them as reliable foundations. This effort is called #Compat2021.

It’s really interesting reading this post because there’s a lot of cross-browser weirdnesses and it’s easy to forget them all. For now though, the team is focusing on problems with Flexbox, Grid, position: sticky, aspect-ratio and CSS transforms. Huzzah!

Chris also wrote what he’d like to see added to that list:

Ten, fifteen years ago, the job of a web designer and developer was heavily thinking about, planning for, and dealing with cross-browser compatibility. These days, it’s still a thing, but it’s not about dealing with bugs, quirks, and frustrating implementation differences like it was then. It’s more edge-case stuff with more obvious work-arounds. And when we’re thinking about the browser and device landscape, we’re doing it through the lens of meeting our users where they are and embracing that landscape. Doing our best, anyway.

[…] I vote for some kind of proper stab at reliable viewport units in 2022, that somehow sensibly handle scrollbars and other browser chrome.

Hear, hear. I bump into problems with viewport units constantly and it would certainly make things easier if they worked more predictably across browsers. For me, I’m extremely excited about fixing the inconsistencies with position: sticky, particularly when it comes to how they interact with tables which has long been a ugh! moment for me.


HTML Boilerplate

Manuel Matuzovic walks through his HTML Boilerplate and explains all the little details that you might never have noticed if you’re like me and just go ahead and copy the code from HTML5 Boilerplate before any new project.

There’s lots of interesting details in this post, like this one note where Manuel argues that you need to have…

<meta charset="UTF-8">

…declared before the <title> element if you want to ensure that it gets rendered correctly by all browsers. Another interesting point from all this is that Manuel detects if a browser supports JavaScript by checking for modules, like this:

<script type="module">
  document.documentElement.classList.remove('no-js');
  document.documentElement.classList.add('js');
</script>

Manuel writes:

I’m cutting the mustard at JS module support. If a browser supports JavaScript modules, it means that it’s a browser that supports modern JavaScript, such as modules, ES 6 syntax, fetch, etc. I ship most JS only to these browsers and I use the js class in CSS, if the styling of a component is different, when JS is active.


Awesome Standalones

I’ve never understood web components. Why are they useful? How do I use them? I know there’s a one or two great tutorials out there but for the longest time I couldn’t quite figure out what day-to-day problem of mine they solved.

That was until I found Dave Rupert’s collection of web components called Awesome Standalones. It shows the power of web components: you don’t have to recreate a component like tabs or something for the fiftieth time. You don’t have to search for how Bootstrap does X or Y. Instead, you could use these web components because they’re like tiny pieces that are un-themed and designed to fit into a larger design system.

Take this <dark-mode-toggle> for instance:

A custom element that allows you to easily put a Dark Mode 🌒 toggle or switch on your site, so you can initially adhere to your users’ preferences according to prefers-color-scheme, but also allow them to (optionally permanently) override their system setting for just your site.

This is so nifty. Better yet, check out this <clipboard-copy-element>.


3D Kitchen

I spotted this extremely fun and cute 3D kitchen made by Ricardo Oliva Alonso where you can drag it around and see every corner of the building:

Ricardo has made a number of these 3D rooms in the past, like this dark living room that’s made with pure CSS:

And then there’s this likewise lovely modernist house that’s also made with nothing but CSS:

Now this isn’t something you could’ve done a decade ago with CSS alone. It reminds me of Jhey Tompkins’ work, like this post where he sets scenes with CSS by thinking in “cubes” instead of boxes.


A Decade of Jetpack!

Jetpack is celebrating 10 years! Jetpack does a lot, from major search improvements, full site backup, social media integration, speed boosts, and security measures. And in the past 10 years, it’s blocked more than 122 billion malicious login attempts, tracked more than 1.6 trillion page views, and served more than 24 trillion images via (it’s free!) Jetpack CDN. Check out the birthday site they put together for an interactive exploration of how Jetpack has helped WordPress sites over the years.


Fauna

The serverless Jamstack database with built-in GraphQL. Fauna is a flexible, developer-friendly, database delivered to you as a secure, cloud API with native support for GraphQL.


[Chris]: There was peak-jQuery.

I’m well aware that jQuery is still quite dominant in how much usage it has on the web, but we’re past peak jQuery. There aren’t dedicated conferences anymore. There aren’t hot new jQuery plugins anymore. If anything, when you hear about jQuery, it’s how some site is phasing it out.

The plugin phenomenon in the jQuery ecosystem was wild. There wasn’t all that much that made a jQuery plugin a jQuery plugin, aside from the fact that the plugin also happened to use jQuery. So then the plugin would lean into the jQuery syntax. It was often expected that you would select some parent element jQuery style then call the plugin which registered itself on $.fn. So you could offer a syntax like $("#slider").anythingSlider() which would likely take an object of options.

I was in on the fun. The anythingSlider was a real thing and decently popular for a minute. I remember how pumped I was when the homepage for the restaurant chain Pei Wei used it. Funnily enough, they still use jQuery, they just use Owl Carousel now.

Our appetite for neat plugins isn’t gone, we just don’t make them in jQuery anymore, we make them in React (as an industry-wide trend, I think it’s fair to say). My guess is that we’re in peak-React right now. And the plugins are just as satisfying as ever.

Take react-beautiful-dnd, which I find to be a very nice React plugin. Well wait, we don’t really call them plugins anymore, they are just packages, if we name them at all, or maybe libraries unto themselves. In the React parlance, we’d use it like this…

<DragDropContext onDragEnd={() => doThings()}>
   <Droppable>
      <Draggable />
      <Draggable />
   </Droppable>
</DragDropContext>

That is this package offering an API that hopefully matches a mental model of constructing a UI of things you can drag around, while supporting lots of use cases. I admit I like that authoring syntax, but it’s not thousands of miles away from how a jQuery plugin might have done it.

Hypothetically, a jQuery plugin would have expressed that like…

$("#drop-drop-context").dragAndDrop({
  droppableAreas: ".droppable",
  draggableAreas: ".draggle",
  
  onDragEnd: function(e) {
    doThings(e);
  }
});

There is a point to be made here about imperative vs declarative programming. I’m not sure I’m smart enough to make it, but anecdotally, I’d say I find the React/JSX-y way of programming this kind of interactivity less buggy and error prone, if only a little. Of course, there are other tradeoffs at work here, like the fact that React doesn’t exactly encourage server-side rendering and all that (fortunately it’s not react-beautiful-dnd that prevents that, as it is SSR-compatible).

I’ve used react-beautiful-dnd lately and I’ve found it, dare I say, rather delightful to work with. It’s no wonder to me that so many devs feel empowered by modern JavaScript frameworks like React and how they can build powerful, feature-rich front ends leveraging stuff like this. Just in the past few weeks, I’ve come across packages that have that same peak-jQuery feel to me…

  • React Hot Toast classy popup messages via <Toaster />
  • React Flow classy box diagrams via <ReactFlow />
  • React Slider a range input with more styleability and functionality than the HTML one via <ReactSlider />

And yet, the web is just the web, even a React site. A JavaScript plugin like Flickity is powered by vanilla JavaScript. As much as I like framework-specific ergonomics sometimes, I’d be tempted to choose an agnostic library like Flickity as much as possible for longevity reasons. It’s a tough call though sometimes. Like certainly you can build a 3D 10-sided die without any frameworks, but in the end, using three.js and React makes it so much more fun and productive to work with.