# How do I prompt for JavaScript that works with a keyboard?

Source: https://forum.codelifter.com/posts/how-do-i-prompt-for-javascript-that-works-with-a-keyboard/
Site: CodeLifter Forum, category Vibe coding prompts
Published: 2026-10-16. Updated: 2026-10-16. Replies: 0.

## Question by CodeLifter editors (staff), 2026-10-16

Spell it out in the prompt, control by control: real button and link elements for anything clickable, which keys do what, where focus goes after an action, and that the focus outline stays visible. "Make it accessible" is too vague to check. Then put the mouse away and test the result with Tab, Enter, Space, Escape and the arrow keys.

## What "works with a keyboard" means

The baseline is WCAG success criterion 2.1.1. The W3C's [Understanding 2.1.1: Keyboard](https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html) states it as: all functionality of the content is operable through a keyboard interface, without specific timings for individual keystrokes, except where the function depends on the path of the user's movement. The same page is clear that dragging an object to a location does not count as path dependent, so a draggable box still needs a keyboard way to move it.

The page also lists the failure that one-line prompts tend to produce: using only pointing-device-specific event handlers for a function (failure F54). A `div` with a click listener is the usual example.

## Lines to put in the prompt

Each line below names an element, a key or a focus rule, so you can check it in the answer. The quoted lines come from the CodeLifter prompts, whose code the editors tested; the prompts themselves have not been run against a named assistant.

| You want | Prompt line | Where it comes from |
| --- | --- | --- |
| Controls that reach the keyboard by default | "Use real `<button>` elements for Previous and Next" | [Slideshow prompt](https://codelifter.com/prompts/slideshow/) |
| A dialog that opens and closes from the keyboard | "Put autofocus on a visible Close button, close the dialog when the backdrop is clicked, leave Escape to the browser" | Image popup prompt |
| Focus back where the user was | "return focus to the thumbnail that opened it" | Image popup prompt |
| A custom widget that keys can move | "Make it focusable with tabindex="0", give it an accessible name that mentions the arrow keys, and move it 10 pixels per arrow key press, or 50 with Shift, calling preventDefault only for the arrows" | [Draggable element prompt](https://codelifter.com/prompts/draggable-element/) |
| Links that still behave like links | "leave clicks with any button other than the main one, and clicks with Ctrl, Cmd, Shift or Alt held, to the browser" | Go back prompt |

Add two general lines to any interactive prompt:

- "Use `<button type="button">` for every control that is not a link. Never put a click handler on a `div` or `span`."
- "Do not remove the focus outline. If you restyle it, use `:focus-visible` and keep it clearly visible."

The phrase "calling preventDefault only for the arrows" matters more than it looks. A key handler that calls `preventDefault()` on every key also swallows Tab, and the user is stuck.

## Why native elements first

MDN's [tabindex reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/tabindex) explains what you get for free: links with an `href`, buttons, form fields and `summary` are focusable by default, and developers should not add `tabindex` to them unless they are changing that behaviour. It also warns against a common shortcut: making a `div` focusable and using it as a button. Such components are not listed in the accessibility tree, so assistive technology cannot find or operate them.

Two more rules from the same page are worth putting in a rules file:

1. Only use `tabindex="0"` or `tabindex="-1"`. Positive values change the Tab order and make the page hard to navigate.
2. Never put `tabindex` on a `<dialog>`.

## Keep focus visible

Success criterion 2.4.7 asks that keyboard focus is visible in at least one mode of operation. The W3C's [Understanding 2.4.7: Focus Visible](https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html) lists styling outlines and borders so that the indicator disappears as a failure (F78), and lists CSS `:focus-visible` as a sufficient technique (C45). In generated CSS, look for `outline: none` or `outline: 0` with nothing put back in its place.

## Where a prompt cannot fix it alone

Some patterns need more than keys. WCAG 2.5.7 says dragging must also be possible with a single pointer without dragging, and a keyboard equivalent alone does not meet it. The CodeLifter draggable element says openly that its code does not meet 2.5.7 by itself. If you need that, ask for it by name: "Add buttons or number inputs that move the element without dragging."

## Test it in five minutes

1. Click the address bar, then press Tab until focus enters your component. Every control should get a visible outline, in a sensible order.
2. Press Shift+Tab to go back. Focus should move backwards through the same stops.
3. Press Enter on links, and Enter and Space on buttons. Both keys should activate a button.
4. Open any dialog. Focus should land inside it; Escape should close it and put focus back on the control that opened it.
5. On custom widgets, try the arrow keys you asked for, with and without Shift.
6. Tab past the component. If you cannot leave it with the keyboard, a handler is swallowing Tab.

If any step fails, quote the missing prompt line back to the assistant and ask for that change alone. The [innerHTML thread](/posts/how-do-i-stop-a-coding-assistant-from-using-innerhtml/) covers the other check worth running on every answer, and the [local models thread](/posts/do-the-codelifter-prompts-work-with-local-models/) covers running these prompts on your own machine.

---
Cite as: CodeLifter Forum, "How do I prompt for JavaScript that works with a keyboard?", https://forum.codelifter.com/posts/how-do-i-prompt-for-javascript-that-works-with-a-keyboard/, accessed 2026-10-16.
