An Idiosyncratic Blog

🔖 Vandalize the web with Bookmarklets

Published on
·
9 minutes read

Let’s say you want to vandalize a website that you don't own. You want to read The Wall Street Journal in Comic Sans, or you want to highlight the last letter of every paragraph in this post to see if there’s some secret message (spoiler alert: there isn't any). Or perhaps you want to do something useful with the web page like highlight a11y issues.

One way to do this is open the DOM inspector in the browser developer tools and fiddle around. But if we want to share it on the internet, we need to build and ship a tool which does that. Browser Extensions are the de-facto way to do this.

Instead of paying $5 to Google to publish an extension, let's see how we can create a Bookmarklet.

Why?

Why would one use Bookmarklet over Browser extensions? Fair question, here are some reasons:

  • They are universal, i.e. they usually work on any browser and whatever the platform, mobile or desktop.
  • They are managed as any bookmarks so can be easily exported and imported between browsers and teams.
  • There isn't any need to create and submit Bookmarklet to any extension store.

Creating Bookmarklet

Creating a Bookmarklet is as simple as,

  1. Write some javascript code
  2. Put javascript: in front of the code
  3. Wrap everything in an IIFE so the page doesn't freak out
javascript: (function () {
  document.body.style.background = 'blue'
})()

Use the browser console to debug your code before saving it as a Bookmarklet.

Substitutions

This one replaces text on a web page. For instance, to replace hello with hi we can write:

javascript: (function () {
  function replace(element, from, to) {
    if (element.childNodes.length) {
      element.childNodes.forEach((child) => replace(child, from, to))
    } else {
      const cont = element.textContent
      if (cont) element.textContent = cont.replace(from, to)
    }
  }

  replace(document.body, new RegExp('bookmarklet', 'g'), 'awesome')
})()

Custom Search Engine

Most search service URLs have a constant path with a variable query parameter. We can use that to run search queries against selected text in the current window.

javascript: (function () {
  window.location = 'http://www.google.com/search?q=' + window.getSelection()
})

Just replace window.location with your search service. Here are some examples:

  • Google: https://www.google.com/search?q=
  • Stack Overflow: https://stackoverflow.com/search?q=
  • Reddit: https://www.reddit.com/search/?q=

Clear Site Data

There are times when I need to clear site data like cookies, local storage, session storage etc. Using this bookmarklet, it is a one click thing.

javascript: (function () {
  localStorage.clear()
  sessionStorage.clear()
  var c = document.cookie.split('; ')
  for (i in c) {
    document.cookie = /^[^=]+/.exec(c[i])[0] + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT'
  }
})()

Highlight Elements on Page

When debugging layouts, it's extremely useful to be able to see layout bounds to check if the layouts are aligned to the exact pixel or not.

There are extensions like VisBug which makes this simpler, but when there are times when it's easier to use a Bookmarklet instead.

javascript: (function () {
  let style = document.createElement('style')
  document.head.appendChild(style)
  let sheet = style.sheet
  sheet.insertRule('* { outline: 1px dotted red !important; }', 0)
})()

You can add div instead of * at * { outline: 1px dotted red !important; } to highlight only the div tags. Or add different borders for different tags. The combinations are endless.

I use outline here instead of border because border is a property of the box-model and tends to mess around layout sizing.

a11y

I've got a bunch of these to enable and test accessibility across sites I develop and sites I use.

  1. Restore Underline Links: There are sites which remove link underlines and replace them with terrible color contrasting links. This bookmarklet restores the underline across the site.
javascript: (function () {
  let style = document.createElement('style')
  document.head.appendChild(style)
  let sheet = style.sheet
  sheet.insertRule('a[href] { text-decoration:underline !important }', 0)
})()
  1. Restore focus outline: Same as above, when sites tend to remove focus outlines, this bookmarklet brings it back.
javascript: (function () {
  let style = document.createElement('style')
  document.head.appendChild(style)
  let sheet = style.sheet
  sheet.insertRule('*:focus{outline:1px dotted red !important;}', 0)
})()
  1. Find Missing Alt Attributes: Using img without an alt attribute is annoying for people who use screen readers. This bookmarklet lets you find such img tag, so you can identify and fix them.
javascript: (function () {
  let style = document.createElement('style')
  document.head.appendChild(style)
  let sheet = style.sheet
  sheet.insertRule('img:not([alt]){outline:2px dotted red !important;}', 0)
})()
  1. aria label: This bookmarklet, courtesy of, helps to validate aria-labels.
javascript: (function () {
  let styles =
      '[aria-label]{background:yellow}[aria-label]:before{content:attr(aria-label);color:red;font-weight:bold}[aria-labelledby]{background:pink}[aria-labelledby]:before{content:attr(aria-labelledby);color:green;font-weight:bold}',
    element = document.getElementById('a11y-css-highlight')
  if (element) {
    element.disabled = !element.disabled
  } else {
    element = document.createElement('style')
    element.id = 'a11y-css-highlight'
    element.type = 'text/css'
    if (element.styleSheet) {
      element.styleSheet.cssText = styles
    } else {
      element.appendChild(document.createTextNode(styles))
    }
    document.getElementsByTagName('head')[0].appendChild(element)
  }
})()

I'd recommend looking at a11y.css to generate CSS to highlight different a11y issues.

Zap Styles

Sometimes you just cannot deal with CSS styles of a site. This handy bookmarklet removes all the styles from a page.

javascript: (function () {
  var i, x
  for (i = 0; (x = document.styleSheets[i]); ++i) x.disabled = true
})()

Display list of tags and class names

This is a handy script, courtesy of, to display class names, and their count along with the tags where each classname is applied.

javascript: (function () {
  var anchor = {},
    classes = [],
    i,
    element,
    elementClass,
    k,
    doc,
    result = '<table border=1><thead><tr><th>#</th><th>Tag</th><th>className</th></tr></thead>'
  for (i = 0; (element = document.getElementsByTagName('*')[i]); ++i)
    if ((elementClass = element.className)) {
      k = element.tagName + '.' + elementClass
      anchor[k] = anchor[k] ? anchor[k] + 1 : 1
    }
  for (k in anchor) classes.push([k, anchor[k]])
  classes.sort()
  for (i in classes)
    result +=
      '<tr><td>' +
      classes[i][1] +
      '</td><td>' +
      classes[i][0].split('.').join('</td><td>') +
      '</td></tr>'
  result += '</table>'
  doc = open().document
  doc.write(result)
  doc.close()
})()

Travel in Time

This one opens the current webpage in Web Archive

javascript: (function () {
  const baseUrl = 'https://web.archive.org/web/*/'
  window.location.href = baseUrl + document.URL
})()

To make writing of JavaScript for a bookmarklet easier, I've created a bare-bones bookmarklet generator that helps create a bookmarklet which can be saved as a bookmark. Check it out here!.