🔖 Vandalize the web with Bookmarklets
- Published on
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,
- Write some javascript code
- Put
javascript:
in front of the code - 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.
- 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)
})()
- 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)
})()
- Find Missing Alt Attributes: Using
img
without analt
attribute is annoying for people who use screen readers. This bookmarklet lets you find suchimg
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)
})()
- 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!.