An interesting web design question was posed to me recently: is it possible to automatically replace images on a webpage with their alt text when the page is printed? I searched around online, but couldn’t find any specific solutions.
So, after a bit of trial and error, I invented my own solution using JavaScript and CSS media types, and thought I would share in case anyone else was interested. It’s a rather specific problem, but perhaps this could be used for accessibility reasons.
HTML
Start off with a simple HTML document:
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8" /> <title>Print Alt Text</title> <link rel="stylesheet" href="css/screen.css" media="screen" /> <link rel="stylesheet" href="css/print.css" media="print" /> <script type="text/javascript" src="js/displayAlt.js"></script> </head> <body> <div> <img src="images/test1.jpg" alt="This is the alt text of Test Image 1" /> </div> <div> <img src="images/test2.jpg" alt="This is the alt text of Test Image 2" /> </div> </body> </html>
There’s nothing particularly special about this – just inline images wrapped in <div> tags (which aren’t necessarily required, but will probably create better results).
JavaScript
In the <head> of the HTML document is a script called displayAlt.js:
window.onload = function displayAlt(){
var imgs = document.images;
for (i = 0; i < imgs.length; i++){
var imgParent = imgs[i].parentNode;
var altText = imgs[i].alt;
var altDiv = imgParent.appendChild(document.createElement('div'));
altDiv.className = "altContent";
altDiv.innerHTML = altText;
}
}
Line by line, in plain English:
- When the document is loaded…
- Find all images in the document
- For each of these images…
- Find the image’s parent (in this case, the wrapping
<div>) - Get the image’s alt text
- Create a new
<div>and insert it as a child of the wrapping<div> - Give the new
<div>a class name called “altContent” - Take the alt text and insert it into the new
<div>
At this point, the alt text of each image on the page will display directly underneath it.
CSS
Now, we want to hide the alt text when the page is viewed in the browser, but hide the images and instead display just their alt text when the page is printed.
Also in the <head> are two stylesheets:
<link rel="stylesheet" href="css/screen.css" media="screen" /> <link rel="stylesheet" href="css/print.css" media="print" />
In screen.css, hide the <div>s that display the alt text:
.altContent {
display: none;
}
And in print.css, hide the images themselves:
img {
display: none;
}
Now, when the page is viewed in the browser, it will look just like normal – but when printed, all of the images will automatically be replaced with their alt text.