Drupal 8 jQuery Background Image Slider

by: Preston Schmidt

Drupal 8 is Here, Let's Make a Background image Slider

This was initially built using paragraphs for Drupal 8, but this code can go in any .html.twig template file. I have included the script in the same file to make this a little more portable and re-usable as well.

In the first code block below you will find the twig markup and the script that creates all the behavior. In the second code block you will find the accompanying CSS that makes it all look pretty. Edit this code as needed for your own project!

This is not your traditional slider and is not meant to be used as a CTA to many different pages. Think of this more as a visually interactive image hero or page banner.

What Does this Drupal 8 Background Slider Do?

  1. This prints the URI's of the images in the Drupal image field into a data attribute in the DOM.
  2. It then collects the data attribute as a list of image URI's and sets them as a CSS background image to the background slider div.
  3. It provides a slider bar at the bottom that visualizes the progress of the slider.
  4. It has a changing background color array where HEX codes can be set in the jQuery script to replicate your branding guidelines.
  5. It hides and shows the paragraph text for each item in the slider.

What You Need to Set Up in Drupal 8

If you're using paragraphs for Drupal 8:

  1. Create a paragraph named 'Background Image Slider'.
  2. Add a field called 'Background Image' and set its limit to unlimited in the field settings.
  3. Add a field called 'Background Image Slider Body' and set its limit to unlimited in the field settings.
  4. Add a field called 'Background Image Slider Title' and set its limit to 1.
  5. Make sure under manage display of the paragraph settings to hide all the labels for these fields.
  6. Create a file in your theme directory called 'paragraph--background-image-slider.html.twig (I like to keep my paragraph templates in their own sub-folder).
  7. Copy the contents of the first code block below (with the twig markup) into the newly created template file.
  8. Copy the content from the second code block below (with the CSS) into your site's stylesheet.
  9. Clear Drupal cache.
  10. Next you will have to add that paragraph to a page on your site and enter content/data into the fields.

If you're NOT using paragraphs for Drupal 8 and just using a content type and template file:

  1. Create a content type of any name you'd like.
  2. Add a field called 'Background Image' and set its limit to unlimited in the field settings.
  3. Add a field called 'Background Image Slider Body' and set its limit to unlimited in the field settings.
  4. Add a field called 'Background Image Slider Title' and set its limit to 1.
  5. Make sure under manage display of the paragraph settings to hide all the labels for these fields.
  6. Create a file in your theme directory named 'node--content-type-name-here.twig.html ('content-type-name-here' will be the name of the content type you created).
  7. Copy the contents of the first code block below (with the twig markup) into the newly created template file.
  8. Copy the content from the second code block below (with the CSS) into your site's stylesheet.
  9. Clear Drupal cache.
  10. Next you will have to create a page of that content type and add some content/data to the fields.

If you are having troubles, check to make sure field names in the paragraph match what's in your new template file.

Note: This is Drupal 8 so make sure that jQuery is actually loading on the page or this will not work.

The Markup and Script:

{% set backgroundImageList %}

    {% for item in content.field_background_image['#items'] %}
            {{file_url(item.entity.uri.value)}},
    {% endfor %}

{% endset %}

<section class="background-slider" data-background-image-list="{{backgroundImageList}}">

    <div class="background-slider-overlay"></div>
    
    <h2>{{content.field_background_image_slider_ti}}</h2>
    {% for item in content.field_background_image_slider_bo['#items'] %}
        <p class="background-slider-paragraph" data-loop-index="{{ loop.index }}">{{item.value}}</p>
    {% endfor %}
    
    <div class="slider-progress-bar-wrapper"><div class="slider-progress-bar"></div></div>
    
</section>

<script>
    (function($) {

        $(document).ready(function () {

            //** Background Image Slider **//
            //Set Variables
            var backgroundImageSlider = $('.background-slider');
            var backgroundSliderOverlay = $('.background-slider-overlay');
                        
            //Create image URL array and variables
            var backgroundImageData = backgroundImageSlider.attr('data-background-image-list');
            var backgroundImageList = backgroundImageData.split(',');
            var backgroundImageCount = backgroundImageList.length -1;
            var backgroundImageLast = backgroundImageCount -1;
            
            //Create the pargraph array variables
            var backgroundParagraphSlider = $('p.background-slider-paragraph');
            var paragraphDataList = backgroundParagraphSlider.attr('data-loop-index');
            var paragraphDataLength = backgroundParagraphSlider.length;
            var backgroundParagraphDataIndex = paragraphDataLength;
            
            //Create Background Colors Array
//you can edit these colors
            var backgroundColors = ['ca1404', '2d7eee', '333333'];
            var backgroundColorsIndex = 0;
            
            //Set progress bar width
            var progressBar = $('.slider-progress-bar');
            var progessBarWidthSection = 100 / backgroundImageCount;
            progressBar.css('width', progessBarWidthSection + '%');
            
            
            //Loop through the image URL's array and Background color array
            var delayTime = 0;
            
            (function theLoop (i) {
                setTimeout(function () {
                    backgroundImageSlider.attr('style', 'background-image: url(' + backgroundImageList[i - 1] + ')');
                    backgroundSliderOverlay.css('background', '#' + backgroundColors[backgroundColorsIndex]);
                    progressBar.css('left', 100 - (progessBarWidthSection * i) + '%');
                    progressBar.css('background', '#' + backgroundColors[backgroundColorsIndex]);
                    backgroundParagraphSlider.each(function () {
                        $(this).addClass('moveSliderParagraph');
                        if ($(this).attr('data-loop-index') == backgroundParagraphDataIndex) {
                            $(this).removeClass('moveSliderParagraph');
                        }
                    });

                    delayTime = 6000;

                    if (backgroundColorsIndex == backgroundColors.length - 1) {
                        backgroundColorsIndex = 0;
                    } else {
                        backgroundColorsIndex++;
                    }
                    if (backgroundParagraphDataIndex == 1) {
                        backgroundParagraphDataIndex = paragraphDataLength;
                    } else {
                        backgroundParagraphDataIndex--;
                    }
                    
                    if (--i) {
                        theLoop(i);
                    }
                    if (i == 0) {
                        i = backgroundImageCount;
                        theLoop(i);
                    }
                }, delayTime);
            })(backgroundImageCount);
            
        });

    }(jQuery));
</script>

The Styles:

.background-slider {
    width: 100%;
    position: relative;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    border-top: none;
    border-bottom: none;
    -webkit-transition: background ease .5s;
    -moz-transition: background ease .5s;
    -o-transition: background ease .5s;
    transition: background ease .5s;
    overflow: hidden;
}

.background-slider-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0.7;
    -webkit-transition: background ease .5s;
    -moz-transition: background ease .5s;
    -o-transition: background ease .5s;
    transition: background ease .5s;
}

.background-slider h2 {
    font-size: 250%;
    padding: 20% 40px 25% 40px;
    color: #fff;
    text-align: center;
    position: relative;
    z-index: 20;
}

.background-slider p {
    font-size: 140%;
    color: #fff;
    text-align: center;
    padding: 40px;
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background: rgba(0, 0, 0, 0.5);
    -webkit-transition: all ease .2s;
    -moz-transition: all ease .2s;
    -o-transition: all ease .2s;
    transition: all ease .2s;
}

.background-slider p.moveSliderParagraph {
    bottom: -30%;
}

.slider-progress-bar-wrapper {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 10px;
    background: rgba(255, 255, 255, 0.6);
}

.slider-progress-bar {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 0;
    background: #ca1404;
    opacity: 0.7;
    -webkit-transition: all ease .6s;
    -moz-transition: all ease .6s;
    -o-transition: all ease .6s;
    transition: all ease .6s;
}

@media screen and (max-width: 800px) {
    
    .background-slider {
        height: auto;
        padding-bottom: 0;
        padding: 40px;
    }
    
    .background-image-slider-content {
        position: static;
        -webkit-transform: none;
        -moz-transform: none;
        -o-transform: none;
        transform: none;
    }
    
}

Outlier

Video, Web, and Design Agency