Build a deck accessibility checker
Flag missing alt text, low contrast, and tiny fonts across a Northwind deck.
Published Dec 14, 2025
A deck that looks polished can still be unreadable for part of its audience. An image with no alt text is silent to a screen reader; a 9pt caption disappears from the back of a room. Northwind’s pitch decks went out the door looking fine on the designer’s monitor — and nobody checked whether they actually worked for everyone.
This script audits a deck for the two accessibility problems that are easy to miss and easy to fix: images with no alt text, and text set below a legible size. It walks every slide and returns a plain list of what to correct, so an accessibility pass becomes a two-minute job instead of a slide-by-slide hunt.
What you’ll need
- The file ID of the Google Slides deck you want to check — the long string in its URL.
- Edit or view access to that deck so
SlidesAppcan open it. - Nothing else — the script only reads the deck and reports; it makes no changes.
The script
// The smallest font size, in points, that counts as legible.
const MIN_FONT_SIZE = 14;
/**
* Audits a Slides deck for accessibility problems and returns
* a list of human-readable issue strings.
*
* @param {string} deckId The file ID of the deck to check.
* @return {string[]} One entry per issue found.
*/
function checkAccessibility(deckId) {
const issues = [];
const deck = SlidesApp.openById(deckId);
const slides = deck.getSlides();
// Guard: an empty deck has nothing to audit.
if (!slides.length) return issues;
slides.forEach((slide, i) => {
const slideNumber = i + 1;
// 1. Every image should carry alt text for screen readers.
// Slides stores it as the image description, with title as a fallback.
for (const image of slide.getImages()) {
const alt = image.getDescription() || image.getTitle();
if (!alt) {
issues.push(`Slide ${slideNumber}: image missing alt text`);
}
}
// 2. Text below the minimum size is hard to read from a distance.
for (const shape of slide.getShapes()) {
const text = shape.getText();
// Skip empty shapes — there is no text to size-check.
if (!text.asString().trim()) continue;
const size = text.getTextStyle().getFontSize();
if (size && size < MIN_FONT_SIZE) {
issues.push(`Slide ${slideNumber}: tiny font (${size}pt)`);
}
}
});
return issues;
}
/**
* Convenience wrapper: checks one deck and logs the result.
*/
function logAccessibility() {
const issues = checkAccessibility('1abcDeckId');
Logger.log(issues.length ? issues.join('\n') : 'No accessibility issues.');
}
How it works
checkAccessibilityopens the deck by ID and collects its slides. If the deck has no slides it returns an empty list straight away.- It walks each slide, tracking a 1-based slide number for readable messages.
- For every image on the slide it reads the description, falling back to the title. An image with neither is flagged as missing alt text — the thing a screen reader needs to describe it.
- For every shape it reads the text. Empty shapes are skipped so a blank placeholder never produces a false flag.
- It reads the shape’s font size and, if a size is set and it falls below
MIN_FONT_SIZE(14pt), records a “tiny font” issue with the exact size. - The collected issues are returned as a flat list of strings.
logAccessibilityis a wrapper that runs the check on one deck and prints the result.
Example run
Running the checker against a six-slide deck might log:
Slide 2: image missing alt text
Slide 4: tiny font (10pt)
Slide 4: image missing alt text
Slide 6: tiny font (9pt)
That is the to-do list: add descriptions to the images on slides 2 and 4, and
bump the small captions on slides 4 and 6 up to at least 14pt. A clean deck logs
No accessibility issues. instead.
Run it
This is an on-demand check, run before a deck ships:
- Paste the script into a standalone Apps Script project.
- Set the deck ID in
logAccessibility(or pass it tocheckAccessibilitydirectly). - Select
logAccessibilityin the editor, click Run, and approve the authorisation prompt the first time. - Read the issues in the execution log, fix them in the deck, and re-run to confirm a clean result.
Watch out for
- The font check only sees a shape’s first run style. If one text box mixes a 12pt line with a 24pt heading, only the leading run’s size is tested — split the shape or iterate the runs for full coverage.
- Despite the description, this version does not measure colour contrast.
SlidesAppcan read foreground colours, but background contrast needs the fill behind the text — add that check if low-contrast text is a real risk. - Decorative images legitimately have no alt text. The checker cannot tell a decorative image from a meaningful one, so expect a few flags you will consciously ignore.
- It reads tables as shapes but does not descend into individual table cells, so small text inside a table can slip through.
- Large decks mean many
getImagesandgetShapescalls. A deck of 100+ slides may approach the Apps Script execution time limit — check decks one at a time.
Related
Extract all deck text into a sheet
Pull text out of every slide for review, translation, or copy-editing.
Updated Jan 4, 2026
Generate sales-enablement decks per segment
Tailor Northwind's messaging slides by audience segment — fintech, healthcare, retail.
Updated Dec 28, 2025
Insert chapter divider slides from an outline
Add section-break slides between chapters in a Northwind deck.
Updated Dec 21, 2025
Drive menu and price-list signage from a Sheet
Generate display slides for a Northwind venue — menus or price lists driven by a Sheet.
Updated Dec 7, 2025
Build a Slides-based countdown timer
Embed a live countdown timer in a Northwind deck — refreshed via a scheduled script.
Updated Nov 30, 2025