In this tutorial, you will learn how to do a cool sticky image effect, where the sticky images change on one side while you scroll through the text. Let’s see how to do that using Elementor and pure CSS – no JavaScript or plugins!
Watch the video below or scroll down to grab the CSS code used!
First, add your containers (using Flexbox in Elementor)
We are using flexbox containers in Elementor Pro, so fist add a new container (let’s call it container A) and make sure that the items inside are stacked vertically (as they probably will already be by default). To do so, go to Layout > Items > Direction and check the vertical down arrow.
Inside this container, create another container (let’s call it container B). This container will be the box that will hold our first slide – including our image in the left column and text on the right side.
Use the Structure or Navigator to organize your widgets! We will call this first container B “First slide” in the Structure panel. Right-click anywhere on your Elementor page and go to “Structure” to open the Navigator sidebar.
You can then change the name of this container in the Structure panel to “First slide”.
Inside this container, you will create two containers – one for each column. The left container will hold our image and the right one will hold our text (or multiple widgets). Set the stacking to horizontal (or rows).
Add the content for the first slide
In the left column (container), add the image widget, select your image and give this image widget a class “first-screen“.
Don’t know where to add a CSS class? Check below:
The Elementor settings we will be adjusting for these image widgets for each screen are: adding CSS classes, z-index and motion effects (sticky, sticky offset and effects offset).
In the right column, add your widgets like text, heading or whatever you need.
Set the image to sticky
Select the image widget on the left and in the ‘Advanced’ > Motion effects > set it to “Sticky” (Top). Then, apply the sticky effect on desktop only (remove mobile and tablet) and set the sticky offset to something like 200.
This sticky offset is the value in pixels that basically represents the distance between the top of your sticky image and the top of your viewport.
You then have to set the effects offset.
The effect offset value will depend on your section height and your image height and you should experiment with this value to find the best that fits. It should approximately be your slider section (or image) height + some default or set paddings on top and bottom and row gaps between the containers. You can use Inspect elements to find the exact or approximate height. Let’s say that your image height is something like 375px – in that case you can try with something like 420px depending on these gaps and paddings.
Try different values for the effects offset to find the proper value – it doesn’t have to be pixel perfect and the effect will still work!
Lastly, set the z-index of this image widget to 2 for example.
Duplicate the container B (first slide)
Next, duplicate the container for the first slide (remember how we named this container in the Structure or Navigator panel for better organization?) to create the second slide.
Change your image and your text as necessary and change the class of your image widget here to “middle-screen“.
We are supposing that you have at least 3 images and 3 scrolling sections.
In the Advanced panel under Motion effects, use the same sticky offset and effects offset like for the first screen – no need to change anything here!
Set the z-index of this image widget to something bigger than the first image z-index, for example 3.
Duplicate this middle screen (container B) to create as many middle slides as needed
These will be the slides in the middle – not the last slide! We will style that one below.
Finally, duplicate this container B to create the last slide
Change the class of the image widget in this last container to class “last-screen“.
This is how our final container structure looks like now:
In Advanced > Motion effects, leave the sticky offset to 200 (it should be the same for all the images!), but remove the effects offset. Set this effects offset to 0 and toggle the ‘Stay in Column’ to ‘Yes’.
This will make sure that after we are done scrolling with text, this last image continues scrolling with it and we move on to the next section on our page.
If the image is showing below the previous slide image, make sure that the z-index of this last image has the highest value – for example 5.
Publish the changes and add the CSS code!
Now that we’ve set up our structure and added the sticky effects in Elementor, it’s time to add the CSS code that will actually create this effect.
I am using Simple Custom JS and CSS plugin.
If you were using the same CSS class names like I did above, add this code below and keep on reading to see what exactly each line means!
Note – try using the !important tag if needed!
/* General styling for the slider images */
.first-screen img,
.middle-screen img,
.last-screen img{
border-radius: 25px;
}
@media (min-width: 1025px){
.first-screen{
opacity: 1;
-moz-transition: opacity .025s ease-out;
-webkit-transition: opacity .025s ease-out;
transition: opacity .025s ease-out;
}
.middle-screen,
.last-screen{
opacity: 0;
-moz-transition: opacity .025s ease-out;
-webkit-transition: opacity .025s ease-out;
transition: opacity .025s ease-out;
}
.elementor-sticky--active.middle-screen,
.elementor-sticky--active.last-screen{
opacity: 1;
}
/* Sticky - effects offset behavior once it's reached */
.elementor-sticky--effects.first-screen,
.elementor-sticky--effects.middle-screen{
opacity: 0;
}
How does this CSS work?
Let’s break down the code above line by line to see how it actually makes this sticky or fixed, pinned image effect on one side and how these sticky images change in one column while we are scrolling through the text.
Target only the desktop devices
First, we are using media query to apply this effect only on desktop devices.
@media (min-width: 1025px){
}
Next, set the default opacity for the first-screen class
Then, we want to toggle the opacity of our images at different sticky states and moments to create the effect.
We are starting by setting the default opacity for our first image (with the class first-screen) to 1. That means that by default, as we start scrolling through our page, this image will appear as it normally would without the sticky effect.
.first-screen{
opacity: 1;
}
Set the transition property
Since we will be changing the opacity of our images at different states, we want to set the transition property to control how this opacity changes when it switches from 1 to 0 or vice versa.
Let’s add this transition to our class, including -moz-transition and -webkit-transition to make sure we are compatible with all browsers.
Note that in this example, we are using a hard transition and a very short transition time (.025s). If you want to create a more subtle and softer effect where the image slowly fades into the next one, try using a different value. For example 0.2s or 0.5s.
This is how our class first-screen will look like:
.first-screen{
opacity: 1;
-moz-transition: opacity .025s ease-out;
-webkit-transition: opacity .025s ease-out;
transition: opacity .025s ease-out;
}
Adjust the classes for the middle screen images and the last image
In the next step, you want to apply similar styling to the middle-screen and last-screen classes.
These images will have the default opacity set to 0, because we want them to appear only AFTER we are done scrolling with the first section and after a defined threshold is reached.
.middle-screen,
.last-screen{
opacity: 0;
-moz-transition: opacity .025s ease-out;
-webkit-transition: opacity .025s ease-out;
transition: opacity .025s ease-out;
}
Make the middle screen and last screen images appear on scroll
Now you want to set the opacity of the middle screen and last screen images to 1 to make them show up on scroll. To do that, we want to modify the elementor-sticky–active class that will target these elements when the sticky effect is active.
.elementor-sticky--active.middle-screen,
.elementor-sticky--active.last-screen{
opacity: 1;
}
Finally, “hide” the images once we are done scrolling in that particular section
The last thing that’s left to do is to now “hide” the images when we are done scrolling in their section. That means that once we reach the effects offset that we previously set in Elementor Motion effects, those images should disappear. In this way, we will make sure that as we are scrolling through the next section, the images from the previous one won’t end up showing up fixed in the background, but will “disappear” once we are done with them.
To achieve this, we will use the elementor-sticky–effects class, apply it only to the first-screen and middle-screen images and set their opacity to 0.
.elementor-sticky--effects.first-screen,
.elementor-sticky--effects.middle-screen{
opacity: 0;
}
That’s it!
Now you’ve successfully created this sticky image effect where the text in one column is moving on scroll, but the images stay fixed (pinned) on one side and change as we scroll through each section.
online course
free 30min consultation
Ready to Learn CSS?
A step-by-step basic online course for beginners and non-coders with 50+ practical exercises to get you started with CSS.
- No HTML
- Interactive
- For non-coders