Reference

Theming and Markup

This page describes the public markup, CSS hooks and JavaScript behaviour of each block so a theme can restyle or extend them.

Assets

When a page contains at least one BlockSuite block, the module appends to the page head:

  • asset/css/card-slider-tabs.css (all four rendered blocks)
  • asset/js/card-slider-tabs.js (all four rendered blocks)

The script is plain JavaScript with no dependencies. It initialises every .card-slider-block and every .bst-tabs-block on DOMContentLoaded. Blocks inserted into the DOM later (for example by a theme's AJAX loading) are not initialised automatically.

Each rendered block is wrapped by Omeka in the usual <div class="block block-<layout>">, so you can also target .block-cardSlider, .block-itemSlider, .block-tabs and .block-tabsGroup.

Slider markup (Card Slider and Item Slider)

<div class="card-slider-block" role="region" aria-label="…"
     data-autoplay="true|false" data-interval="4000" data-visible="3">
  <h2 class="card-slider-block__heading">…</h2>
  <div class="card-slider-block__viewport">
    <div class="card-slider-block__track">
      <div class="card-slider-block__card" role="group" aria-label="Slide 1 of 5">
        <div class="card-slider-block__inner">…</div>
      </div>
    </div>
  </div>
  <button class="card-slider-block__prev" type="button" hidden>‹</button>
  <button class="card-slider-block__next" type="button">›</button>
  <div class="card-slider-block__live sr-only" aria-live="polite"></div>
</div>

The Item Slider adds item-slider-block to the wrapper and item-slide to each card.

Class Element
.card-slider-block__heading Optional <h2> heading
.card-slider-block__track Flex row that is translated horizontally
.card-slider-block__card One slide; flex-basis: calc(100% / var(--cards-visible, 3))
.card-slider-block__inner Card surface (white, 1px border, 8px radius, flex column)
.card-slider-block__image Card Slider image, 4:3, object-fit: cover
.card-slider-block__content, __title, __desc, __link Card Slider text and link button
.item-slide__thumbnail, .item-slide__placeholder Item Slider image or "No image" SVG placeholder
.item-slide__meta Item Slider property list
.item-prop, .item-prop--dcterms-title, … One property line, with a per-term modifier
.prop-label, .prop-value Property label and first value
.item-slide__link Item Slider link button
.card-slider-block__prev, __next Arrow buttons, absolutely positioned at the vertical centre

Slider behaviour

  • data-visible is the configured desktop count. The script sets the CSS custom property --cards-visible on the wrapper to 1 below 768px, min(2, desktop) below 1024px, and the desktop count above. The stylesheet also has matching media queries as a fallback before the script runs.
  • The track moves by setting transform: translateX(-index * 100 / visible %); there is a transform 0.4s ease transition.
  • The previous arrow gets the hidden attribute at the first position and the next arrow at the last position. Arrows are only rendered when there is more than one card.
  • Keyboard: ArrowLeft and ArrowRight while focus is inside the wrapper.
  • Pointer: pointerdown/pointermove/pointerup on the track; a horizontal move over 50px advances or goes back, smaller moves snap back. Images have dragstart prevented.
  • Autoplay (data-autoplay="true") uses setInterval with data-interval milliseconds, stops at the last position, and pauses on mouseenter/focusin, resuming on mouseleave/focusout. Any manual navigation restarts the timer.
  • The live region text is set to Slide N of M on each move.

Tabs markup (Tabs (HTML) and Tabs (Blocks))

<div class="bst-tabs-block" id="bst-tabs-{blockId}">
  <h2 class="bst-tabs-block__heading">…</h2>
  <div class="bst-tabs-block__intro">…</div>                <!-- Tabs (Blocks) only -->
  <div role="tablist" class="bst-tabs-block__tablist" aria-label="…">
    <button role="tab" id="bst-tab-{blockId}-0" aria-controls="bst-panel-{blockId}-0"
            aria-selected="true" tabindex="0" class="bst-tabs-block__tab" type="button">…</button>
  </div>
  <div role="tabpanel" id="bst-panel-{blockId}-0" aria-labelledby="bst-tab-{blockId}-0"
       class="bst-tabs-block__panel bst-tabs-block__panel--active" tabindex="0">…</div>
  <div role="tabpanel" id="bst-panel-{blockId}-1" … class="bst-tabs-block__panel" hidden tabindex="0">…</div>
</div>

A Tabs (Blocks) container adds bst-tabs-block--group to the wrapper and is itself wrapped in the standard block <div> (with grid position classes when the page uses the grid layout). The blocks inside a panel keep their own standard block wrappers.

Class Element
.bst-tabs-block__heading Optional <h2>
.bst-tabs-block__intro Blocks before the first divider (Tabs (Blocks) only)
.bst-tabs-block__tablist Flex, wrapping, 2px bottom border
.bst-tabs-block__tab Tab button; [aria-selected="true"] is bold with a 3px bottom border
.bst-tabs-block__panel Panel; .bst-tabs-block__panel--active marks the visible one, [hidden] is display: none

Tabs behaviour

  • Clicking a tab, or pressing ArrowLeft, ArrowRight (both wrap), Home or End while a tab has focus, activates that tab: it becomes aria-selected="true" with tabindex="0", all others get tabindex="-1", and only its panel is shown.
  • Each .bst-tabs-block only manages the tabs and panels that belong to it directly, so tab blocks nested inside a panel of another tab block work independently.
  • The default tab is decided server-side and written into the markup (aria-selected, hidden, --active), so the page renders correctly before the script runs.

Overriding templates

Copy any of these into your theme to change the markup:

view/common/block-layout/card-slider.phtml
view/common/block-layout/item-slider.phtml
view/common/block-layout/tabs.phtml
view/common/block-layout/tabs-group.phtml

The variables each template receives are listed in Block Data. If you keep the class names, role attributes, aria-controls and id pattern, the bundled script continues to work; otherwise dequeue it by not using those classes and provide your own.

Log in for Support