Skip to main content

Button

The button element is a multi-touch enabled button, allowing simultaneous presses, pointers sliding between buttons, and concurrent use with other inputs.

It is a versatile element, designed specifically for game-like controls with touch, mirroring the Gamepad API button properties.

X
<xyba-button>X</xyba-button>

Install

npm install xyba-elements

Importing

Once installed, you can import via xyba-elements.

// Custom Elements
import "xyba-elements/elements/button/button.js";

// React
import { Button } from "xyba-elements/react";

Or import from CDN,

<script src="https://cdn.jsdelivr.net/npm/xyba-elements/dist/cdn/elements/button/button.js">

Examples

Capture pointer

Add the attribute or property capture to designate the button as the target for future events of the pointer until it's released. It also has the effect that the button is pressed until the pointer is lifted.

NB! Capture isn't suitable for buttons implementing the relates-to attribute or property. In this case wrap the elements with xyba-capture

A B
<xyba-button capture>A</xyba-button> <xyba-button capture>B</xyba-button>

Ignore Capture

The xyba-button has an option to react to events even though the pointer has pointerCapture. This can be useful in some scenarios, where eg. a xyba-analog element has capture but should still be able to press the button.

The capture attribute can be empty (it will ignore all pointer captures from any element), or a string of query selectors for element captures it should ignore (only ignore pointer captures from specific elements),

The property ignoreCapture can also be set to true or false to ignore or not.

A
<xyba-analog capture></xyba-analog>
<xyba-button capture ignore-capture>A</xyba-button>

Here's an example where button A only reacts to captured events from button B, but not from button C.

A B C
<xyba-button capture ignore-capture="#ignore-b-capture">A</xyba-button>
<xyba-button capture id="ignore-b-capture">B</xyba-button>
<xyba-button capture>C</xyba-button>

Relate to Other Elements

You can have a button relate to HTML elements using the attribute relates-to or property .relatesTo using query selectors separated by spaces in a string.

X Y XY
<xyba-button relates-to="#relates-xy">X</xyba-button>
<xyba-button relates-to="#relates-xy">Y</xyba-button>
<xyba-button id="relates-xy">XY</xyba-button>

Relates to advanced

Here's an advanced example for creating a diamond shaped collection of buttons with support for multiple button presses with a single pointer. It works by relating the buttons to a number of invisible HTML elements.

Y
B
A
X
<div class="rel-diamond">
<div class="rel-parent rel-top">
<xyba-button relates-to=".rel-top .rel-top-left .rel-top-right"
>Y</xyba-button
>
</div>
<div class="rel-parent rel-right">
<xyba-button relates-to=".rel-right .rel-top-right .rel-bottom-right"
>B</xyba-button
>
</div>
<div class="rel-parent rel-bottom">
<xyba-button relates-to=".rel-bottom .rel-bottom-left .rel-bottom-right"
>A</xyba-button
>
</div>
<div class="rel-parent rel-left">
<xyba-button relates-to=".rel-left .rel-bottom-left .rel-top-left"
>X</xyba-button
>
</div>
<div class="rel-area rel-top-left"></div>
<div class="rel-area rel-top-right"></div>
<div class="rel-area rel-bottom-right"></div>
<div class="rel-area rel-bottom-left"></div>
</div>

Expand Interaction Area

You can use ::before and ::after pseudo-elements to expand its interaction area, making it larger and easier to click.

X
<xyba-button class="before-example">X</xyba-button>

Toggle

Makes the button into a toggle button

X
<xyba-button toggle>X</xyba-button>

Disable

Disables the button, along side all pointer events.

X
<xyba-button disabled>X</xyba-button>

Customizing style

Disable default visual style

Add the attribute no-style to remove all default visual styling to implement your own style. The base styles for layout and pointer-events are preserved.

A
<xyba-button no-style>A</xyba-button>

Style using ::part

The button can be styled using ::parts.

A
<xyba-button class="button-part">A</xyba-button>

Custom visual styling

A simple custom style could be implemented like this.

A
<xyba-button class="custom-style" no-style>
<span>A</span>
</xyba-button>

Slotted elements

It's designed to be simple to use images by using slotted elements, the xyba-button accepts slotted elements for:

  • base - The base element (background)
  • image - The base image that is always visible.
  • image-pressed - The image only visible when pressed.
<xyba-button no-style class="slotted-elements">
<img slot="image" src="https://shorturl.at/MVwBM" loading="eager" />
<img slot="image-pressed" src="https://shorturl.at/rMHQj" loading="eager" />
</xyba-button>

Events

Use Inline events

Call global functions directly in the html using inline events. All events are available with the prefix on{event_name} as attributes and properties.

A B C D
<xyba-button onpress="window.handlePress">A</xyba-button>
<xyba-button onrelease="window.handleRelease">B</xyba-button>
<xyba-button onup="window.handleUp">C</xyba-button>
<xyba-button ondown="window.handleDown">D</xyba-button>

Use event listeners

Use references to the elements and add event listeners.

A B C D
<xyba-button id="event-button-a">A</xyba-button>
<xyba-button id="event-button-b">B</xyba-button>
<xyba-button id="event-button-c">C</xyba-button>
<xyba-button id="event-button-d">D</xyba-button>

Read state in game loop

It's also possible to read the current state instead of handling events

X
<xyba-button id="game-loop-demo">X</xyba-button>

Properties / Attributes

propertyattributetypedefaultdescriptionreadonly
valuevaluenumber0The value of pressure (either 0 or 1)
disableddisabledbooleanfalseIf the button is disabled
pressedpressedbooleanfalseIf the button is pressed
touchedtouchedbooleanfalseIf the button is touched
relatesTorelates-tostring | undefinedThe element querySelector queries it relates to
capturecapturebooleanfalseThe element querySelector queries it relates to
ignoreCaptureignore-captureboolean | string | undefinedThe element querySelector queries it should ignore pointer capture from. or boolean to ignore-all
noStyleno-stylebooleanfalseWhether default style should be in use
toggletogglebooleanfalse
movement{ x: number; y: number }The movement of the pad since last time it was requested.readonly
onpressonpressButtonPressEventThe event attribute / property for the `press` event.
onreleaseonreleaseButtonReleaseEventThe event attribute / property for the `release` event.
ondownondownButtonDownEventThe event attribute / property for the `down` event.
onuponupButtonUpEventThe event attribute / property for the `up` event.

CSS Slots

namedescription
The default button content.
baseThe base element of the button element.
imageThe button image (fills container).
image-pressedThe button image when pressed (fills container).

Events

namedescriptiontype
pressDispatched when the button is pressed.ButtonPressEvent
releaseDispatched when the button is released.ButtonReleaseEvent
changeDispatched when the button pressed state changes.ChangeEvent
downDispatched when the button is pressed down.ButtonDownEvent
upDispatched when the button is released.ButtonUpEvent
movementDispatched when the button is released.ButtonMovementEvent

CSS Custom Properties

namedescriptiondefault
--xyba-button-colorThe color inherited used for inheritance
--xyba-button-sizeThe size of the button
--xyba-button-backgroundThe background when not pressed
--xyba-button-background-activeThe background when pressed
--xyba-button-backdrop-filterThe backdrop filter used for the button
--xyba-button-border-widthThe border width used for the button
--xyba-button-border-colorThe border color used for the button
--xyba-button-border-color-activeThe border color used for the button when pressed
--xyba-button-border-styleThe border style used for the button
--xyba-button-text-colorThe text color specifically for the button text or icon
--xyba-button-text-color-activeThe text color specifically for the button text or icon when pressed