Xbox controller tester, labelled the way it is printed

The tool below opens with Xbox names against every index, so buttons[0] reads "A" instead of "face button, bottom". Both triggers report a continuous value, both sticks plot their coordinates, and the device panel prints your pad's id and mapping so you can tell at a glance whether the standard layout even applies.

No controller yetLabels shown for Xbox

Press any button on your controller

A connected pad stays invisible to this page until you use it. That is the specification working as designed, not a fault — see the note below the tool.

Device report

id
waiting for input
mapping
—
index
—
buttons
—
axes
—
vibrationActuator
—

Vibration

Buttons

  • [0] A—
  • [1] B—
  • [2] X—
  • [3] Y—
  • [4] LB—
  • [5] RB—
  • [6] LT—
  • [7] RT—
  • [8] View—
  • [9] Menu—
  • [10] LS (left stick click)—
  • [11] RS (right stick click)—
  • [12] D-pad ↑—
  • [13] D-pad ↓—
  • [14] D-pad ←—
  • [15] D-pad →—
  • [16] Xbox button—

Axes

  • [0] left stick horizontal0.000
  • [1] left stick vertical0.000
  • [2] right stick horizontal0.000
  • [3] right stick vertical0.000

The two-minute check

Work around the pad in a fixed order so nothing gets missed: A, B, X, Y; LB, RB; LT, RT; View and Menu; both stick clicks; all four d-pad directions; the Xbox button. That is 17 inputs — the whole canonical set — plus the Share button on a Series X|S pad. Then push each stick to all four extremes and watch the axis values reach ±1.000, and squeeze each trigger from rest to the stop watching the value sweep from 0.000 to 1.000. Anything that fails to light or fails to reach its extreme is worth a second look while the pad is still returnable.

Two results deserve particular attention because they pass a casual test. A trigger that rests above 0.000 with your hands off the pad has stopped coming home — still below the pressed threshold, so a lights-only tester calls it healthy. And a stick that reaches only 0.94 at full deflection has lost part of its range, which feels like reduced sensitivity rather than a fault. Both are invisible to a tester that only shows lights.

What Chromium reads each Xbox button from

Browsers do not receive an "Xbox controller"; they receive a HID report and remap it onto the canonical layout. Chromium's Windows source contains a dedicated function for Xbox pads over Bluetooth, and the table below is that function's assignments, transcribed from it directly.

Transcribed from MapperXboxBluetooth in Chromium's gamepad_standard_mappings_win.cc. Windows only — Chromium keeps separate mapping files for macOS and Linux, which this table does not cover. Applies to: Xbox One S, Xbox Elite Series 2 and Xbox Adaptive controllers connected over Bluetooth, by product id.
Canonical index Button on the pad Read from Arrives as
buttons[0] A buttons[0] a raw button
buttons[1] B buttons[1] a raw button
buttons[2] X buttons[3] a raw button
buttons[3] Y buttons[4] a raw button
buttons[4] LB buttons[6] a raw button
buttons[5] RB buttons[7] a raw button
buttons[6] LT AxisToButton(axes[3]) an axis, converted
buttons[7] RT AxisToButton(axes[4]) an axis, converted
buttons[8] View buttons[10] a raw button
buttons[9] Menu buttons[11] a raw button
buttons[10] LS (left stick click) buttons[13] a raw button
buttons[11] RS (right stick click) buttons[14] a raw button
buttons[16] Xbox button buttons[12] a raw button

DpadFromAxis(axes[9]) fills indices 12–15 from a single hat axis.

Two things stand out. First, the triggers — canonical indices buttons[6] and buttons[7] — are not read from raw buttons at all; they are converted from axes. That is the mechanical reason a trigger has a continuous value in the first place, and why it behaves unlike every other entry in the button array. Second, the four face buttons come from raw positions 0, 1, 3, 4 — not 0 to 3 — and across the whole span the mapper touches, raw positions 2, 5, 8, 9 go unread entirely. Gaps like that in a raw report are completely normal, and they are exactly why reading indices straight off a pad that reports no mapping produces such confusing results.

Where the trigger dead zone comes from

Chromium turns a trigger's analog value into a boolean with a single comparison: pressed is true when the value exceeds 30/255, or 0.117647. The comment on that constant in the browser's source says "Matches XInput's trigger deadzone", which makes the provenance unusually clear — the web platform inherited the number from Xbox's own input stack rather than picking one. If you have ever wondered why a light trigger pull does nothing in a browser game, that is the number responsible, and it is the same one your Xbox software has been applying all along.

Splitting a controller fault from everything else

  1. Change one variable at a time. Wired then wireless, then a different port, then a different machine. An input that fails on all four is the controller; one that fails on one is not.
  2. Check mapping before believing an index. Over a dongle or an adapter it frequently reports the empty string, and every published table stops applying.
  3. Rule the OS out for the Xbox button. Windows claims it for the Game Bar; a pad that reports everything else is healthy.
  4. Test the sticks at rest, not just in motion. Full-deflection tests pass on badly drifting sticks — that is what the stick drift test is for.
  5. Try a different browser. If a pad enumerates in one and not another, the fault is in the browser's device table, and your hardware is fine.

If you also have other pads

The indices are shared but the letters are not, and Nintendo's arrangement is the reverse of Microsoft's — the bottom face button that reads "A" here reads "B" on a Pro Controller. The Switch Pro controller test covers that directly, and the controller button mapping page puts all four label sets in one table so you can see which indices agree.

Questions people actually ask

Does this work with an Xbox Series X, Xbox One or Xbox 360 controller?

All of them, and with third-party pads that present themselves the same way. What the page cares about is not the model but whether your controller reports mapping === "standard"; the device panel prints that value. When it does, the 17 canonical indices mean what this page says they mean. When it does not, read your indices off the live panel instead.

Where is the Share button on a Series X|S controller?

At index 17 on some platforms and nowhere at all on others, which is worth knowing before you count buttons. The canonical layout tops out at 16, and Chromium's macOS and Linux mappers — gamepad_standard_mappings_mac.mm and gamepad_standard_mappings_linux.cc — carry a Series X|S function that writes Share into the next slot as XBOX_SERIES_X_BUTTON_SHARE, pushing the reported total to 18, one past 17. The Windows mapper transcribed further down this page has no such row: it ends at the canonical count, so on that path Share never reaches the button array. Both counts are correct, and neither is an anomaly, which is why the device panel prints the number your browser actually reported instead of the number a chart predicts.

Why do my triggers show a value before they show as pressed?

Because Chromium derives the pressed flag from the analog value using a threshold of 30/255 — about 11.76% of travel — and the comment beside that constant in the source reads "Matches XInput's trigger deadzone". The lineage is not a coincidence: the browser adopted the same trigger dead zone Xbox software has used for years. The analog trigger test shows both numbers side by side.

My controller works over USB but not over Bluetooth. Why would that be?

Because the browser identifies and remaps controllers by product id, and an Xbox pad presents different ids on different connections. Chromium keeps a dedicated Bluetooth mapping for the Xbox One S, Elite Series 2 and Adaptive controllers; a pad whose Bluetooth id is not in that table falls through to generic handling, which usually means an empty mapping and a different button order. Test both connections and compare the device panel.

The Xbox button does nothing when I press it.

It is canonical index 16 — the center button in center cluster — and on Windows it is frequently intercepted by the system before any browser sees it, because it opens the Game Bar. That is an OS behaviour. If every other input registers and only this one does not, your pad is fine.

Can I test the Elite paddles here?

Usually not. Paddles on Elite-series controllers are typically configured to mirror existing buttons in the controller's own firmware, so pressing one reports the button it was mapped to, with no paddle of its own in the array. If a paddle is unassigned in your profile, it sends nothing at all and no browser can see it. Assign it to a face button, press it, and check that the corresponding index lights.

Keep testing

Test the rest of the desk