Skip to main content

Customizing Presentations with CSS, HTML, and JavaScript

Add custom CSS, HTML, and JavaScript to presentations using the built-in code tabs in the Presentation Editor

Written by Marc Rosenberg
Updated today

Customizing Presentations with CSS, HTML, and JavaScript

The Presentation Editor includes three built-in code tabs — CSS, HTML, and JS — that let you go beyond the standard field configuration to control exactly how your content looks and behaves on screen.

These tabs are available to Professional and Business subscribers.


Overview

Each tab serves a distinct purpose:

Tab

Purpose

CSS

Style dynamic text fields and HTML elements — font size, color, positioning, rotation, and more

HTML

Inject custom HTML markup — embedded content, custom layout elements, external feeds

JS

Add JavaScript for dynamic behavior — clocks, observers, timed actions, and third-party integrations

All three tabs work together. CSS styles the elements, HTML provides the markup, and JS adds interactivity. For simple price and name styling, you may only need the CSS tab. For third-party widget integrations (like a weather widget), you will typically use all three.


The CSS Tab

The CSS tab is where you control the visual appearance of your dynamic text fields and any custom HTML elements. Everything you add here is scoped to the presentation.

How it works

Each dynamic field is assigned a CSS class when you create it in the Fields tab (for example, .price or .item-name). You define the appearance of that class in the CSS tab.

.price {
  font-size: 44px;
  color: #ffffff;
  font-family: 'Oswald', sans-serif;
}.item-name {
  font-size: 32px;
  color: #f5c518;
}

Positioning fields

Fields are absolutely positioned on the canvas. The CSS tab is one way to specify a field's position — the other is drag-and-drop (enabled in Presentation Properties).

.price {
  font-size: 44px;
  color: red;
  top: 540px;
  left: 120px;
  position: absolute;
}

For portrait presentations without True Portrait mode, apply a rotation transform:

.price {
  transform: rotate(270deg);
  font-size: 44px;
  color: red;
}

Styling the Not Available overlay

When a field is marked N/A (86'd), Menuboard Manager applies the .n-a CSS class to the overlay element. Customize its appearance here:

.n-a {
  font-size: 36px;
  color: #ffffff;
  background-color: rgba(0, 0, 0, 0.75);
}

What is supported

  • Modern CSS is fully supported. Standard CSS syntax — flexbox, grid, transforms, animations, custom properties — all work.

  • Non-standard or proprietary CSS is not supported.

  • External stylesheets are supported via @import or <link> tags in the HTML tab, but external resources are not downloaded to local device storage. Adding CSS directly in the CSS tab is the preferred and most reliable method, especially for offline or low-connectivity display environments.

Note: Always test your CSS changes by publishing to a test unit before pushing to production displays. Some display hardware (particularly older Samsung TIZEN and LG WebOS units) may have minor rendering differences.


The HTML Tab

The HTML tab lets you inject custom HTML markup directly into the presentation. This is useful for third-party widget embeds, custom layout structures, or any content that needs to be defined as HTML rather than as a dynamic field.

How it works

HTML entered in this tab is injected into the presentation's DOM when it loads on the display. You can reference elements from the HTML tab in your CSS and JS tabs.

Common uses

  • Third-party widgets — embed a weather widget, social media feed, or custom data display using the widget's provided HTML snippet

  • Decorative elements — add dividers, logos, or background blocks as HTML elements and style them with CSS

  • Custom layout containers — create structural HTML that organizes content outside of the field section system

Example: Weather widget anchor tag

<a class="weatherwidget-io" id="weatherwidgetIo"
  href="https://forecast7.com/en/32d76n97d33/fort-worth/?unit=us"
  data-label_1="FORT WORTH"
  data-label_2="WEATHER"
  data-font="Arial Black">FORT WORTH WEATHER</a>

(The corresponding CSS and JS for this widget go in the CSS and JS tabs respectively. See Adding Widgets to a Presentation for the full weather widget setup.)

Note: HTML added in this tab cannot access or modify the field data managed by Menuboard Manager. It operates alongside the field system, not inside it.


The JS Tab

The JS tab lets you add JavaScript that runs when the presentation loads on the display. This enables dynamic behavior that goes beyond what CSS alone can provide.

How it works

JavaScript entered in this tab is executed in the context of the presentation page on the display device. You have access to the standard browser DOM APIs.

Key objects available in the presentation context:

  • document.getElementById('fields') — the container element holding all dynamic field elements

  • document.getElementById('playlist') — the playlist container, whose children correspond to individual playlist images/videos

  • Standard browser APIs: setTimeout, setInterval, MutationObserver, fetch, etc.

ES5 compatibility

ES5 syntax is strongly recommended for broadest compatibility across display hardware. Older Samsung TIZEN, LG WebOS, and BrightSign devices may not support ES6+ features like arrow functions, const/let, template literals, or async/await.

Write:

var items = document.getElementsByClassName('price');

Rather than:

const items = document.getElementsByClassName('price');

Common uses

  • Clocks and timers — update a display element every second with the current time

  • Playlist observers — use a MutationObserver to show or hide elements when a specific playlist slide becomes visible

  • Auto-reload — force the presentation to reload on an interval to refresh external content (e.g., a weather feed)

  • Third-party script loading — inject an external <script> tag to load a widget library

Example: Auto-reload after 8 hours

setTimeout(function() {
  window.location.reload();
}, 2.88e+7); // 28,800,000 ms = 8 hours

Example: Show/hide fields based on active playlist slide

var fields = document.getElementById('fields');
var children = fields.children;
var firstSlide = document.getElementById('playlist').firstChild;var observer = new MutationObserver(function(mutations) {
  for (var i = 0; i < mutations.length; i++) {
    var mutation = mutations[i];
    if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
      if (firstSlide.style.visibility === 'visible') {
        showFields();
      } else {
        hideFields();
      }
    }
  }
});observer.observe(firstSlide, { attributes: true });function showFields() {
  for (var i = 0; i < children.length; i++) {
    children[i].classList.remove('hide-prices');
  }
}function hideFields() {
  for (var i = 0; i < children.length; i++) {
    children[i].classList.add('hide-prices');
  }
}

Note: Always test JavaScript by publishing to a test unit before deploying to production displays. JavaScript errors are silent on display hardware and can prevent expected behavior without any visible error message.


Use Cases and Examples

Styling prices by column

Use unique CSS classes per field to position items precisely across a multi-column layout:

.col1-price { font-size: 40px; color: #fff; top: 200px; left: 480px; position: absolute; }
.col2-price { font-size: 40px; color: #fff; top: 200px; left: 960px; position: absolute; }
.col3-price { font-size: 40px; color: #fff; top: 200px; left: 1440px; position: absolute; }

Adding a live clock via JS and HTML

In the HTML tab:

<div id="clock" style="position:absolute; top:50px; left:50px; font-size:48px; color:white;"></div>

In the JS tab:

function updateClock() {
  var now = new Date();
  var h = now.getHours();
  var m = now.getMinutes();
  var ampm = h >= 12 ? 'PM' : 'AM';
  h = h % 12 || 12;
  m = m < 10 ? '0' + m : m;
  document.getElementById('clock').innerText = h + ':' + m + ' ' + ampm;
}
updateClock();
setInterval(updateClock, 1000);


Limitations

  • No server-side access. JS runs entirely in the browser context on the display device. It cannot make authenticated requests to the Menuboard Manager API or access backend data directly.

  • External resources require network access. If the display is offline or on a restricted network, external scripts, fonts loaded via @import, and third-party widget APIs will not load. Add critical CSS directly in the CSS tab rather than relying on external URLs.

  • ES5 compatibility. Avoid modern JavaScript syntax on presentations that will play on older hardware.

  • No persistent storage between reloads. localStorage and sessionStorage may be available on some platforms but are not guaranteed to persist across presentation reloads or device reboots. Do not rely on them for critical state.

  • HTML cannot interact with field data. Custom HTML elements are rendered alongside dynamic fields, but cannot read or modify field values managed by Menuboard Manager.


Related Articles

Did this answer your question?