Build Six Hold-to-Play Piano Keys with Vanilla Web APIs

Quick Overview

Build six accessible hold-to-play piano keys with vanilla HTML, CSS, and JavaScript. Mouse and keyboard presses must compose correctly across simultaneous inputs, auto-repeat, outside release, editable targets, focus loss, and cleanup.

Build Six Hold-to-Play Piano Keys with Vanilla Web APIs

Company: Roblox

Role: Frontend Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

## Prompt Build a six-key piano interface for notes `C`, `D`, `E`, `F`, `G`, and `A` using only vanilla HTML, CSS, and JavaScript. The stylesheet already defines the visual class `.key.active`. The interaction requirements are: - Holding the primary mouse button down on a piano key adds `active`; releasing the button removes it immediately, including when release occurs outside the original element. - Holding the physical keyboard letters `c`, `d`, `e`, `f`, `g`, or `a` activates the corresponding keys until each matching keyup. - Several physical keys may be held at once and remain active independently. - Any other keyboard input is ignored. - Repeated `keydown` events generated while a key is held must not corrupt state. Explain the event model, state representation, cleanup, and accessibility behavior. Provide one compact, complete executable-style vanilla HTML/JavaScript example containing all six labeled controls and all required listeners. ### Constraints & Assumptions - Each note element has a stable `data-note` value and the shared `key` class. - Mouse and keyboard can refer to the same note at the same time; releasing one source must not deactivate a note still held by the other source. - The page can lose focus while keys are held, so state needs a blur or visibility cleanup path. - Audio playback is outside this exercise; only visual pressed state is required. - Key matching is case-insensitive and based on the typed letter, not a locale-specific label. - Piano shortcuts do not activate from an input, textarea, select, or editable target. A matching `keyup` still performs release cleanup even if focus moved into such a target after `keydown`. ### Clarifying Questions to Ask - Should mouse dragging between keys activate new notes? No; only the key on which the press began is associated with that press. - Must mouse and keyboard sources compose? Yes. - Should keyboard auto-repeat retrigger state? No. - What accessible roles, labels, focus behavior, and reduced-motion considerations apply? - Is touch support required now or an extension? ```hint Track sources rather than one Boolean For each note, retain the set of active input sources. The element is visually active while that set is nonempty. ``` ### What a Strong Answer Covers - Six semantic, labeled buttons with data-driven note lookup and `aria-pressed` synchronized with `.active`. - Delegated or per-key mouse handlers plus document-level release handling so release outside cannot stick a key. - Independent keyboard-held state, explicit editable-target policy, repeat-safe source tokens, normalization, and invalid-key filtering. - Correct composition when mouse and keyboard simultaneously hold the same note. - Cleanup on blur, visibility loss, element removal, and ordinary release. - Minimal DOM writes through one render helper and tests for simultaneous and interleaved inputs. - Accessibility that does not hijack unrelated typing contexts without a stated focus policy. ### Follow-up Questions 1. What bug appears if state is only one Boolean per note? 2. How would pointer events and pointer capture add touch and stylus support? 3. Should global keyboard shortcuts fire while a user types in an input field? 4. How would you test a mouse release outside the piano? 5. What cleanup is needed when the browser tab becomes hidden?

Quick Answer: Build six accessible hold-to-play piano keys with vanilla HTML, CSS, and JavaScript. Mouse and keyboard presses must compose correctly across simultaneous inputs, auto-repeat, outside release, editable targets, focus loss, and cleanup.

|Home/Software Engineering Fundamentals/Roblox
Roblox logo
Roblox
Aug 15, 2026, 12:00 AM
mediumFrontend EngineerTechnical ScreenSoftware Engineering Fundamentals
1
0

Prompt

Build a six-key piano interface for notes C, D, E, F, G, and A using only vanilla HTML, CSS, and JavaScript. The stylesheet already defines the visual class .key.active.

The interaction requirements are:

  • Holding the primary mouse button down on a piano key adds active ; releasing the button removes it immediately, including when release occurs outside the original element.
  • Holding the physical keyboard letters c , d , e , f , g , or a activates the corresponding keys until each matching keyup.
  • Several physical keys may be held at once and remain active independently.
  • Any other keyboard input is ignored.
  • Repeated keydown events generated while a key is held must not corrupt state.

Explain the event model, state representation, cleanup, and accessibility behavior. Provide one compact, complete executable-style vanilla HTML/JavaScript example containing all six labeled controls and all required listeners.

Constraints & Assumptions

  • Each note element has a stable data-note value and the shared key class.
  • Mouse and keyboard can refer to the same note at the same time; releasing one source must not deactivate a note still held by the other source.
  • The page can lose focus while keys are held, so state needs a blur or visibility cleanup path.
  • Audio playback is outside this exercise; only visual pressed state is required.
  • Key matching is case-insensitive and based on the typed letter, not a locale-specific label.
  • Piano shortcuts do not activate from an input, textarea, select, or editable target. A matching keyup still performs release cleanup even if focus moved into such a target after keydown .

Clarifying Questions to Ask Guidance

  • Should mouse dragging between keys activate new notes? No; only the key on which the press began is associated with that press.
  • Must mouse and keyboard sources compose? Yes.
  • Should keyboard auto-repeat retrigger state? No.
  • What accessible roles, labels, focus behavior, and reduced-motion considerations apply?
  • Is touch support required now or an extension?

What a Strong Answer Covers Guidance

  • Six semantic, labeled buttons with data-driven note lookup and aria-pressed synchronized with .active .
  • Delegated or per-key mouse handlers plus document-level release handling so release outside cannot stick a key.
  • Independent keyboard-held state, explicit editable-target policy, repeat-safe source tokens, normalization, and invalid-key filtering.
  • Correct composition when mouse and keyboard simultaneously hold the same note.
  • Cleanup on blur, visibility loss, element removal, and ordinary release.
  • Minimal DOM writes through one render helper and tests for simultaneous and interleaved inputs.
  • Accessibility that does not hijack unrelated typing contexts without a stated focus policy.

Follow-up Questions Guidance

  1. What bug appears if state is only one Boolean per note?
  2. How would pointer events and pointer capture add touch and stylus support?
  3. Should global keyboard shortcuts fire while a user types in an input field?
  4. How would you test a mouse release outside the piano?
  5. What cleanup is needed when the browser tab becomes hidden?
Loading comments...