Add Parallax Blocks to Drupal 8 With ScrollMagic

Add Parallax Styled Blocks to Your Drupal 8 Theme

In this tutorial, I will explain how to use custom block types to create a Parallax effect in your Drupal 8 subtheme.

To follow along with these steps, it would help to have a good understanding of Drupal 8 theming. You can click here to take our Drupal 8 Theming Class.

To be able to follow this tutorial, you also need to install Bootstrap and create a subtheme from the CDN folder. You can follow our guide here in our earlier post.

Step #1. Configure the Bootstrap theme

Parallax effects are usually full width so you need to turn on Fluid container option from the Bootstrap theme menu.

  • Go to “Appearance” and make sure the Bootstrap theme is set as default.
  • Enter the Bootstrap theme settings and select the Container drop-down.
  • Check the box for “Fluid container”.
  • Click “Save configuration”.


Step #2. Create blocks

Now you need to make some custom blocks for the display. By using custom blocks you can theme the blocks specifically.

  • Go to Structure > Block layout > Types.
  • Click “Add custom block type”.


  • Label the custom block “Parallax”:


  • Now go to “Add custom block” and create two blocks, one for each of the images you are using. I called these blocks Parallax 1 and Parallax 2.
  • Set the region to content and save the blocks.


Now you need to use the custom basic blocks to display content between the images on the block layout page. Also, remove any blocks you have placed in the sidebars as this will prevent the width being 100%.


Step #3. Enable debugging

  • Now turn on debugging if you don’t already have it enabled.
  • Go to sites/default and copy and rename to services.yml on line 58 change debug to true:


  • Now, to be able to see the theme suggestions, add this code to your subtheme.theme file:
/**  * Implements hook_theme_suggestions_HOOK_alter() for form templates.  * @param array $suggestions  * I found this code on  * @param array $variables  */ function subtheme_theme_suggestions_block_alter(array &$suggestions, array $variables) {     // Block suggestions for custom block bundles.     if (isset($variables['elements']['content']['#block_content'])) {         array_splice($suggestions, 1, 0, 'block__bundle__' . $variables['elements']['content']['#block_content']->bundle());     } }
  • The function name needs to match your theme name. Adding this to your theme file allows you to theme custom blocks.
  • Flush all caches and if you inspect the site now you should see theme suggestions.
  • In Google Chrome, right click on the region and select Inspect to access the inspector tool:


  • Add the template suggestion for parallax block in your templates theme folder subtheme/templates/block–bundle–parallax.html.twig
  • Add this code to the template file:
<div class="parallax parallax--{{ elements['#id'] }}">     <div class="parallax__bg"></div>     <div class="parallax__content">         <h2{{ title_attributes }}>{{ label }}</h2>         {{ content['body']['0']['#text'] | raw}}     </div> </div> 
  • This code will style the parallax custom block you created. If you need to debug this you can use kint from the Devel module.

Step #4. Style the blocks

Now you need to add the CSS to style the blocks.

  • Open your /css/style.css and add this code:
.main-container, .page-header {    padding: 0px; }  .block-block-content2b3d7746-776f-484c-8686-c0e00a3978b6 {    text-align: center;    padding: 10em;    font-size: 20px;    background-color: #204d74;    color: #fff; }  .parallax {    text-align: center;    position: relative;    overflow: hidden;    height: 500px; }  .parallax__bg {    position: absolute;    width: 100%;    height: 140%; }  .parallax--parallax1 .parallax__bg {    background: url('../images/yourimage'); }  .parallax--parallax2 .parallax__bg  {    background: url('../images/yourimage'); }  .parallax__content {    position: relative;    top: 50%;    -webkit-transform: translateY(-50%);    -ms-transform: translateY(-50%);    transform: translateY(-50%);    color: #fff;    h2 {      margin: 0px;      font-size: 30px;    }    p {      font-size: 20px;    } }
  • You will need to update  .block-block-content2b3d7746-776f-484c-8686-c0e00a3978b6 to match your block:


This is the class assigned to your custom block. If you named your Parallax block differently, you will have to update .parallax–parallax1 and .parallax–parallax2.

Step #5. Add the images and ScrollMagic

  • Go to your theme and create a folder called /images/. This is where you will save the images for the parallax effect.
  • Add some Javascript to make the images move slightly. For this, you will use ScrollMagic. Download and extract the files from GitHub:


  • Now go to your theme and create a folder called /js/ and move these files into the folder
    • animation.gsap.min.js
    • ScrollMagic.min.js
    • TweenMax.min.js
  • Now you need to add our custom js add parallax.js
  • You now need to tell the theme to load the js libraries. To do that, open subtheme/subtheme.libraries.yml:
global-styling:   css:     theme:       css/style.css: {}    js:     js/ScrollMagic.min.js: {}     js/animation.gsap.min.js: {}     js/TweenMax.min.js: {}     js/parallax.js: {}   dependencies:     - core/drupal     - core/jquery 
  • And finally, add this code to your parallax.js file:
(function ($) {     'use strict';     Drupal.behaviors.myBehavior = {         attach: function (context, settings) {              var controller = new ScrollMagic.Controller();              var blocks = [".parallax--parallax1", ".parallax--parallax2"];              blocks.forEach(function (block, index) {                  var $bg = $(block).find('.parallax__bg');                 var $content = $(block).find('.parallax__content');                  var tl = new TimelineMax();                 tl                     .from($bg, 2, {y: '-40%', ease: Power0.easeNone}, 0)                     .from($content, 1, {autoAlpha: 0, ease: Power0.easeNone}, 0.4)                 ;                  var scene = new ScrollMagic.Scene({                     triggerElement: block,                     triggerHook: 1,                     duration: "100%"                 })                 .setTween(tl)                 .addTo(controller);             });         }     } }(jQuery));
  • Make sure the images you are using are big enough for the max width you want to display.
  • And now you should have a nice scrolling effect that you have applied only to our custom blocks:


0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
Hamza Zia
Hamza Zia
6 years ago

Parallax effect makes everything better 😉

Steinar Jordan
Steinar Jordan
6 years ago

I followed your tutorial and got the desired effect. Thanks!
However, there is a very similar tutorial to yours (with Video). In the other example the Main Header stays Static (non-disappearing), while in yours the Header disappears with the Scrolling.
As I followed yours mostly, I have a disappearing Header… could you (or helpful kibitzer) explain how to make the Header Static?


Steinar Jordan
Steinar Jordan
6 years ago

Hi All,
Answering my own question: Here is how you make the Header Static (non-disappearing).
Above I am mimicking the terminology I used in my original post, however, it seems that ‘Static’ does not mean (to Bootstrap) ‘non-disappearing’. And instead of ‘Header’ they use ‘Navbar’. Not a big deal, but it will make this a little more complicated to follow… oh well.
Under the ‘Settings’ for your subtheme theme (or for the parent Bootstrap theme) select the ‘Components’ vertical tab. Then change the ‘Navbar Postion’ value to “Fixed Top”. And the Header (Navbar) is Fixed (non-disappearing) at the top. I tried “Static Top” and it did not have the desired effect, hence I used that word differently than they.
As you may have inferred by now, this is not dependent upon anything related to the Parallax effect. That is, I created a normal Page with a large amount of Lorem Ipsum so that the Fixed vs Disappearing Navbar difference was expressed here too, with no aspect of the Parallax being invoked.
If anyone is reading this, I would still like to know what it is called when the an alternate (often abbreviated) Navbar flies in to replace the original as the Scrolling begins… and how to do that whatever it is called.


6 years ago
Reply to  Steinar Jordan

Thanks for posting that solution, Brad

2 years ago
Reply to  Steinar Jordan

I have this same problem and looking for a solution for it

David Dowell
David Dowell
6 years ago

Got this up and running great, thank you! Next I’d like to somehow set up where a user can add/edit the images instead of needing to send them to me so I can edit them in the css. Any tips or pointers on how that could be managed?

David Dowell
David Dowell
6 years ago
Reply to  David Dowell

I’ve implemented at least a starter solution to my question above and wanted to share. I simply named the images “image1”, “image2”, “image3” with instructions to name replacement images as such, then I created a simple view to show the current parallax images that users can edit, and then remove and replace each image as they choose. The only bump is that users have to remember to rename the images themselves to be image1.jpg (case-sensitive jpg, png, etc.). Thanks again for the great tutorial!!

Andrey Berrocal
Andrey Berrocal
6 years ago

Hi I follow this tutorial, and with great success I have the parallax effect, but I notice when I use on mobile or tablet, the background image doesn’t scale properly. I tried with a boostrap class “img-responsive” but it doesn’t work. Do you know how to fix this issue?

6 years ago


I followed the tutorial below to create a parallax effect on the home page of my site.

The parallax effect works very well for the anonymous user.
comment image

When I log in with a user or administrator, the parallax effect does not work and white space is displayed between the blocks.

I do not understand where the problem comes from. An idea ?
comment image

6 years ago
Reply to  Mathieu

Hi Mathieu, what happen if you try with another height dimension of the picture?

5 years ago
Reply to  Andrey

I had the same problem. Wrap the JS Code in a $(document).ready(function () { }); It works for me.

5 years ago

Dont work for me. Any help please, i do all the steps and finally appears the space with the text and no images…

5 years ago
Reply to  Diego

The images do not appear to me the same as what happens to Diego

3 years ago

or… use the context module.
just a checkbox to check.

Would love your thoughts, please comment.x