#244: Vendoring and CSS

[Robin]: Someone emailed me the other day out of the blue and noticed an odd pattern: apparently whenever I write about just about anything design systems related or about front-end development, the conversation always comes back to my frustrations with Bootstrap. I’m constantly refactoring it, removing it, tidying it up.

So: why’s that?

Well, I think Bootstrap is an example of a remarkably good tool that’s often misused. And the reason why is because when folks start building an app they often think of CSS as something that’s annoying, something that shouldn’t be built from scratch so they turn to a library like Bootstrap. They don’t want to have to build a carousel or a button or an anything for the millionth time, they just want to copy and paste HTML and CSS together to make it work.

The problem with this is that if left untended, Bootstrap can become an example of radioactive code.

The last three projects I’ve worked on all started with Bootstrap to provide the foundations for things — they’d start by loading Bootstrap via a CDN in the head of the document:

<head>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
</head>

This is bad for a whole bunch of performance reasons so eventually folks would start using it as a dependency in node. They would npm install bootstrap and badda bing badda boom, you now have all the CSS you’ll ever need.

The problem here is that Bootstrap contains so much stuff that you don’t need 95% of it. You’ll need the reset, the normalize styles but the dozens and dozens of component styles you won’t need or ever use. They’ll just get in the way and slow you down.

But not only are you asking users to download data but it will make for a worse developer experience, too. That’s because folks on most teams will start to componentize their front-end code and instead of refactoring Bootstrap they’ll often choose to make a new component and then override the Bootstrap styles. This will happen until things get so messy that even though you might have a nifty <Button> React component, there might be eight different style sheets impacting that component from god knows where.

When a team starts using Bootstrap in this way it gets incredibly difficult to see the damage and point it back to this single point of failure. You’ll just start finding that it’s harder to write good front-end code. You’ll find tons of hacks lying around in your codebase and you’ll furrow your brow before continuing writing more code somewhere else.

Now, I don’t blame Bootstrap for this — I blame how Bootstrap is used.

The way we should use it is by taking only the pieces we need, specifically, the component styles. We shouldn’t npm install this stuff either. I think we need to vendor it.

What does “vendoring” code mean? Well, the other day I stumbled upon this term in a blog post by Tom MacWright:

Vendoring, in the programming sense, means “copying the source code of another project into your project.” It’s in contrast to the practice of using dependencies, which would be adding another project’s name to your package.json file and having npm or yarn download and link it up for you.

This is exactly how I think we should be using CSS framework-esque projects like Tachyons and Bootstrap: just go and copy/paste only the parts of that code that you need.

Whenever I join a team this is almost always the first thing I do when it comes to design systems. I vendor Bootstrap, copying and pasting and deleting only the stuff we need and moving all those global styles into React components so that they can be read and understood easily in the future.

Vendoring code in this way might sound gross but it’ll be easier to make changes in the future, easier to read, and oddly enough easier to update if that specific library changes, too.


Styling Psuedo Elements with JavaScript

Here’s a neat trick from Michelle Barker where she shows us how to style pseudo elements like :before or :after with JavaScript because today you can’t directly access a pseudo element like this:

document.querySelector('.my-element::after')

This would be nifty but sadly it just won’t work today. So, Michelle recommends that we turn to CSS variables to help us out here instead:

.my-element::after {
  height: var(--height, 0);
}

Now we can grab the CSS custom property --height with JavaScript and set it to whatever we want. And that’s a pretty smart workaround if you ask me. It’s similar to how you can’t use inline styles to do something like a :hover, but you can use custom properties as a workaround.


Weird things you can do with fonts

At this point in my career I thought I knew everything about fonts, but nope. Here’s something utterly genius: a recreation of the classic GameBoy Pokémon game which is stored and played from…a font file? Yep, you read that right: a game that’s playable from a font file.

As you type the game progresses, whether that’s on the web or whether you download the font file itself and start typing something out in Microsoft Word or in Illustrator. It’s remarkable and reminds me once again that fonts are very complex bits of software—they’re fully fledged apps, really. And once you start to think about fonts in that way I think it opens up a lot of thoroughly exciting doors.

Also, as a font nerd I found it particularly interesting reading about how the developer, Michael Milet, designed and built the game. There’s a ton of minute details to learn about arcane font formats but it’s super accessible to read.


AMP and Web Vitals

Ethan Marcotte wrote this interesting post about the relationship between AMP and Web Vitals. Ethan writes:

For all its many, many faults, the AMP Project does have an external advisory committee, which provides advice to Google in an attempt to “make AMP a great web citizen.” And while the shift to Core Web Vitals is a step in the right direction, it also means that Google alone determines what a “great page experience” means. They’ve set certain thresholds within the Web Vitals that your page is expected to meet. And those thresholds can then be changed by Google at any point.

I do love Core Web Vitals because they’re metrics that help me understand how users are experiencing the websites that I build, but it’s hard to argue with Ethan’s point here: they’re defined and entirely owned by Google.


React State Management Libraries and How to Choose

Dave Cedia wrote this great piece about React State Management Libraries and walks through all the different ways to do that alongside all the ways we probably shouldn’t:

All of those variables that decide what state your app is in have to be stored somewhere. So state management is a broad term that combines how you store the state and how you change it.

React and its ecosystem offer lots of different ways to store and manage that state. And when I say lots I mean LOTS.

Performance gotchas, common pitfalls, and the benefits of using this one library over the other. It’s a handy post and reminds me that state management is a complex subject with tons of nuance.



Web Directions Hover, The Conference CSS Deserves

Hover is the conference CSS deserves, covering the most recent developments, and key aspects of our favorite language in a depth you won’t find anywhere else. Online, and global, taking place April 23 & 30 in a range of time zones — CSS-Tricks readers get 30% off with the code csstricks.


[Chris]: Josh Comeau writes:

As JavaScript developers, the sheer amount of stuff we’re expected to know is enormous, and it grows bigger every day.

In my opinion, if we really want to maximize the return on our investment, one of the best things we can focus on is CSS.

That’s a cool way of putting it. Just the other day I accidentally used a bunch of JavaScript to do a thing that CSS can do much more easily and better. Thank god a co-worker helped me come to my senses. If you learn HTML & CSS deeply, that will likely happen pretty often. You’ll reach for tools that do the job easier and better rather than reaching for JavaScript all the time. You know what they say, when the only tool you have is JavaScript, everything looks like a package.