Skip to content

Instantly share code, notes, and snippets.

@gsuberland
Last active November 19, 2025 13:04
Show Gist options
  • Select an option

  • Save gsuberland/928847fd65b2317c5ec132ffc9dde8b9 to your computer and use it in GitHub Desktop.

Select an option

Save gsuberland/928847fd65b2317c5ec132ffc9dde8b9 to your computer and use it in GitHub Desktop.
Greasemonkey / Tampermonkey script to bring back hoverable alt text in Mastodon 4.4
// ==UserScript==
// @name Mastodon 4.4 - Reinstate title text!
// @namespace http://tampermonkey.net/
// @version 2025-11-19b
// @description Restores alt text in the title attribute of images and videos, allowing the alt text to be viewed in a tooltip while hovering with the mouse. See https://github.com/mastodon/mastodon/issues/33799
// @author Graham Sutherland
// @match https://chaos.social/*
// @grant none
// ==/UserScript==
/*
Changelog:
2025-11-19b - Remove the icon from the userscript comment block because it keeps breaking userscript installs AAAAAAAA I HATE THIS
2025-11-19 - Handle case where VIDEO element has aria-label attribute but not alt attribute.
2025-07-22 - Initial release.
*/
(function() {
'use strict';
new MutationObserver(mutationList => {
mutationList.forEach(mutation => {
// watch for new 'img' and 'video' elements
Array.from(mutation.addedNodes)
.filter(el => el.nodeName != '#text')
.flatMap(el => [
(el.tagName == 'IMG' || el.tagName == 'VIDEO') ? [ el ] : [],
Array.from(el.getElementsByTagName('IMG')),
Array.from(el.getElementsByTagName('VIDEO'))
])
.flat()
.forEach(el =>
{
// if this media element has alt text, but no title text (missing attribute or empty string), clone alt text into the title attribute
if (el.hasAttribute("alt"))
{
if (!el.hasAttribute("title") || el.getAttribute("title") == "")
{
el.setAttribute("title", el.getAttribute("alt"));
}
}
// video elements sometimes just have aira-label and no alt text, so if we don't find alt then check for that too.
else if (el.tagName === "VIDEO" && el.hasAttribute("aria-label"))
{
if (!el.hasAttribute("title") || el.getAttribute("title") == "")
{
el.setAttribute("title", el.getAttribute("aria-label"));
}
}
});
});
}).observe(document.body, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment