Any control element can send user input to the MediaController and receive media state from the MediaController.

The MediaController receives user input via MediaUIEvents like MediaUIEvents.MEDIA_PLAY_REQUEST or MediaUIEvents.MEDIA_SEEK_REQUEST. The MediaController may receive these events in one of two ways:

  • From a control element that is nested under the <media-controller> element (see diagram 1). The DOM element that will receive bubbling up events from the control element is the <media-controller> element, it’s also called an associated element in the codebase.

  • From a control element that is not nested under the <media-controller> element (see diagram 2). An associated element is created by targeting the media controller via the mediacontroller attribute or property.

    <media-controller id="my-ctrl">
      <video slot="media"></video>
    <media-play-button mediacontroller="my-ctrl"></media-play-button>

    Now the DOM events are received by the associated element and passed through to the MediaController.

    All Media Chrome elements support the mediacontroller attribute and can be made an associated element. Simple HTML elements can be made associated elements but require some JavaScript to get this to work.

The MediaController propagates media state by setting MediaUIAttributes on observing DOM elements.

Any associated element or any of its descendants can receive media state from the MediaController, as long as the elements are identifiable as something that should receive media state (aka identifiable as a media state receiver). Elements are identified as media state receivers in one of two ways:

  • The native Media Chrome web components will have this built in and they do this by having the MediaUIAttributes listed in the web component observedAttributes array.

    class MediaPlayButton extends MediaChromeButton {
      static get observedAttributes() {
        return [...super.observedAttributes, MediaUIAttributes.MEDIA_PAUSED];
  • Simple HTML elements like a <div> element for example are also able to receive media state by defining a mediachromeattributes attribute and listing the MediaUIAttributes space separated.

    <div mediachromeattributes="mediapaused mediacurrenttime"></div>

media chrome diagram

View Figma embed

media chrome diagram

View Figma embed