Here’s my favorite weird trick to debug CSS

Written by Zaydek Michels-Gualtieri.

Hi! 👋 I’m Zaydek! When I first set out to learn how to make websites, it was more far more painful than anticipated. After all, I’m an experienced programmer and graphic designer — how could websites be that hard?

In this article, I detail the process and decisions that led me to create a CSS debugger.

body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}

@jgthms This is really cool. I turned on my debugger for your website and it looks like this. It's just a few lines: https://t.co/9TUjTLge6p

 — @username_zaydek

What’s a debugger?

There’s a great Donald Knuth quote about debugging. To paraphrase, it goes something like this:

Young Donald Knuth sitting in front of an IBM 650

I didn’t come to appreciate this idea until CSS. Programming languages have this reasonableness about them, where logic exceeds opinion. But CSS is different because CSS “feels” opinionated.

So what can we do? Well, we can listen to the good advice of Donald Knuth and use a debugger!

Where a programming language is a tool, a debugger is tooling we can use to understand our tool — our code. Not all comp-sci folk like debuggers, and I understand this.

Don’t make the computer do what we don’t understand. I think there’s merit in this, but what I’m talking about here is revealing structure where it was otherwise invisible.

Take the following:

Click here to open in Scrimba’s playground

What can we do to see our website’s structure? Here are two solutions I’m aware of: we can make one-off CSS rules to emphasize an element, or we can use Chrome’s, Firefox’s, or Safari’s Debugger Tools. But that’s still more-or-less a one-off solution. What we need is a general solution.

Our debugger

Not long ago I was designing this header, and it wasn’t simple. The intent was to hover an image over multi-line text. Should be simple, right?

Well CSS is the antagonist here. What would otherwise be simple in Photoshop can be a hero’s journey in CSS, and this led me to experimenting with outline:

* { outline: solid 0.25rem hsla(210, 100%, 100%, 0.5); }
Click here to open in Scrimba’s playground

Nothing too special—just soft-white lines. What we do have, however, is a rule that applies to all elements as long as we use an * and not the name of the id, class, or element.

Yet the introduction of the * { … } was profound for me. I thought, “Where would I not want this?” So I added a few more lines and developed a more formal debugger:

* {
color: hsla(210, 100%, 100%, 0.9) !important;
background: hsla(210, 100%, 50%, 0.5) !important;
outline: solid 0.25rem hsla(210, 100%, 100%, 0.5) !important;
}
Click here to open in Scrimba’s playground

Much improved! Here we’ve created a schematic-like feel for our website. I was careful to not use solid colors, but instead chose soft-colors or colors with an alpha channel so that nested elements appear deeper in color, with bluer blues and whiter whites. I also added !important because of the infamous CSS Specificity Wars.

What can sometimes feel like CSS screwing with us is how and when the cascade applies. That is, “How is it that styles are sometimes applied and sometimes not?”

This isn’t Schrodinger's CSS, it’s simple math. CSS uses a simple calculator to determine which rules are more specific, and the result determines whether or not CSS is applied.

An implementation of CSS’s specificity calculator

The mother of all specificity is !important, which overrides all inline, IDs, classes, and element rules. It’s like the Death Star as compared to The Empire. Despite the fact that the use of !important is discouraged in general, it’s perfect for a debugger — because we won’t ship our website with it “turned on.” Instead, we use the debugger just in the design and development of our website.

The more I used the debugger, the more I realized that using *:not(path):noth(g) as the selector was preferred. This way, I wouldn’t get extraneous lines from vector graphics. I also noticed that disabling box-shadow was cleaner, as the debugger doesn’t need a sense of depth.

To use it, we can either click on and off the bookmark or we can link a standalone file:


<head>

<link rel="stylesheet" href="styles/reset.css">
<link rel="stylesheet" href="styles/debug.css">
<link rel="stylesheet" href="styles/style.css">

</head>

And here is the final debugger:

*:not(path):not(g) {
color: hsla(210, 100%, 100%, 0.9) !important;
background: hsla(210, 100%, 50%, 0.5) !important;
outline: solid 0.25rem hsla(210, 100%, 100%, 0.5) !important;
    box-shadow: none !important;
}
Click here to open in Scrimba’s playground

I think we humans hate what we don’t understand. And CSS is no exception. It’s mischaracterized because it’s misunderstood. I propose: think of CSS as a double-edged sword. It can be used to both construct and deconstruct websites. CSS is unlike Photoshop, but that doesn’t mean it can’t do things that Photoshop can’t. Creating our own debugger is one thing we can do.

How to use this debugger 🔍

  1. Go to zaydek.github.io/debug.css
  2. Bookmark “Debug CSS”
  3. Click the bookmark to toggle it *on* and *off* 💡

Want to support me? 😍 You can Buy Me A Coffee! *A personal note* I prefer Chai Tea ☕️ and Green Tea Lattes, 🍵 though.

Have a question, comment, or feedback? You can also reach out to me on Twitter; Tweet or DM me @username_zaydek. 🐦

I also taught a free HTML/CSS course on Scrimba where I teach how to build a beautiful blog from *scratch*. Click here to enroll! 👋


Here’s my favorite weird trick to debug CSS was originally published in freeCodeCamp on Medium.