Scrolling content¶
Availability: All contexts
The scroller module is used to render an automatically scrolling carousel with constantly moving content. Perfect for displaying rotating content such as testimonials or features with smooth, continuous scrolling.
Configuration parameters¶
Content¶
scrollerItemsRepeater¶
Repeater field for managing carousel slides (minimum 1, maximum 20 slides).
Each slide contains:
image(optional)- Image upload field (supported formats: webp, svg, jpg, png, gif, jpeg)
- The filename is important for SEO and should describe the content
-
Use dashes to separate words in filenames
-
imageAlt(optional) - Alternative text (
altattribute) for the image - Should contain a description of the image content
-
Read by screen readers and analyzed by search engines
-
content(optional) - WYSIWYG editor for slide text content
- HTML rich text formatting is supported
addHeading¶
boolean (optional, default: 0) - Display a heading above the scroller module.
When enabled, shows the following field:
- title - Module heading content (supports translations)
Basic Settings¶
moduleHeight¶
radio (required, default: automatic) - Determines how the module height is calculated.
Options:
- automatic - adjusts module height to content
- fixed - use a custom fixed height value
height¶
integer (optional, default: none) - Fixed height in pixels.
Only visible and required when moduleHeight is set to fixed.
- Default: not set
- Unit: px
scrollerVerticalAlignment¶
select (optional, default: center) - Vertical position of content within the module.
Only visible and available when moduleHeight is set to fixed.
Options:
- start - align content to top
- center - align content to center (default)
- end - align content to bottom
slideImagePosition¶
select (optional, default: above) - Layout direction of image and text content within each slide.
Options:
- above - Image displayed above content
- below - Image displayed below content
- left - Image displayed on the left side
- right - Image displayed on the right side
direction¶
select (required, default: rtl) - Direction of the automatic scrolling.
Options:
- rtl - Scroll to the left
- ltr - Scroll to the right
speed¶
select (optional, default: 1) - Scrolling speed of the carousel.
Options:
- 0.3 - Very slow
- 1 - Slow (default)
- 2 - Medium
- 3 - Fast
hasControls¶
boolean (optional, default: 0) - Add pause/stop button to the carousel.
When enabled, displays play and pause buttons allowing users to control the scrolling.
In the current implementation, enabling controls also disables automatic pause on hover and focus, so start/stop behavior is handled through the buttons.
Important: Content that scrolls automatically for more than 5 seconds must have a pause/stop option (EAA Directive compliance).
sliderRotation¶
integer (optional, default: 0) - Rotation angle of the content.
- Range: -3° to 3°
- 0° = no rotation
- Negative values = clockwise rotation
- Positive values = counterclockwise rotation
- Unit: degrees (°)
Responsive Breakpoints¶
Configure the number of visible slides for different device sizes:
Mobile¶
phoneElementsCountPerRowinteger(default: 2)- Range: 1 to 24
- Number of visible slides on phone/mobile devices
Tablet¶
tabletElementsCountPerRowinteger(default: 3)- Range: 1 to 24
- Number of visible slides on tablet devices
Laptop¶
laptopElementsCountPerRowinteger(default: 3)- Range: 1 to 24
- Number of visible slides on laptop/medium screens
Desktop¶
desktopElementsCountPerRowinteger(default: 3)- Range: 1 to 24
- Number of visible slides on desktop/large screens
Background Image¶
backgroundImage¶
Image upload field for the module background (supported formats: jpg, png, webp, svg, gif).
The background image is displayed behind the scrolling content.
Module Appearance¶
textColor¶
colorPicker (optional, default: @globalFontColor) - Text color for slide content.
Supports CSS color variables through the allowVariables option.
backgroundColor¶
colorPicker (optional, default: @globalBodyBackgroundColor) - Background color for the content area.
Supports CSS color variables through the allowVariables option.
CSS¶
classNames¶
string (optional) Additional CSS classes defined in the module schema.
Module source code¶
{% if moduleConfig.scrollerItemsRepeater|length > 0 %}
{% from "@macros/image.twig" import image %}
{% from "@macros/header.twig" import header %}
{% from "@macros/scroller.twig" import scroller %}
{% set elementsPerPageDesktop = moduleConfig.desktopElementsCountPerRow|default(3) %}
{% set elementsPerPageLaptop = moduleConfig.laptopElementsCountPerRow|default(3) %}
{% set elementsPerPageTablet = moduleConfig.tabletElementsCountPerRow|default(3) %}
{% set elementsPerPageMobile = moduleConfig.phoneElementsCountPerRow|default(2) %}
{% set speed = moduleConfig.speed|default(1) %}
{% set finalSpeed = moduleConfig.direction == 'ltr' ? -(speed|number_format(2, '.')) : (speed|number_format(2, '.')) %}
{% set scrollerSettings = {
"mountOnConnectedCallback": true,
"perPage": elementsPerPageDesktop,
"arrows": false,
"pagination": false,
"gap": "1rem",
"hasArrowsOnMobile": false,
"type": "loop",
"perMove": 1,
"drag": "free",
"focus": "center",
"keyboard": true,
"autoScroll": {
"autoStart": true,
"pauseOnFocus": moduleConfig.hasControls ? false : true,
"pauseOnHover": moduleConfig.hasControls ? false : true,
"rewind": false,
"speed": finalSpeed,
},
"reducedMotion": {
"speed": 0,
"autoScroll": {
"autoStart": false,
"speed": 0,
}
},
"breakpoints": {
1440: {
"perPage": elementsPerPageLaptop,
},
1000: {
"perPage": elementsPerPageTablet,
},
576: {
"perPage": elementsPerPageMobile
}
}
}
%}
{% set scrollerItemsTemplate %}
{% for group in moduleConfig.scrollerItemsRepeater %}
{% if group.active %}
<li class="splide__slide scroller__slide image_{{ moduleConfig.slideImagePosition }}" style="color: {{ moduleConfig.textColor }};{% if moduleConfig.moduleHeight == 'fixed' %} --height: {{ moduleConfig.height }}px;{% endif %}">
{% if group.values.image %}
{{ image({
img: {
width: group.values.image.width,
height: group.values.image.height,
src: group.values.image.paths.original,
id: "picture-#{group.values.image.id}",
alt: group.values.imageAlt,
title: group.values.imageAlt,
class: "scroller__slide-image",
decoding: 'async',
loading: 'lazy',
}
})
}}
{% endif %}
{% if group.values.content %}
<div class="scroller__slide-content resetcss fr-view">
{{ group.values.content|raw }}
</div>
{% endif %}
</li>
{% endif %}
{% endfor %}
{% endset %}
<div class="scroller {% if moduleConfig.classNames %}{{ moduleConfig.classNames }}{% endif %}">
{% if moduleConfig.addHeading and moduleConfig.title %}
{{
header({
level: 'h2',
content: moduleConfig.title,
hasUnderline: false,
classNames: 'scroller__title'
})
}}
{% endif %}
<div class="scroller__wrapper" style="{% if moduleConfig.backgroundColor %} --bgColor: {{ moduleConfig.backgroundColor }};{% endif %}{% if moduleConfig.backgroundImage %}background-image: url({{ moduleConfig.backgroundImage.paths.original }}); background-size: cover; background-position: center center; {% endif %}{% if moduleConfig.moduleHeight == 'fixed' %}--height: {{ moduleConfig.height }}px;{% endif %} --vertical-alignment: {{ moduleConfig.scrollerVerticalAlignment|default('center') }};">
<div class="scroller__content" style="color: {{ moduleConfig.textColor }}; --skew: {{ moduleConfig.sliderRotation }}deg;">
{{
scroller(scrollerItemsTemplate, {
id: "scroller-#{moduleInstance}",
scrollerConfig: scrollerSettings,
hasControls: moduleConfig.hasControls,
})
}}
</div>
</div>
</div>
{% endif %}
Macros reference¶
Webcomponents reference¶
Used styles¶
Module configuration schema¶
[
{
"label": "Content",
"state": "unfolded",
"elements": [
{
"name": "scrollerItemsRepeater",
"type": "repeater",
"label": "Manage slides with content",
"supportsTranslations": true,
"labelDescription": "Min. 1",
"isRequired": true,
"options": {
"defaultGroupLabel": "Slide",
"minActiveGroups": 1,
"maxActiveGroups": 20,
"elements": [
{
"name": "image",
"type": "imageUpload",
"hint": "The file name is important for SEO and should describe the content of the image. Use dashes to separate words.",
"options": {
"allowedExtensions": [
"webp",
"svg",
"jpg",
"png",
"gif",
"jpeg"
]
},
"label": "Image <<SVE>>",
"isRequired": false
},
{
"name": "imageAlt",
"type": "text",
"hint": "Alternative text (\"alt\" attribute) should contain a description of what the graphic presents. This description is read by software for the blind and analyzed when search engines index the page.",
"label": "Alternative image description (\"alt\")",
"isRequired": false
},
{
"name": "content",
"type": "wysiwyg",
"label": "Text editor content",
"isRequired": false
}
]
}
},
{
"name": "addHeading",
"type": "checkbox",
"label": "Display heading",
"isRequired": false,
"defaultValue": 0,
"children": [
{
"type": "text",
"name": "title",
"label": "Module heading content",
"supportsTranslations": 1,
"relations": [
{
"parentName": "addHeading",
"parentValueToActionsMap": [
{
"value": 0,
"actions": [
"setHidden",
"setDisabled",
"setOptional"
]
},
{
"value": 1,
"actions": [
"setVisible",
"setAvailable",
"setRequired"
]
}
]
}
]
}
]
}
]
},
{
"label": "General settings",
"state": "unfolded",
"elements": [
{
"name": "moduleHeight",
"type": "radio",
"label": "Module height",
"defaultValue": "automatic",
"options": {
"radioOptions": [
{
"key": "automatic",
"label": "automatic <<feminine>>",
"labelDescription": "adjusts to content"
},
{
"key": "fixed",
"label": "fixed",
"labelDescription": "fixed custom value"
}
]
}
},
{
"name": "height",
"type": "number",
"label": "Height",
"options": {
"postfix": "px"
},
"validators": [
{
"type": "int"
}
],
"relations": [
{
"parentName": "moduleHeight",
"parentValueToActionsMap": [
{
"value": "automatic",
"actions": [
"setHidden",
"setDisabled",
"setOptional"
]
},
{
"value": "fixed",
"actions": [
"setVisible",
"setAvailable",
"setRequired"
]
}
]
}
]
},
{
"name": "scrollerVerticalAlignment",
"type": "select",
"label": "Content position in module",
"defaultValue": "center",
"options": {
"selectOptions": [
{
"key": "start",
"label": "top <<at_the_top>>"
},
{
"key": "center",
"label": "center <<in_the_middle>>"
},
{
"key": "end",
"label": "bottom <<at_the_bottom>>"
}
]
},
"relations": [
{
"parentName": "moduleHeight",
"parentValueToActionsMap": [
{
"value": "automatic",
"actions": [
"setHidden",
"setDisabled",
"setOptional"
]
},
{
"value": "fixed",
"actions": [
"setVisible",
"setAvailable",
"setRequired"
]
}
]
}
]
},
{
"name": "slideImagePosition",
"type": "select",
"label": "Content layout in slide",
"defaultValue": "above",
"options": {
"selectOptions": [
{
"key": "above",
"label": "Image above content"
},
{
"key": "left",
"label": "Image on the left side"
},
{
"key": "right",
"label": "Image on the right side"
},
{
"key": "below",
"label": "Image below content"
}
]
}
},
{
"name": "direction",
"type": "select",
"options": {
"selectOptions": [
{
"key": "rtl",
"label": "To the left"
},
{
"key": "ltr",
"label": "To the right"
}
]
},
"label": "Scrolling direction",
"defaultValue": "rtl"
},
{
"name": "speed",
"type": "select",
"label": "Scrolling speed",
"isRequired": false,
"defaultValue": "1",
"options": {
"selectOptions": [
{
"key": "0.3",
"label": "Very slow"
},
{
"key": "1",
"label": "Slow"
},
{
"key": "2",
"label": "Medium"
},
{
"key": "3",
"label": "Fast"
}
]
}
},
{
"name": "hasControls",
"type": "checkbox",
"label": "Add pause/stop option",
"hint": "Content that scrolls automatically for more than 5 seconds must have a pause/stop option (EAA Directive).",
"isRequired": false,
"defaultValue": 0
},
{
"name": "sliderRotation",
"type": "number",
"label": "Content rotation",
"isRequired": false,
"defaultValue": 0,
"labelDescription": "0° - no rotation. From -3° (clockwise) to 3° (counterclockwise).",
"validators": [
{
"type": "int"
},
{
"type": "greaterEqThan",
"options": {
"min": -3
}
},
{
"type": "lessEqThan",
"options": {
"max": 3
}
}
],
"options": {
"postfix": "°"
}
},
{
"name": "headerMobile",
"type": "header",
"options": {
"icon": "phone"
},
"label": "Mobile",
"children": [
{
"name": "phoneElementsCountPerRow",
"type": "number",
"validators": [
{
"type": "int"
},
{
"type": "greaterEqThan",
"options": {
"min": 1
}
},
{
"type": "lessEqThan",
"options": {
"max": 24
}
}
],
"label": "Number of visible slides",
"labelDescription": "Max. 24.",
"defaultValue": 2
}
]
},
{
"name": "headerTablet",
"type": "header",
"options": {
"icon": "tablet"
},
"label": "Tablet",
"children": [
{
"name": "tabletElementsCountPerRow",
"type": "number",
"validators": [
{
"type": "int"
},
{
"type": "greaterEqThan",
"options": {
"min": 1
}
},
{
"type": "lessEqThan",
"options": {
"max": 24
}
}
],
"label": "Number of visible slides",
"labelDescription": "Max. 24.",
"defaultValue": 3
}
]
},
{
"name": "headerLaptop",
"type": "header",
"options": {
"icon": "laptop"
},
"label": "Laptop",
"children": [
{
"name": "laptopElementsCountPerRow",
"type": "number",
"validators": [
{
"type": "int"
},
{
"type": "greaterEqThan",
"options": {
"min": 1
}
},
{
"type": "lessEqThan",
"options": {
"max": 24
}
}
],
"label": "Number of visible slides",
"labelDescription": "Max. 24.",
"defaultValue": 3
}
]
},
{
"name": "headerDesktop",
"type": "header",
"options": {
"icon": "desktop"
},
"label": "Desktop",
"children": [
{
"name": "desktopElementsCountPerRow",
"type": "number",
"validators": [
{
"type": "int"
},
{
"type": "greaterEqThan",
"options": {
"min": 1
}
},
{
"type": "lessEqThan",
"options": {
"max": 24
}
}
],
"label": "Number of visible slides",
"labelDescription": "Max. 24.",
"defaultValue": 3
}
]
}
]
},
{
"label": "Background image",
"state": "folded",
"elements": [
{
"name": "backgroundImage",
"type": "imageUpload",
"hint": "The file name is important for SEO and should describe the content of the image. Use dashes to separate words.",
"options": {
"allowedExtensions": [
"jpg",
"png",
"webp",
"svg",
"gif"
]
},
"label": "Background image",
"isRequired": false
}
]
},
{
"label": "Module appearance",
"state": "unfolded",
"elements": [
{
"name": "textColor",
"type": "colorPicker",
"options": {
"allowVariables": true
},
"label": "Text color in module",
"isRequired": false,
"defaultValue": "@globalFontColor"
},
{
"name": "backgroundColor",
"type": "colorPicker",
"options": {
"allowVariables": true
},
"label": "Background color under content",
"isRequired": false,
"defaultValue": "@globalBodyBackgroundColor"
}
]
},
{
"label": "CSS",
"state": "unfolded",
"elements": [
{
"name": "classNames",
"type": "text",
"label": "CSS class",
"labelDescription": "Enter the class name without a dot at the beginning. You can add multiple classes by separating them with spaces."
}
]
}
]