Polish

View saved

Goal for this step

Part 4 makes MiniCalc feel finished. Mouse users already have a working pad. Now keyboard users should get the same power, screen readers should hear clearer names, and divide-by-zero should never dump a raw Infinity onto the display.

Polish is not decoration only. These changes teach habits you will reuse on every interactive page: shared action handlers, visible focus, and honest error states.

What you should already know

You need the working click logic from Part 3. Ideally your handlers already funnel through one function such as handleAction(action, value). If clicks are still scattered, refactor lightly before adding keyboard support so both input paths share one brain.

A little CSS for :focus or :focus-visible helps. You do not need a design system—just a clear outline so keyboard users can see where they are.

Concepts in plain language

Accessible names matter when the visible label is a symbol. Sighted users understand ÷. A screen reader benefits from an aria-label such as “Divide”. The visible text can stay short while the accessible name stays descriptive.

aria-live="polite" on the display asks assistive technology to announce updates without interrupting the user mid-sentence. Pair it with aria-atomic="true" so the whole display value is read, not only a tiny fragment.

Keyboard support should call the same functions as clicks. Duplicating math in two places guarantees the paths drift apart. Map keys to actions, then reuse handleAction.

Divide-by-zero is a teaching moment. Computers can produce Infinity, but a calculator product should show a short human message and recover cleanly on the next digit or Clear press.

Labels, live regions, and keyboard mapping

Add descriptive aria-label text to operator and utility buttons. Keep digit labels as the digits themselves. Update the display markup so it politely announces changes.

Add a keydown listener on document. Digits, operators, Enter or =, Escape for clear, and Backspace should call the same action path as the on-screen buttons. Prevent the browser’s default Backspace navigation when you handle it yourself.

<output id="display" aria-live="polite" aria-atomic="true">0</output>
<button type="button" data-action="operator" data-value="/" aria-label="Divide">÷</button>

document.addEventListener("keydown", (event) => {
  if (/^[0-9]$/.test(event.key)) {
    handleAction("digit", event.key);
  } else if (event.key === "Enter" || event.key === "=") {
    handleAction("equals");
  } else if (event.key === "Escape") {
    handleAction("clear");
  } else if (event.key === "Backspace") {
    event.preventDefault();
    handleAction("backspace");
  }
});

Handle divide by zero safely

Inside compute, detect a zero divisor and return a sentinel such as null instead of performing the division. The caller can set the display to a short message like Cannot divide by 0 and mark state so the next digit starts fresh.

Clear and digit entry should wipe the error. Leaving Infinity or NaN on screen teaches the wrong lesson about how friendly software behaves.

case "/":
  if (b === 0) return null; // signal error to the caller
  return a / b;

Run the snapshot and verify

Serve Part 4 and try the calculator with the mouse, then put the mouse aside and use only the keyboard. Confirm digits, operators, Enter, Escape, and Backspace all work.

Trigger 10 ÷ 0 and confirm you see a clear error instead of Infinity. Tab through controls and confirm focus rings remain visible. If you use a screen reader, listen for display updates after equals.

git clone https://github.com/michaeldunga1/fcc-js-calculator.git
cd fcc-js-calculator/04-Polish
python3 -m http.server 8000
# Then visit http://localhost:8000

Common mistakes, checklist, and practice tip

Handling keyboard math in a second copy of your logic is the fastest way to create inconsistent bugs. One action function should serve both input paths.

Removing outlines with outline: none without a replacement focus style hurts keyboard users. If you restyle focus, keep contrast strong.

Practice tip: after you finish, add a percent key or a plus/minus toggle using the same data-action pattern. If the new key fits cleanly, your architecture is doing its job.

  • Number keys and operators work without clicking
  • Buttons have descriptive aria-label text where symbols need names
  • 10 ÷ 0 shows a clear error instead of Infinity
  • Focus rings remain visible for keyboard users
  • Click and keyboard paths share one action handler

Comments

One comment per signed-in account. Comments are saved with this page’s URL.