by

Snippets: Debugging CSS

Reading Time: 3 minutes

I have a very handy, very small CSS Snippet that I use to debug CSS whenever the browser starts starts misbehaving. I figure I’d share with you, in case you, too, needed such a snippet.

The Outlining Snippet

Unlike border, the outline property does not and will never contribute to layout. Not only that, outlines aren’t necessarily rectangular. So what I do is keep a debug class whose job it is to draw outlines around it, and all of its children.

I find this helpful when I’m trying to figure out how big an element is.

/*For the element I'm debugging */
.isDebugging .debug {
  outline: 1px solid rgb(200, 100, 50); 
}

/*For all of that element's children*/
.isDebugging .debug * {
    outline: 1px solid rgb(200, 100, 50); 
}

The Backgrounding Snippet

This is my favorite snippet for seeing how many nested things are in a space. I set the background color using some opacity. As we get more nested elements, backgrounds become more opaque.

I find this helpful when I’m trying to figure out how elements are nested inside of each other.

.isDebugging .debug-bg {
  outline: 1px solid rgba(200, 100, 50, 0.9);
  background: rgba(200, 100, 50, 0.1); 
}

.isDebugging .debug-bg * {
    background: rgba(200, 100, 50, 0.1); 
}

Protect the CSS with some JS

To Err is human, to forgive [shipping to production] is divine

Shakespeare and Frank, Frankspeare if you will

I want to avoid my debugging CSS making it to production at all costs. So what I also keep around for my projects is some JavaScript that turns on debugging. Something that adds a class name to the body. This means that even if a Pull Request doesn’t catch my debug class sitting on an element, and even if our automated tests don’t spot it, it still can’t do any harm because I have to intentionally turn it on.

As a bonus, this means that if something does make it to production, I have the ability to insert this classname with a few inconspicuous keystrokes.

/**
 * @class Debug
 * @classdesc A small utility for debugging.
 *
 */
class Debug {
  constructor() {
    this.init();
  }

  /**
   * determines if debugging has been unlocked from sessionStorage
   * @type {boolean}
   */
  get isUnlocked() {
    const storageItem = sessionStorage.getItem('isDebugging');

    return storageItem === 'true';
  }

  /** logs an optionally styled message in the console
   * @method
   * @param  {string} message message to be sent to the console
   * @param  {string} [styles=''] CSS styles to be added to the message
   */
  static logMessage(message, styles = '') {
    console.log(`${styles && '%c'} ${message}`, styles || ' ');
  }

  /**
   * "unlocks" debugging by adding a classname and putting value in sessionStorage
   * @method
   * @static
   */
  static unlock() {
    document.body.classList.add('isDebugging');
    sessionStorage.setItem('isDebugging', 'true');
    Debug.logMessage('debugging unlocked');
  }

  /**
   * binds any events used by debugging
   * This includes event listener that checks for keystrokes
   * @method
   * @static
   */
  static bindEvents() {
    // up up down down left right left right b a
    const keys = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
    let keysIndex = 0;

    const keydownTracker = (event) => {
      const nextKey = keys[keysIndex++];
        
      if (event.keyCode === nextKey) {
        if (keysIndex === keys.length) {
          document.removeEventListener('keydown', keydownTracker);
          Debug.unlock();
        }
      }
    };

    document.body.addEventListener('keydown', keydownTracker);
  }

  /**
   * Initializes the module
   */
  init() {
    if (this.isUnlocked) {
      Debug.unlock();
    }
    Debug.logMessage('Debugger available', 'color: #ef8c23');
    Debug.bindEvents();
  }
};

You may notice that my debugger comes with its own logMessage. This is handy from the JavaScript side because it means I can make my debugging console statements obvious— and therefore easier to spot.

So, with all of this I can use my debugger withconst debugger = new Debug();

Try it out

Type ↑ ↑ ↓ ↓ ← → ← → b a anywhere on the page, and you’ll be able to debug this post.

This is also a gist complete with Sass mixin, if that’s your thing.