JavaScript MouseEvent buttons Property

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline Widely available
Instance property

What You’ll Learn

MouseEvent.buttons is a read-only bit-field: which mouse buttons are held when the event fires. Learn the power-of-two values, how to combine and test bits, how this differs from button, and five try-it labs.

01

Kind

Instance property

02

Returns

Number (bit-field)

03

Status

Baseline Widely available

04

Access

event.buttons

05

Check bit

& 1, & 2, & 4

06

Great for

Drag / mousemove

Introduction

While drawing or dragging, you often need “is the left button still down?” on every mousemove. That is what buttons answers: the set of buttons currently pressed, encoded as a single number.

JavaScript
element.addEventListener("mousemove", (event) => {
  console.log(event.buttons); // 0, 1, 2, 3, 4, 5, 6, …
});
💡
Beginner tip

Think of sticky notes on a fridge: each button has its own note (1, 2, 4…). If several are stuck up, you add the numbers. To ask “is left up?” you use & with 1.

Understanding the Property

MDN: MouseEvent.buttons indicates which buttons are pressed when a mouse event is triggered. If more than one is pressed, the values are added together (for example secondary 2 + auxiliary 4 = 6).

  • Instance — read event.buttons in a handler.
  • Bit-field — powers of two that combine with addition / |.
  • Any mouse event — useful on mousemove, unlike button.
  • Not button — different property, different number system.

📝 Syntax

JavaScript
const held = mouseEvent.buttons;

Value

A number representing one or more held buttons:

buttonsMeaning (standard layout)
0No button / uninitialized
1Primary (usually left)
2Secondary (usually right)
4Auxiliary (usually middle / wheel)
84th (typically Back)
165th (typically Forward)
3Left + right (1 + 2)
6Right + middle (2 + 4)

Test a single button

JavaScript
const leftHeld = (event.buttons & 1) === 1;
const rightHeld = (event.buttons & 2) === 2;
const middleHeld = (event.buttons & 4) === 4;

⚖️ buttons vs button

buttonsbutton
QuestionWhich are held?Which changed?
TypeBit-fieldSingle index
Left10
Right22
Middle41
On mousemoveYes — use thisUnreliable

⚡ Quick Reference

GoalCode
Read held setevent.buttons
Left held?(event.buttons & 1) === 1
Right held?(event.buttons & 2) === 2
Middle held?(event.buttons & 4) === 4
Drag while movingif (event.buttons & 1) { … }
Synthetic left-held movenew MouseEvent("mousemove", { buttons: 1 })
MDN statusBaseline Widely available (Apr 2018)

🔍 At a Glance

Four facts about buttons.

Kind
instance

On the event

Type
bit-field

1 + 2 + 4…

Status
baseline

Since Apr 2018

Use on
mousemove

Drag detection

Examples Gallery

Examples follow MDN MouseEvent.buttons. Hold one or more buttons while clicking or moving to see combined values.

📚 Getting Started

Read the bit-field and decode individual buttons.

Example 1 — Log buttons on Press / Release

MDN-style: show the raw value and each button flag.

JavaScript
const buttonNames = ["left", "right", "wheel", "back", "forward"];

function mouseButtonPressed(event, buttonName) {
  return Boolean(event.buttons & (1 << buttonNames.indexOf(buttonName)));
}

function format(event) {
  const obj = { type: event.type, buttons: event.buttons };
  for (const name of buttonNames) {
    obj[name] = mouseButtonPressed(event, name);
  }
  return JSON.stringify(obj, null, 2);
}

document.addEventListener("mousedown", (e) => {
  console.log(format(e));
});
document.addEventListener("mouseup", (e) => {
  console.log(format(e));
});
Try It Yourself

How It Works

1 << index builds the bit for each named button. Bitwise & tests whether that bit is set in event.buttons.

Example 2 — Simple Left / Right / Middle Checks

The everyday pattern without a name table.

JavaScript
document.addEventListener("mousedown", (e) => {
  console.log({
    left: (e.buttons & 1) === 1,
    right: (e.buttons & 2) === 2,
    middle: (e.buttons & 4) === 4,
    raw: e.buttons
  });
});
Try It Yourself

How It Works

Mask with &, then compare to the same mask. You can also write Boolean(e.buttons & 1).

📈 Drag, Synthetic Events & button

Use buttons while moving; contrast with button.

Example 3 — Paint / Drag with mousemove

This is why buttons exists—button is unreliable here.

JavaScript
canvas.addEventListener("mousemove", (e) => {
  if ((e.buttons & 1) !== 1) {
    return; // not dragging with left
  }
  console.log("paint at", e.offsetX, e.offsetY);
});
Try It Yourself

How It Works

While the pointer moves with the primary button down, buttons stays 1 (or a larger combined value). Release and it becomes 0.

Example 4 — Synthetic Event with buttons: 3

Simulate left + right held for tests.

JavaScript
const event = new MouseEvent("mousemove", {
  buttons: 3, // 1 + 2
  bubbles: true
});

console.log(event.buttons);              // 3
console.log((event.buttons & 1) === 1);  // true (left)
console.log((event.buttons & 2) === 2);  // true (right)
console.log((event.buttons & 4) === 4);  // false (middle)
Try It Yourself

How It Works

Set buttons in MouseEvent() options. Combine bits with + or | (for example 1 | 2).

Example 5 — Same Gesture, Different Properties

Left press: button is 0, buttons is 1.

JavaScript
const leftDown = new MouseEvent("mousedown", {
  button: 0,
  buttons: 1
});

const bothDown = new MouseEvent("mousedown", {
  button: 2,   // right just changed
  buttons: 3   // left + right held
});

console.log(leftDown.button, leftDown.buttons); // 0 1
console.log(bothDown.button, bothDown.buttons); // 2 3
Try It Yourself

How It Works

Use button to learn which button just changed; use buttons to learn the full held set. See the button tutorial for press/release switching.

🚀 Common Use Cases

  • Canvas painting and drag selection while the pointer moves.
  • Detecting multi-button chords (left + right held together).
  • Ignoring hover moves when no button is down (buttons === 0).
  • Unit tests that synthesize held-button state on mousemove.
  • Teaching bit masks with a concrete browser API.

🔧 How It Works

1

One or more buttons stay down

OS tracks the current pressed set.

Input
2

Browser encodes a bit-field

Powers of two added into buttons.

Event
3

Any mouse handler reads it

Including mousemove and hover-related events.

Handler
4

Mask with &

Branch on left, right, middle, or combinations.

📝 Notes

  • Baseline Widely available (MDN, since April 2018).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Remapped / left-handed devices may change which physical button maps to primary.
  • Firefox historically had platform quirks (for example very old macOS returning 0); modern browsers are fine for typical use.
  • Related: button, clientX, altKey, MouseEvent(), Window, JavaScript hub.

Universal Browser Support

MouseEvent.buttons is Baseline Widely available across modern browsers (MDN: since April 2018). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

MouseEvent.buttons

Bit-field of held buttons for any mouse event—ideal for drag and paint on mousemove.

Universal Widely available
Google Chrome Full support · Desktop & Mobile
Full support
Mozilla Firefox Full support · Desktop & Mobile
Full support
Apple Safari Full support · macOS & iOS
Full support
Microsoft Edge Full support · Chromium
Full support
Opera Full support · Modern versions
Full support
Internet Explorer Supported in modern IE versions
Full support
buttons Excellent

Bottom line: Read event.buttons; test bits with &; prefer over button on mousemove.

Conclusion

event.buttons is the held-button bit-field. Combine values when several buttons are down, test with &, and use it on mousemove for drag logic. Use button when you need which button just changed.

Continue with clientX, button, MouseEvent(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Use buttons for held state on mousemove
  • Test bits with & 1, & 2, & 4
  • Combine bits with | when synthesizing events
  • Pair with button on mousedown / mouseup
  • Treat remapped devices as logical primary/secondary

❌ Don’t

  • Confuse left buttons === 1 with button === 0
  • Expect button alone to drive drag painting
  • Compare buttons only with === 1 if chords matter
  • Forget 0 means no button held
  • Skip accessibility for pointer-only paint tools

Key Takeaways

Knowledge Unlocked

Five things to remember about buttons

Held-button bit-field for every mouse event type.

5
Core concepts
🔢 02

1 / 2 / 4

left / right / mid

Bits
03

Add / OR

combine held

Chords
✏️ 04

Drag

on mousemove

Use
🛡️ 05

Baseline

since 2018

Status

❓ Frequently Asked Questions

It is a read-only number that is a bit-field of which mouse buttons are currently pressed when the event fires. Values add together—for example left (1) + right (2) = 3.
No. MDN marks MouseEvent.buttons as Baseline Widely available (since April 2018). It is not Deprecated, Experimental, or Non-standard, so no status warning banner is needed.
button is which button changed (0 left, 1 middle, 2 right) and is reliable mainly on press/release events. buttons is which buttons are held (1 left, 2 right, 4 middle) and works across mouse event types, including mousemove.
Use a bitwise AND: (event.buttons & 1) === 1. For right use & 2, for middle & 4.
Because bits add: secondary (2) + auxiliary/middle (4) = 6 when both are held at once.
Pass buttons in MouseEvent options, for example new MouseEvent("mousemove", { buttons: 1 }) to simulate left held while moving.
Did you know?

MDN’s example uses 1 << index so left is bit 0 (1), right bit 1 (2), wheel bit 2 (4), and so on—the same powers of two listed in the value table, generated from an array of names.

Next: MouseEvent.clientX

Learn viewport X coordinates for mouse events.

clientX →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful