Skip to content

adSlots: ad slot elements never get the mo-item class, so no layout rule applies #10

Description

@MattOpen

Summary

Ad slots created by adSlots never receive the mo-item class, so none of the library's own layout rules apply to them. In a two-column timeline the slot spans the full width instead of one column, gets no float, and the library's own height reservation never takes effect.

This affects both style: 'card' and style: 'fullwidth'.

Cause

_createAdSlot() (src/moTimeline.js:533) assigns the class list instead of adding to it:

_createAdSlot(fullWidth) {
  const slot = document.createElement('li');
  slot.className = 'mo-ad-slot';        // <- overwrites, so `mo-item` is never present
  if (fullWidth) slot.classList.add('mo-fullwidth');
  return slot;
}

Every layout rule in moTimeline.css is scoped to .mo-timeline > .mo-item:

.mo-timeline > .mo-item                     { float: left; width: 50%; ... }
.mo-timeline > .mo-item.mo-inverted         { float: right; }
.mo-timeline > .mo-item.mo-ad-slot          { min-height: 100px; }   /* line 308 */
.mo-timeline.mo-twocol > .mo-item.mo-fullwidth { clear: both; width: 100%; }

Since the slot only carries mo-ad-slot, none of these match.

Items get mo-item in _initItems() and insertItem(); ad slots are created in _injectAdSlots(), which never adds it.

Reproduction

Standalone page, only moTimeline.css and moTimeline.umd.js, no other CSS, config exactly as in the README "Ad slots" section (mode: 'every_n', interval: 3, style: 'card', theme: true, columnCount: {xs:1,sm:1,md:2,lg:2}), 12 items via addItems(), callback appends an <ins> as shown in the docs.

Measured at 900px container width, v2.13.2:

ad slot regular item
classes mo-ad-slot mo-item js-mo-item
computed width 900px 450px
computed float none left
computed min-height 0px

Expected per README: "The library provides a <li class="mo-ad-slot"> element with min-height: 100px (so the observer can detect it before content loads)".

The 0px height has a second consequence: an empty slot has no area, so the IntersectionObserver (threshold 0.5) may never fire and onEnterViewport is never called — the slot stays empty even when the visitor scrolls right past it.

Suggested fix

slot.className = 'mo-item mo-ad-slot';

or

slot.classList.add('mo-item', 'mo-ad-slot');

⚠️ Worth checking alongside: js-mo-item is deliberately not added, since _initItems() uses that selector to find real items and slots must not be counted as items. The CSS only needs mo-item.

Note

The live demo does not exercise adSlots anywhere — the option appears only in the documentation and in the bundled source. That is likely why this went unnoticed since the feature was introduced in v2.11.0.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions