CSS Bookmarklets for Testing and Fixing
I regularly have to test sites in development, review some third-party site, or just use a site in my day-to-day time wasting (and banking) rituals. I’ve relied on viewing the page’s source or popping into my browser’s dev tools to find a missing element, copy un-transformed text, check for inline styles, and so on. Typically I am relying on CSS and not JavaScript, as that is where I excel.
I got a little annoyed doing that all the time, and this morning I had reason to visit Pinterest and mostly lost my marbles at its login overlay and refusal to scroll. So I channeled that rage and taught myself to build a bookmarklet to dump that Pinterest overlay crap. I have created a few more that include my standard styles for testing, styles that perhaps you (dear reader) will find useful.
I’ll have basic instructions below showing you how you can build your own and/or modify the ones I’ve provided.
Note your browser’s Content Security Policy may prevent the script in a bookmarklet from modifying a page, in which case you can run it in the browser console. In Firefox use Ctrl + Shift + K, In Chrome use Ctrl + Shift + J.
Bookmarklets You May Steal
Note that I say may steal. That’s me giving you permission. Note that I call them bookmarklets. That’s me not giving into the term favelets or whatever HotJava called them (was it hot links?).
- Restore Link Underlines
- Restore Focus Outlines
- Find Inline Styles
- Find Duplicate ARIA Roles
- Find Missing Alt Attributes
- Fix Pinterest
- Reset Text Size (added January 30, 2015)
- Find Empty Elements (added May 6, 2015)
- Invert Page (added August 17, 2015, updated December 8, 2016)
- Link Underlines for Stack Overflow Questions and Answers (added June 17, 2016)
Show Twitter Image Alt Text(Added January 3, 2017)- Fix LinkedIn Profile (Added August 15, 2017)
- Focus Interactive Controls (Added July 11, 2018)
- Reading Order (Added April 13, 2019)
- Show Tweet Image Alt Text (Added August 23, 2019)
- Fix GitHub Tables (Added January 20, 2020)
- Dismissable 44×44 Cursor (Added August 26, 2020)
- Unset Font Weights (Added January 28, 2022)
- Re-enable Text Selection (Added March 25, 2022)
- Fix Twitter Homoglyphs (Added April 3, 2023)
- Fix Disability:IN 2024 Agenda (Added July 2, 2024)
- Restore Controls to HTML Video Players (Added July 3, 2024)
Restore Link Underlines
You know what’s cool? Removing link underlines and providing terrible link color contrast. It’s so cool, in fact, that I want to make those sites less cool. As well as usable. Read my rant on this.
This bookmarklet restores link underlines across the board. Every link. After all, if you want the link underlines, you probably don’t care that the designer would freak out at the noise it adds to the page.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('a[href]{text-decoration:underline !important}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Link Underlines
Restore Focus Outlines (or Fix Virgin America)
Just as cool as removing link underlines is removing the outline on elements that get focus as you tab through a page. After all, if you’ve hidden the links, why not hide when the links are selected. Virgin America tends to agree.
This bookmarklet not only restores the outline (in the form of the two-pixel dotted blue line), but also adds a drop shadow for those cases where the blue is lost against the surrounding colors.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('*:focus{outline:2px dotted #00f !important;box-shadow: 0 0 2em rgba(0,0,0,.75) !important;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Focus Outlines
Find Inline Styles
Over at Algonquin Studios we have worked in the content management space for, well, since the dawn of content management systems. One of the risks of using a CMS is that your authors may accidentally (or intentionally) embed styles whether by pasting rich-text from elsewhere or by features built into the WYSIWYG editor within the tool. This is most common with text styles.
Sometimes it is faster to just find the elements that have a style
attribute on them, as that’s the first clue that there may be a conflict that needs to be corrected. This option will find any of those elements and give them a yellow background along with a two-pixel dotted red border (like the Windows “hot dog” theme from the previous century).
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('*[style]{border:2px dotted #f00 !important;background-color:#ff0 !important;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Inline Styles
Find Duplicate ARIA Roles
In ARIA, there are a few instances of roles that should only appear once on a page. These landmark roles are banner
, contentinfo
, and main
. In addition, the W3C HTML5.1 specification notes that there must be only one main
element per page.
This bookmarklet will identify any additional instances of any of the once-per-page items above. If you know enough about coding ARIA, then you probably know enough about finding which of the roles/elements is on repeat. Offending items will have a two-pixel dotted red border and red background.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('*[role=main]:nth-of-type(n+2),*[role=banner]:nth-of-type(n+2),*[role=contentinfo]:nth-of-type(n+2),main:nth-of-type(n+2){border:2px dotted #f00 !important;background-color:#f00;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Duplicate ARIA
Find Missing Alt Attributes
An image without an alt
attribute can be anything from an annoyance to a barrier to those using assistive technologies. Being able to quickly identify those images on a page can save time when figuring where to focus your efforts.
This bookmarklet will find those images and give them a two-pixel dotted red border. Note that it only looks for images with a missing alt
, as a blank alt
attribute is often perfectly valid.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('img:not([alt]){border:2px dotted #f00 !important;background-color:#f00;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Missing @alt
Fix Pinterest
When you visit Pinterest without a Pinterest account, or without being logged in, you are prompted to sign up/in by a terrible overlay. In addition, the page won’t scroll past a certain point. This annoys me. So I made a bookmarklet to remove the two overlays and re-enable scrolling. You can test it on my abandoned Pinterest page.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('.Modal, .UnauthBanner {display: none !important;}',0);b.insertRule('.hasFooter.Grid.Module{overflow-y:visible !important;}',0);b.insertRule('.noScroll{overflow:auto !important;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Fix Pinterest
Reset Text Size (Added January 30)
Sadly, it is not uncommon for sites to reset the default size of the text on the page. Too often that is done to satisfy a design change. One site where I find the text too small to read comfortably, or at all, is Daring Fireball. I know I am not the only one to feel this way.
This bookmarklet will resize the text on the body
element to 100%, ideally conforming to whatever your default browser preferences are. It works great on Daring Fireball, but could easily be overridden on sites that set the text size in other ways and/or on other elements.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('body{font-size:100% !important;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Reset Text Size
Find Empty Elements (Added May 6)
It is not uncommon for a WYSIWYG editor in a CMS or on a comment site to throw extra empty p
elements into the content. While I once wrote a style into my development CSS to highlight these issues, I was reminded of the potential utility by a Happy Cog post on pseudo classes.
This bookmarklet will find elements that are empty — no content, no whitepsace. It will not highlight images (by excluding elements with a src
attribute) nor form inputs (by excluding elements with a type
element), two common self-terminating elements that will otherwise trigger this. It isn’t perfect, but you are welcome to make it your own.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('*:not([src]):not([type]):empty{border:2px dotted #00f !important;background-color:#00f;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Find Empty Elements
Invert Page (Added August 17, updated Dec. 8, 2016)
I have a nifty app on my phone that allows me to turn the brightness down to barely visible. This is handy when reading at night. Even when very dark, sometimes the black text on white page is just too hard on my eyes.
This bookmarklet will invert the entire page (like looking at a negative of a film photo). It then goes through and unverts (I just made up a word) all img
and video
elements. It won’t work on background images, which also makes this a handy testing tool. Also, since pages that exclude a background color don’t invert properly for me in Chrome, and since checking for a null value is nigh impossible, I just force the background to nearly black (which means it satisfies my goal of painless reading at night). Note, the latest update also removes any background color from the html
element. You can just chop the document.body.style.backgroundColor='#111';
off the end if you don’t want it.
javascript:(function () { var css = 'html {-webkit-filter: invert(100%);' + '-moz-filter: invert(100%);' + '-o-filter: invert(100%);' + '-ms-filter: invert(100%); } img {-webkit-filter: invert(100%);' + '-moz-filter: invert(100%);' + '-o-filter: invert(100%);' + '-ms-filter: invert(100%); } video {-webkit-filter: invert(100%);' + '-moz-filter: invert(100%);' + '-o-filter: invert(100%);' + '-ms-filter: invert(100%); } html { background-color: transparent; }'; var head = document.getElementsByTagName('head')[0]; var style = document.createElement('style'); if (!window.counter) { window.counter = 1; } else { window.counter++; if (window.counter % 2 == 0) { var css = 'html{-webkit-filter:invert(0%);-moz-filter:invert(0%);-o-filter:invert(0%);-ms-filter:invert(0%);}img{-webkit-filter:invert(0%);-moz-filter:invert(0%);-o-filter:invert(0%);-ms-filter:invert(0%);}video{-webkit-filter:invert(0%);-moz-filter:invert(0%);-o-filter:invert(0%);-ms-filter:invert(0%);}html{background-color:transparent;}' } } style.type = 'text/css'; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style); document.body.style.backgroundColor='#111'; }());
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Invert Page
Remove Twitter Moments (Added December 15)
People really don’t like Twitter Moments. I don’t think we need to remove it, but I understand lots of people find it hugely distracting. All this does is hide the option in the menu bar. It will also fail when Twitter updates its code again in n weeks.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('li.moments{display: none;}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Hide Twitter Moments
Link Underlines for Stack Overflow Questions and Answers (Added June 17, 2016)
I made a request at Stack Overflow to put underlines on links so they more visible (especially since they don’t have enough contrast with the surrounding text). While it gets debated and (based on feedback) probably ignored, I made a bookmarklet to restore links where I need them.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('.post-text a:link, .post-text a:visited, .comment-copy a:link, .comment-copy a:visited{text-decoration:underline !important}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: StackOverflow Link Underlines
Show Twitter Image Alt Text (Added January 3, 2017)
During an A11yNYC event tonight discussing alternative text for images, somebody asked how to see any alternative text applied to images on Twitter. The answer is use a screen reader or your browser’s inspector, but that seems unfortunate. So I made a bookmarklet to display a Twitter image’s alt text on top of the image. This is quick and dirty. The tweets must be loaded, it does not work on tweets with more than one image, it has not been thoroughly tested, and is not ideal code. But it is a start. Corrections / improvements welcome.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('a[href]{text-decoration:underline !important}',0);b.insertRule('div.alt{position:absolute;top:0;bottom:0;right:0;left:0;width:100%;z-index:999999;background-color:rgba(0,0,0,.75);color:#fff;box-sizing:border-box;padding:1em 2em;font-size:calc(1em + .25vw)}',0);var imgContainers=document.querySelectorAll('.AdaptiveMedia > div > div > div');for(i=0;i<imgContainers.length;i++){var imgs=imgContainers[i].getElementsByTagName('img');for(j=0;j<imgs.length;j++){var altDiv=document.createElement('div');altDiv.className='alt',imgAlts=imgs[j].getAttribute('alt'),altDiv.innerText=imgAlts,imgs[j].parentNode.insertBefore(altDiv,imgs[j].nextSibling)}}})();
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Show Twitter Image Alt Text
Fix LinkedIn Profile (Added August 15, 2017)
Sometimes I go to Google to look up a name, and often the search results bring me to LinkedIn. The problem is that LinkedIn throws a stupid sign-up modal in front of the content and turns off all scrolling. This is easy enough to fix with the browser’s inspector, or just a quickie bookmarklet.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('#advocate-modal{display:none !important;}',0);b.insertRule('body.advocate-modal-visible,body{overflow:auto !important;}',0);})();
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Fix LinkedIn Profile
Focus Interactive Controls (Added July 11, 2018)
Keyboard testing involves hitting the Tab a lot. Sometimes you want to see the focus styles, sometimes you want to see the order of the page, or see what is hidden, or hear how a screen reader announces controls. This bookmarklet will loop through every interactive control on the page, sitting on each one for one second. Also, once you start it, you cannot stop it. You can adjust the timing (to give a screen reader more time to announce each one) and you can adjust the CSS selector in the document.querySelectorAll
(to maybe pull only interactive controls that are within <main>
, for example). Or steal Scott O’Hara’s.
javascript:(function(){try{for(var e=document.querySelectorAll("a[href], area[href], input:not([disabled]), button:not([disabled]), select:not([disabled]), textarea:not([disabled]), iframe, object, embed, summary, [tabindex]:not([tabindex='-1']), [contenteditable=true], video[controls], audio[controls]"),t=0;t<e.length;t++)!function(t){setTimeout(function(){e[t].focus()},1000*t)}(t)}catch(e){console.log('getInteractives(): '+e)}})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Focus Interactive Controls
Reading Order (Added April 13, 2019)
I wrote up a whole thing in a detailed post, so go there to copy the script: Reading Order Bookmarklet
Copy or drag the link to your bookmarks: Reading Order
Show Tweet Image Alt Text (Added August 23, 2019; updated December 29, 2020)
There is still no easy way to see the alt text for an image in a tweet. Twitter’s developers eschewed the best practices of id
attributes or reasonable structure, which made creating simple styles a bit tricky. So this isn’t perfect, but yeah. In the meantime, read how to improve your tweet accessibility.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('a[role=link] div[aria-label]::after,div[aria-label][data-testid=previewInterstitial]::after{content:attr(aria-label);display:block;background-color:rgba(0,0,0,.8);color:#ff0;font-family:\'Segoe UI\',-apple-system,BlinkMacSystemFont,Roboto,Oxygen-Sans,Ubuntu,Cantarell,\'Helvetica Neue\',sans-serif;padding:1em;position:absolute;top:0;left:0;right:0;z-index:1}',0);b.insertRule('[dir=auto]>svg{display:none}',0);b.insertRule('a[role=link] div[aria-label]{display:contents;margin-top:unset !important;margin-bottom:unset !important}',0);})();
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Show Tweet alt Text
Fix GitHub Tables (Added January 20, 2020)
If you create a table on GitHub, there is a style intended to make it fit into the page container by adding scrollbars. It uses display: block
, and (as we know) that style strips table semantics in browsers making them useless for screen reader users. This bookmarklet undoes that style.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('.markdown-body table{display:table}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Fix GitHub Tables
Dismissable 44×44 Cursor (Added August 26, 2020)
I took Jarek Smith’s bookmarklet to show a 44 pixel square cursor and modified it to dismiss the cursor when you press Esc. Obviously there is some risk to using Esc, but I figure for testing it is fine, until it is not, and then you can customize it to a key or combination that works for you. A better solution is to destroy the CSS block entirely, but I have to go make dinner.
javascript:(function(){ var style = document.createElement('style'), styleContent = document.createTextNode('* { cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJBJREFUeNrs2dEKgDAIhWEN3/+VLYtBF12MppHwDxY0uvg4DJpORcSl0bB4uPcwq+oFHu8/956pbtJsAAYMGDBgwIABA044t3pMEgb8VU2XsWdn1o/aUUn4bchPBWNFYWvVidxbCFGmr7YULBs1YDPfsYcXEi9ryvDjAAwYMGDAgAED7nK8bHG7qNLs6nYXYAAheh5j8Qw5fwAAAABJRU5ErkJggg==) 22 22, auto !important}'); style.appendChild(styleContent ); var caput = document.getElementsByTagName('head'); caput[0].appendChild(style); document.onkeydown=function(e){var n;('key'in(e=e||window.event)?'Escape'==e.key||'Esc'==e.key:27==e.keyCode)&&(n=document.createElement('style'),document.head.appendChild(n),n.sheet.insertRule('*{cursor:revert !important}',0))}; })();
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: 44×44 Cursor, with Esc
Unset Font Weights (Added January 28, 2022)
Many sites use a custom font. When that custom font is thicker, such as using a headline font for body text, the site owner may make it thinner by adjusting the font-weight
. The problem is sometimes the font is broken, does not load, or the developer just has much better eyes, and the text ends up being far too narrow. This bookmarklet unsets all font-weight
(though you may need to tweak it for some sites) except on <strong>
, <b>
, and <h1>
through <h6>
. If the font is too narrow at any weight, this bookmarklet will not address it.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('*:not(strong):not(b):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6){font-weight:unset !important}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Unset Font Weight
Re-enable Text Selection (Added March 25, 2022)
Some devs may use the CSS property user-select
to prevent users from selecting text, either because they misunderstand the web in general or because they are trying to prevent draggable controls from also selecting. This bookmarklet will unset that rule for all elements.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('*{user-select:unset !important}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Re-enable Text Selection
Fix Twitter Homoglyphs (Added April 3, 2023)
It is trivially easy to impersonate someone else on Twitter, as its repeated Twitter Blue debacle has shown. Because nobody at Twitter enabled font-feature-settings: "ss01"
for tweets (only handles), homoglyph attacks (where characters like l and I look the same) are still easy, and a paid blue check can compound confusion. This bookmarklet enables the settings to make characters easier to distinguish
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule('body * {font-variant-alternates: styleset(ss01) !important;}',0);b.insertRule('@font-feature-values TwitterChirp{@styleset { ss01: 1 }}',0);})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Fix Twitter Homoglyphs
Fix Disability:IN 2024 Agenda (Added July 2, 2024)
The agenda page for Disability:IN in 2024 has some challenges (and WCAG violations). I made a bookmarklet to address the session index and then a second bookmarklet to also fix the search form. They are both in my post Disability:IN 2024 Agenda Bookmarklet. I add a lot more detail and context there, and those boomarklets are essentially useless after July 19, 2024.
Restore Controls to HTML Video Players (Added July 3, 2024)
While I am glad many sites have moved away from animated GIFs for product demos and other embellishments, too often they are set-up to auto-play, loop, and the author removed the ability to pause or stop the video (/me side-eyes Google’s web.dev). This bookmarklet looks for all <video>
elements that have no controls
attribute and adds it.
javascript:(function(){document.querySelectorAll('video:not([controls])').forEach(v=>{v.setAttribute('controls','');})})()
Copy or drag the link to your bookmarks, or make a new one and paste the code from above: Restore Video Controls
Make/Modify Your Own Bookmarklet
If you look at the code chunks above, you’ll see I am doing the same thing over and over. I am using the JavaScript CSSStyleSheet.insertRule()
method to insert a new style rule into the page’s stylesheet. Not only does the Mozilla Developer Network have a great overview with sample code, but David Walsh shows similar code with some minor tweaks.
This approach allows me to leverage my CSS skills to write selectors to find and style elements on the page. Since CSS has so many powerful selectors, I find this easier to quickly repurpose. In addition to adding a new style, I always include !important
with each so that it will override any inline styles.
If you are writing a function from scratch, make sure you minify it to take up less space (you may bump into character limits for a bookmarklet). Pre-pend javascript:
and make it the href
value of a link and you are done.
Here is a sample block of code you can use with the styles rendered in bold so you can replace them with your favorite selector. In this example I have two style rules so you can see how to add additional selectors.
javascript:(function(){var a=document.createElement('style'),b;document.head.appendChild(a);b=a.sheet;b.insertRule("a[href]{text-decoration:underline !important}",0);b.insertRule("*[style]{border:2px dotted #f00 !important;background-color:#f00;}",0);})()
And with that you should be off to the races.
Related
Links to my posts referenced above:
- Accessibility Bookmarklets and Tools
- I Don’t Care What Google Did, Just Keep Underlining Links
- Keep the Focus Outline
- See slide 93 for an example of where ARIA landmark roles generally go
- Image alt Exception Change Re-Re-Re-Requested
Update: February 14, 2015
It’s hard to use bookmarklets on mobile devices, but I have a solution.
Update: March 4, 2016
I’ve been adding more into the article over the last year, but Ted Drake just posted one for showing aria-label
values on a page. I felt it was worth linking.
4 Comments
Invert Page is cool. Possible don’t invert images when run this bookmarklet?
In response to .I wrote the bookmarklet to not invert (or rather, re-invert) any
img
andvideo
elements. It will still invert CSS background images. I chose not to un-invert background images because they are often used behind content, so inverted content would be illegible. Also, an entire page background image that is bright would still be too bright when reading in the dark.
Hi, thanks for gathering all those bookmarklets :)
I made one by myself, based on a very large CSS file: https://github.com/ffoodd/a11y.css
It’s meant to warn developper about possible mistakes in HTML code thanks to CSS. It’s widely documented with a website (http://ffoodd.github.io/a11y.css/) to test and explain selectors, and a wiki (https://github.com/ffoodd/a11y.css/wiki) to explain the code itself.Id’ love to have your opinion about this. And it’s still evolving, so feel free to open an issue :)
In response to .This looks pretty handy. It reminds me of Heydon Pickering’s Revenge.css (though his was not the first). I would have to play around with it a bit to get a sense of where it fits in my toolbox.
Leave a Comment or Response