# Themes

With our templating framework you can create your own custom player designs. This feature is available with player version v5.1 and above.

```javascript
new js3q({
    dataid: '5c3b0910-8850-11e7-9273-002590c750be',
    container: 'player',
    template: {
        htmlFile: '*httpPathToFile*',
        // or inline:
        // html: `<div class="myCustomDiv"> ... </div>`,
        cssFile: '*httpPathToFile*',
        // or inline:
        // css: `.myCustomDiv { color: red; ... }`,
    }
});
```

A player template is comprised of a HTML and CSS definition of the player elements. To use a player template, you can provide links to these files hosted on your sever using the parameters `htmlFile` and `cssFile`. If you choose to host the files yourself, please check your `CORS` settings.

Alternatively you can post the markup inline using the config parameters `html` and `css`.

Hint: If you use inline Markup, we recommend using string literals (`` ` ``) instead of quotes ( `"`, `'`), to avoid issues with line breaks.

Finally, it is also possible to upload the files directly to a player using our GUI.

### **Template Options**

The following additional options are available when configuring a playlist

| Value            | type    | Description                                      | Default |
| ---------------- | ------- | ------------------------------------------------ | ------- |
| htmlFile         | string  | URl of the template. Be aware of CORS            |         |
| html             | string  | inline Markup                                    |         |
| cssFile          | string  | URL of the CSS                                   |         |
| css              | string  | inline CSS                                       |         |
| audioPoster      | boolean | For hiding the cover in the audio template       | true    |
| audioDescription | boolean | For hiding the description in the audio template | true    |

### **Syntax**

You can add a `class` attribute to each container to define the CSS. The `data-role` attribute is used by our engine to map the button role. You can find a complete list of all buttons below.

### **Base Template (Video)**

```html
<div data-role="sdn-player">
  <div data-role="sdn-display">
    <div data-role="sdn-stats"></div>
    <div data-role="motion-poster"></div>
    <div data-role="sdn-wall"></div>
    <div data-role="display-ad"></div>
    <div data-role="adskip-button"> {{skip}} </div>
    <div data-role="sdn-unmute-button"></div>

    [[context]]

    <div data-role="channel-label"></div>
    <div data-role="title"></div>

    <video
      data-role="source-container"
      x-webkit-airplay="allow"
      webkit-playsinline="true"
      playsinline="true"
      src=""
    ></video>

    <div data-role="play-button-overlay">
      <div data-role="play-button-overlay-span"></div>
    </div>

    <div data-role="play-buffer-overlay">
      <div data-role="play-buffer-overlay-spinner"></div>
    </div>

    <div data-role="player-controls">
      [[seekbar]] [[controls]]
      <div data-role="thumbnails"></div>
    </div>

    [[watermark]]

    <div data-role="gradiant"></div>
    <div data-role="gradiant-top"></div>

    [[qosmenu]]

    <div data-role="top-chrome">
      <div data-role="share-menu">
        <div data-role="sidebar-button"></div>
      </div>
    </div>

    <div data-role="sidebar"></div>

    [[infobar]]

    <div data-role="playlist"></div>
  </div>
</div>
```

### **Roles and Classes**

| data-role                    | default css class                                      | required                       |
| ---------------------------- | ------------------------------------------------------ | ------------------------------ |
| sdn-player                   | `.js3q-player`                                         | ✅                              |
| sdn-audio-player             | `.js3q-player.js3q-audio-player`                       | (as alternative to sdn-player) |
| sdn-display                  | `.sdn-display`                                         | ✅                              |
| sdn-stats                    | `.sdn-stats`                                           |                                |
| motion-poster                | `.sdn-motion-poster`                                   |                                |
| display-ad                   | `.sdn-display-ad`                                      | ✅                              |
| adskip-button                | `.sdn-display-adskipbutton`                            |                                |
| title                        | `.sdn-title`                                           | ✅                              |
| sdn-wall                     | `.sdn-wall`                                            |                                |
| sdn-unmute-button            | `.sdn-display-ad`                                      |                                |
| context                      | `.sdn-context-menu`                                    |                                |
| channel-label                | `.sdn-channel-label`                                   | ✅                              |
| source-container             | `.sdn-source-element`                                  |                                |
| play-button-overlay          | `.sdn-play-overlay`                                    |                                |
| play-button-overlay-span     | `.sdnicbsun-play.none-shadow`                          |                                |
| play-minus15-overlay         | `.sdn-minus15-overlay`                                 |                                |
| play-minus15-overlay-button  | `.ssdnicbsun-minus15.none-shadow`                      |                                |
| play-plus15-overlay          | `.sdn-plus15-overlay`                                  |                                |
| play-plus15-overlay-button   | `.ssdnicbsub-plus15.none-shadow`                       |                                |
| play-buffer-overlay          | `.sdn-buffering`                                       |                                |
| play-buffer-overlay-spinner  | `.sdn-spinner`                                         |                                |
| player-controls              | `.sdn-player-controls`                                 |                                |
| seek-bar                     | `.sdn-time-seekbar`                                    |                                |
| scrubberbar                  | `.sdn-time-scrubber`                                   |                                |
| scrubber-loaded              | `.sdn-time-loaded`                                     |                                |
| scrubber-loaded-pointer      | `.sdn-time-loaded-pointer`                             |                                |
| scrubberdragger              | `.sdn-time-playahead`                                  |                                |
| scrubber-playahead           | `.scrubbBarDragger`                                    |                                |
| chrome                       | `.sdn-player-chrome`                                   |                                |
| pause-button                 | `.sdn-button.sdn-play-button.sdnicbsun-play`           |                                |
| play-button                  | `.sdn-button.sdn-play-button.sdnicbsun-pause`          |                                |
| back-button                  | `.sdn-button.sdn-play-button.sdnicbsun-back`           |                                |
| play-minus10-button          | `.sdn-button.sdn-play-button.sdnicbsun-minus10`        |                                |
| play-plus10-button           | `.sdn-button.sdn-play-button.sdnicbsun-plus10`         |                                |
| play-plus15-button           | `.sdn-button.sdn-play-button.sdnicbsun-plus15`         |                                |
| play-minus15-button          | `.sdn-button.sdn-play-button.sdnicbsun-minus15`        |                                |
| volume-button                | `.sdn-button.sdnicbsun-volume3wave`                    |                                |
| volume-display-wrapper       | `.sdn-volume-wrapper`                                  |                                |
| volume-display               | `.sdn-volume-slider`                                   |                                |
| volume-controls-marker       | `.sdn-volume-marker`                                   |                                |
| volume-controls-thumb        | `.sdn-volume-thumb`                                    |                                |
| timeleft-display             | `.sdn-button.sdn-time-left`                            |                                |
| timeleft-span                |                                                        |                                |
| enter-button                 | `.sdn-button-right.sdnicbsun-fullscreen`               |                                |
| exit-button                  | `.sdn-button-right.sdnicbsun-exitfullscreen`           |                                |
| qos-button                   | `.sdn-button-right.sdn-audioonly-hidden.sdnicbsun-cog` |                                |
| cast-button                  | `.sdn-button-right.sdnicbsun-cast`                     |                                |
| airplay-button               | `.sdn-button-right.sdnicbsun-airplay`                  |                                |
| thumbnails                   | `.sdn-thumbnails`                                      |                                |
| gradient                     | `.sdn-player-gradiant`                                 |                                |
| gradient-top                 | `.sdn-player-gradiant-top`                             |                                |
| qos-menu                     | `.sdn-qos-menu`                                        |                                |
| qos-menu-header-close-button | `.sdn-button-right.sdnicbsun-close.sdn-hidden`         |                                |
| qos-menu-wrapper             | `.sdn-qos-menu-wrapper`                                |                                |
| qs-playbackrate-settings     | `.sdn-quality-settings`                                |                                |
| qs-playbackrate-menu         | `.sdn-ul-menu`                                         |                                |
| qs-quality-settings          | `.sdn-quality-settings`                                |                                |
| qs-audio-settings            | `.sdn-audio-settings`                                  |                                |
| qs-cc-settings               | `.sdn-audio-settings`                                  |                                |
| qs-audio-menu                | `.sdn-ul-menu`                                         |                                |
| top-chrome                   | `.sdn-top-chrome`                                      |                                |
| share-menu                   | `.sdn-share-menu`                                      |                                |
| sidebar-button               | `.sdn-button-right.sdnicbsun-info.sdn-hide`            |                                |
| playlist                     | `.sdn-playlist`                                        |                                |
| infobar                      | `.sdn-infobar.sdn-hide`                                |                                |
| sidebar                      | `.sdn-sidebar`                                         |                                |
| watermark                    | `.sdn-watermark`                                       |                                |
| watermark-picture            | `.sdn-watermark-picture`                               |                                |

### **Labels/Language Strings**

For language strings in the template, you can use the same fields as described [here](https://player.docs.3q.video/player-web-sdk/labels). To embed them, place the field name between curly brackets. (e.g. `{{tips.play}}`)

Not only you can use the built-in language strings, you can also define your very own ones:

```javascript
new js3q({
  //...
  labels: {
    de: {
      'my-special-language-string': 'Lorem Ipsum',
    },
    en: {
      'my-special-language-string': 'dolor sit amet',
    },
  },
  template: {
    html: `<div>
      {{my-special-language-string}}

      <div data-role="title"></div>
      <!-- ... -->
    </div>`,
  },
})
```

### **Components**

Several components are separated for easier maintenance. You can override each component as described above, or you can create your own components.

To embed a component, place it between square brackets. (e.g. `[[context]]`)

```javascript
new js3q({
  //...
  template: {
    //...
    components: {
      audioPoster: {
        html: `<div class="outer" style="padding: 20px; background: lime;">
                <div class="inner">
                  <div data-role="audio-poster"></div>
                </div>
              </div>`,
        css: `
        .outer {
          /* Beware, that it is not possible to style the root element here */
          /* You need to style it inline, as shown above */
        }

        .inner {
          background: yellow;
          padding: 20px;
        }

        .sdn-ellipsis {
          display: none !important; // Does not affect the rest of the player, just works for the component
        }
      `,
      },
    },
  },
})
```

### **\[\[context]]**

The right-click menu

#### **Markup**

```html
<div data-role="context">
  <ul data-role="context-ul">
    <li data-role="context-li">
      <b>3Q</b> Videoplayer v${__PLAYER_VERSION__}
    </li>
    <li data-role="context-li-third">{{stats}}</li>
  </ul>
</div>
```

The cog menu for quality- and language-settings.

#### **Markup**

```html
<div data-role="qos-menu">
  <h2 data-role="qos-menu-header">
    {{tips.settings}}
    <button
      tooltip-position="left"
      tooltip="{{tips.settingsClose}}"
      data-role="qos-menu-header-close-button"
    ></button>
  </h2>

  <div data-role="qos-menu-wrapper">
    <div data-role="qs-playbackrate-settings">
      <h3>{{playbackrate}}</h3>
      <ul data-role="qs-playbackrate-menu"></ul>
    </div>

    <div data-role="qs-quality-settings">
      <h3>{{quality}}</h3>
      <ul class="sdn-ul-menu">
        <li>
          <span class="current">{{auto}}</span>
        </li>
      </ul>
    </div>

    <div data-role="qs-audio-settings">
      <h3>{{audiotracks}}</h3>
      <ul data-role="qs-audio-menu"></ul>
    </div>

    <div data-role="qs-cc-settings"></div>
  </div>
</div>
```

### **\[\[seekbar]]**

The seekbar which indicates the progress of the content

#### **Markup**

```html
<div data-role="seek-bar">
  <div data-role="scrubberbar"></div>
  <div data-role="scrubber-loaded">
    <div data-role="scrubber-loaded-pointer"></div>
  </div>
  <div data-role="scrubberdragger"></div>
  <div data-role="scrubber-playahead"></div>
</div>
```

### **\[\[videoControls]]**

The control bar for video content

#### **Markup**

```html
<div data-role="chrome">
  <button
    data-role="pause-button"
    tooltip="{{tips.play}}"
    tooltip-position="left"
  ></button>
  <button
    data-role="play-button"
    tooltip="{{tips.pause}}"
    tooltip-position="left"
  ></button>
  <button
    data-role="back-button"
    tooltip="{{playlist.playback}}"
    tooltip-position="left"
  ></button>
  <button
    data-role="next-button"
    tooltip="{{playlist.playnext}}"
    tooltip-position="left"
  ></button>
  <button data-role="play-minus10-button"></button>
  <button data-role="play-plus10-button"></button>
  <button data-role="play-minus15-button"></button>
  <button data-role="play-plus15-button"></button>
  <button
    data-role="volume-button"
    tooltip="{{tips.mutevolume}}"
    tooltip-position="left"
  ></button>

  <div data-role="volume-display-wrapper">
    <div data-role="volume-display">
      <div data-role="volume-controls-marker">
        <span data-role="volume-controls-thumb"></span>
      </div>
    </div>
  </div>

  <button data-role="timeleft-display">
    <span data-role="timeleft-span">
      ● Live
    </span>
  </div>

  <button
    data-role="enter-button"
    tooltip="{{tips.fullscreen}}"
  ></button>
  <button
    data-role="exit-button"
    tooltip="{{tips.exitfullscreen}}"
  ></button>
  <button data-role="qos-button" tooltip="{{tips.settings}}"></button>
  <button data-role="cast-button" tooltip="{{tips.cast}}"></button>
  <button
    data-role="airplay-button"
    tooltip="{{tips.airplay}}"
  ></button>
</div>
```

### **\[\[audioControls]]**

The control bar for audio content

#### **Markup**

```html
<div data-role="chrome">
  <button
    data-role="pause-button"
    tooltip="{{tips.play}}"
    tooltip-position="left"
  ></button>
  <button
    data-role="play-button"
    tooltip="{{tips.pause}}"
    tooltip-position="left"
  ></button>
  <button
    data-role="back-button"
    tooltip="{{playlist.playback}}"
    tooltip-position="left"
  ></button>
  <button
    data-role="next-button"
    tooltip="{{playlist.playnext}}"
    tooltip-position="left"
  ></button>
  <button data-role="play-minus10-button"></button>
  <button data-role="play-plus10-button"></button>
  <button data-role="play-minus15-button"></button>
  <button data-role="play-plus15-button"></button>
  <button
    data-role="volume-button"
    tooltip="{{tips.mutevolume}}"
    tooltip-position="left"
  ></button>

  <div data-role="volume-display-wrapper">
    <div data-role="volume-display">
      <div data-role="volume-controls-marker">
        <span data-role="volume-controls-thumb"></span>
      </div>
    </div>
  </div>

  <button data-role="qos-button" tooltip="{{tips.settings}}"></button>
  <button data-role="cast-button" tooltip="{{tips.cast}}"></button>
  <button
    data-role="airplay-button"
    tooltip="{{tips.airplay}}"
  ></button>

  <button data-role="timeleft-display">
    <span data-role="timeleft-span">
      ● Live
    </span>
  </button>
</div>
```

### Minimal Example Audio Player <a href="#page_minimal_example_audio_player" id="page_minimal_example_audio_player"></a>

```html
<div data-role="sdn-audio-player">
  <div data-role="sdn-display" class="sdn-display sdn-display-audio">
    <div data-role="channel-label"></div>
    <div data-role="title"></div>

    <video data-role="source-container" class="sdn-source-element sdn-hidden" x-webkit-airplay="allow" webkit-playsinline="true" playsinline="true" src="">

    <div data-role="player-controls">
      [[audioControls]]
    </div>

    <div data-role="playlist"></div>
  </div>
</div>
```
