Notice: Undefined index: order_next_posts in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 194

Notice: Undefined index: post_link_target in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 195

Notice: Undefined index: posts_featured_size in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 196

Code CSS on-scroll image animations

Recreate the popular zoom-in effect for images that is introduced as the user scrolls


Whether it’s for fun or to emphasise something serious, this sinister on-scroll effect can be used to capture the attention of your website viewers and to set the tone. With this in mind, there can be justified use of this effect for user experience design as well as using it from a graphic design perspective.

This animation effect makes use of HTML, CSS and JavaScript. This is important because CSS alone can’t be used to detect page-scrolling events, hence these interactions are managed with JavaScript while the default styling settings are defined in regular CSS. Note that for this Web Workshop we have placed both CSS and JavaScript in separate files so that the effect can be reused across multiple pages without any code duplication taking place.

The CSS filter property is fairly versatile and allows for many other options in addition to or instead of the greyscale property used in this tutorial.


Main page setup

The main page requires the standard HTML, head and body containers to be defined. This also enables us to insert the page components in the following steps in a way that keeps the JavaScript and CSS separate from the page body content.

CSS file linking

This HTML markup will link the files that the CSS and JavaScript code are contained in to the page so that the styling and functionality can be shared across multiple pages. It also enables us to keep the code clean by separating content, styling and functionality.

Content containers

Insert the sinister header and the main page content inside the page <body> tag. The sinister <header> contains the background photo image, an overlay image used for the zoom and a content container for the additional text content – in this case it’s a title.

Initiate page styling

Now that the HTML elements are in place, we can move to the styles.css file to start styling the page. We start this file with the default styling of the main page – mainly the page background and the <main> content container, which we want to use to ensure that the content is centred and has readable text.

Sinister styling

The header’s styling need to stretch across the page and have a visible height. It will also need to hide any overflow from the zooming images we are using. Images and the content container will be posited at the top left of the <head>, which is made possible with the header using relative positioning.

$(window).on('scroll', header{
display: block;
position: relative;
height: 100%;
text-align: center;
overflow: hidden;
margin-top: 25%;
header h1{
font-size: 6em;
color: #c00;
text-shadow: 2px 2px #000
header img,
header .content{
position: absolute;
top: 0;
left: 0;
margin: 0 auto 0 auto;
width: 100%;}

Style individual images

There are two images used in our layout – the first being the main photo image and the other being the sinister zoom overlay. We’ve avoided overcomplicating the HTML with class name and instead are using their position in the <header> container to define positioning styles.

$( "#header" ).click(function() {
if (menuOn == false){
$('#menu').animate({"bottom": -100}, 500 );
menuOn = true;
} else {
$('#menu').animate({"bottom": "-100%"}, 500 );
menuOn = false;

Initiate listening code

With the styling now complete, we are ready to add the code to trigger changes as the page scrolls. This is achieved by adding JavaScript code that waits for a page-scroll event. We put this inside another listener for the completion of the page loading to avoid an error.

Activate image zooming

The sinister effect is primarily made from two animations – the main picture made bigger and the overlay made smaller to focus its inverted transparent circle around the image. We use a query selector to target the images to apply sizing and positioning calculations based on the scroll position.

document.querySelector("header img").style.width = (100+(window.scrollY/20))+"%";
document.querySelector("header img").style.left = (0-(window.scrollY/50))+"%";
if(-200+(window.scrollY/3) < -10){
document.querySelector("header img:nth-child(2)").style.width = (500-(window.scrollY/1.5))+"%";
document.querySelector("header img:nth-child(2)").style.left = (-200+(window.scrollY/3))+"%";
if(-180+(window.scrollY/3.5) < -20)document.querySelector("header img:nth-child(2)") = (-180+(window.scrollY/3.5))+"%";

More sinister colouring

The effect can be made to look more sinister by making the main photo change from full colour to black and white as the sinister effect takes place. This can be done by using the scroll position to affect the greyscale property. For the full code on this tutorial, make sure that you check our FileSilo site.