Skip to content
CodeLifter

Image popup

A full-size image viewer on the native dialog element: Escape closes it, focus returns to the thumbnail, and the large image keeps its alt text.

CL-0036 fixesChecked 2026-10-15
An empty white slide mount beside a black loupe with an orange-red base ring

1. The prompt

Not yet run against a named assistant · 113 words · CC-BY-4.0

Write an image popup in plain JavaScript using the native <dialog> element and showModal(). Each thumbnail is a link with the class popup that points to the full-size image, so it still opens where scripts or dialog support are missing. Use one click listener on the document. Set the large image's src and alt as properties, never by writing HTML, and take the alt from a data-alt attribute or the thumbnail's alt text. Put autofocus on a visible Close button, close the dialog when the backdrop is clicked, leave Escape to the browser, clear the image source on close and return focus to the thumbnail that opened it. Add an MIT licence comment.

image-popup.js JavaScript · 19 lines Reviewed
// MIT licence. CodeLifter editors, codelifter.com/prompts/image-popup/
const box = document.getElementById("imgbox");
const big = box.querySelector("img");
let opener = null;
document.addEventListener("click", (e) => {
const link = e.target.closest("a.popup");
if (!link || typeof box.showModal !== "function") return; // link still works
e.preventDefault();
opener = link;
big.src = link.href;
big.alt = link.dataset.alt || link.querySelector("img")?.alt || "";
box.showModal();
});
box.querySelector(".close").addEventListener("click", () => box.close());
box.addEventListener("click", (e) => { if (e.target === box) box.close(); });
box.addEventListener("close", () => {
big.removeAttribute("src");
opener?.focus(); // return focus to the thumbnail
});
2. What the prompt should produce. Load it after the markup below.

What a one-line prompt gets you

Representative output for “an image popup lightbox in JavaScript” and nothing else, written by the editors to show the pattern. It runs. It also leaves these gaps.

AI-generatedunreviewed
Shown for comparison. Do not ship.
function openImage(src) {
var img = new Image();
img.onload = function() {
var win = window.open("", "popup", "width=" + img.width + ",height=" + img.height);
win.document.write("<img src='" + src + "'>");
};
img.src = src;
}
// <a href="javascript:void(0)" onclick="openImage('photo.jpg')"><img src="thumb.jpg"></a>
Representative one-line-prompt output, written by the editors to show the pattern. Not a recorded generation.
  1. 1 Popup blockers can stop it.window.open runs in the image onload handler, after the click. MDN says popups must be opened in direct response to user input, and that window.open returns null when a blocker stops it, so the next line throws. The reviewed code opens a dialog inside the click handler.Prompt line: “Using the native <dialog> element and showModal().”
  2. 2 The link goes nowhere without JavaScript.MDN warns that javascript: hrefs misbehave when copied, opened in a new tab, bookmarked or loaded with scripts off, and give screen readers the wrong semantics. The reviewed thumbnail is a real link to the image.Prompt line: “Each thumbnail is a link with the class popup that points to the full-size image.”
  3. 3 Neither image has alt text.A screen reader user learns nothing about the picture they asked to see. The reviewed code copies data-alt, or the thumbnail's alt, to the large image.Prompt line: “Take the alt from a data-alt attribute or the thumbnail's alt text.”
  4. 4 Focus ends up in another window.The picture opens in a separate window, which MDN's accessibility notes call disorienting because a popup has no Previous button. The reviewed dialog stays in the page and sends focus back to the thumbnail when it closes.Prompt line: “Return focus to the thumbnail that opened it.”
  5. 5 It builds HTML from a string.document.write with a concatenated src turns a crafted file name into markup. The reviewed code sets src and alt as properties, so nothing is parsed as HTML.Prompt line: “Set the large image's src and alt as properties, never by writing HTML.”
  6. 6 It carries no licence.Nothing says who wrote it or on what terms. The reviewed script starts with an MIT licence line and a credit.Prompt line: “Add an MIT licence comment.”

Install it

  1. 1Make a large and a small version of each image. The link's href points to the large one; the img inside points to the small one.
  2. 2Write alt text on every thumbnail, and add a data-alt attribute on the link if the large image needs a longer description.
  3. 3Paste the dialog and the style block once per page, anywhere in the body, and load image-popup.js after them.
  4. 4Add class="popup" to every thumbnail link that should open in the dialog.
  5. 5Open a thumbnail with the keyboard, press Escape, and check that focus lands back on the thumbnail you opened.
index.html HTML · 12 lines Reviewed
<a href="harbour-large.jpg" class="popup" data-alt="Harbour at dusk, full size">
<img src="harbour-small.jpg" alt="Harbour at dusk" width="200" height="133"></a>
<dialog id="imgbox" aria-label="Enlarged image">
<button type="button" class="close" autofocus>Close</button>
<img alt="">
</dialog>
<style>
#imgbox { padding: 0; border: 0; max-width: 95vw; max-height: 95vh; }
#imgbox img { display: block; max-width: 95vw; max-height: calc(95vh - 3rem); }
#imgbox::backdrop { background: rgb(0 0 0 / 0.75); }
</style>
<script src="image-popup.js"></script>

Questions and answers

Has this prompt been tested with an assistant?

Not yet. The editors wrote the prompt to describe the reviewed code, which they wrote and tested with AI assistance and re-ran in a scripted DOM test on 2026-10-15. Nobody has run the prompt against a named assistant, so compare any answer with the code above.

Does the popup close with the Escape key?

Yes, without extra script. MDN's dialog reference says modal dialogs can be closed by pressing Esc, and that a dialog opened with showModal() and no closedby attribute behaves as if closedby were set to closerequest.

How does a click outside the image close it?

A click on the dark backdrop lands on the dialog element itself, while a click on the picture lands on the img. The script closes the dialog only when the event target is the dialog.

Where should focus go when the popup closes?

Back to the thumbnail that opened it. The WAI-ARIA Authoring Practices dialog (modal) pattern says focus returns to the invoking element when a dialog closes, unless that element no longer exists.

Why is autofocus on the Close button?

MDN recommends autofocus on the element the reader will use first, and suggests the close button when nothing else needs immediate interaction. The APG pattern also strongly recommends a visible button that closes the dialog.

Why not put tabindex on the dialog?

MDN's dialog page warns that the tabindex attribute must not be used on the dialog element. Focus belongs on the controls inside it.

Why not open the image with window.open?

MDN says modern browsers have strict popup blocker policies, that window.open returns null when blocked, and that it opens a new tab by default rather than a sized window. A dialog keeps the picture in the page.

Is the dialog element supported everywhere?

MDN lists the dialog element and showModal() as Baseline widely available, across browsers since March 2022 (checked 2026-10-15). Where showModal is missing, the script steps aside and the link opens the image directly.

Can I use the image popup on a client site?

Yes. The code is MIT licensed, so you can use and change it in paid work; keep the licence line or credit CodeLifter in your notices.

Sources

  1. 1<dialog>: The Dialog elementMDN Web Docs, checked 2026-10-15
  2. 2HTMLDialogElement: showModal() methodMDN Web Docs, checked 2026-10-15
  3. 3Dialog (Modal) PatternWAI-ARIA Authoring Practices Guide, W3C, checked 2026-10-15
  4. 4Window: open() methodMDN Web Docs, checked 2026-10-15

More prompts

All six prompts