Web Developer, JavaScript

How To Asynchronously Load And Fade Images With CSS And jQuery

One of the easiest way to improve the aesthetics of the web page is to add images. We can asynchronously load the images for better performance. Here we will learn how to asynchronously load images and fade the image in with CSS and jQuery.
Published: 04/28/2022 8:44 am
Updated: 04/28/2022 9:03 am
#load image #async image #fade in image #css #html #js #jquery
April 2022 | Work Heavy

Overview

A web page needs to not only function well, but also look good. One of the easiest way to improve the aesthetics of the web page is to obviously add images. Better quality images can mean bigger file sizes, which means longer load times, so how do we prevent the page from taking a super long time to load? We can asynchronously load the images. Here we will learn how to asynchronously load images and fade the image in with CSS and jQuery. We'll also apply this to both the img element and a div element. If you just want the source code, you can find that here

Create HTML File for Demo

First let's create the basic HTML file for this demo. Below is just a simple web page with some initial CSS and DIVs. The class demo-container is just for the sake of demo not for the grid. The my-async-img class is our main class for the asynchronously loaded images, which we will populate later. Then we have some basic HTML in the body, just a div with the demo-container class with 2 child elements. One is an img with the my-async-img class and a div with the my-async-img class. These two elements will be where our images display.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Image Fade In Example</title>

        <style>
            .demo-container{
                -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
                -moz-box-sizing: border-box;    /* Firefox, other Gecko */
                box-sizing: border-box;         /* Opera/IE 8+ */
                width:100%;
                padding: 10px;
            }

            .my-async-img{

            }



        </style>
    </head>
    <body>

    <div class="demo-container">
        <img class="my-async-img" />
        <div class="my-async-img" ></div>
    </div>

    </body>
</html>

Adding the CSS

In order to asynchronously load our images and fade them in, we actually don't need too much CSS. The main property we need is opacity because that is what we will animate to fade in the image. Since we are also making this usable for divs, we add a few background properties, but these can be adjusted per your preference. THen the height, width, and display are more so just for this demo.

    <head>
        <meta charset="UTF-8">
        <title>Image Fade In Example</title>

        <style>
            .demo-container{
                -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
                -moz-box-sizing: border-box;    /* Firefox, other Gecko */
                box-sizing: border-box;         /* Opera/IE 8+ */
                width:100%;
                padding: 10px;
            }

            .my-async-img{
                background-repeat: no-repeat;
                background-size: cover;
                background-position: center;
                opacity: 0;
                height:400px;
                width:400px;
                display: inline-block;
            }



        </style>
    </head>
    <body>

    <div class="demo-container">
        <img class="my-async-img" />
        <div class="my-async-img" ></div>
    </div>
    </body>
    

Adding the Attributes

Now to make everything easily communicate with the Javascript, we will add a few attributes to the elements that need an image loaded. First we add the data-my-async-img attribute which will simply be the iamge url. Then we have the optional attribute data-my-anim-duration which is a time input for how long we want the fade in animation to take.

    <div class="demo-container">
        <img class="my-async-img" data-my-async-img="/workheavy-web-dev-examples/img/lizard.png"/>
        <div class="my-async-img" data-my-async-img="/workheavy-web-dev-examples/img/lizard.png" data-my-anim-duration="5000"></div>
    </div>
    

Adding the JavaScript

In order to asynchronously load our images, we will need to use JavaScript. Let's add a place for it on our demo page at the end of the body element. We also will need to use jQuery so grab a CDN link here and add it to the head of the demo page.

    <head>
        <meta charset="UTF-8">
        <title>Image Fade In Example</title>

        <!-- jQuery library -->
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

        <style>
            .demo-container{
                -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
                -moz-box-sizing: border-box;    /* Firefox, other Gecko */
                box-sizing: border-box;         /* Opera/IE 8+ */
                width:100%;
                padding: 10px;
            }

            .my-async-img{
                background-repeat: no-repeat;
                background-size: cover;
                background-position: center;
                opacity: 0;
                height:400px;
                width:400px;
                display: inline-block;
            }



        </style>
    </head>
    <body>

    <div class="demo-container">
        <img class="my-async-img" />
        <div class="my-async-img" ></div>
    </div>

    <script>
        // our JavaScript will go here
    </script>
    </body>
    

Now we will add the main functionality of our JavaScript. First we have a simple if statement to detect if we have jQuery loaded or not. This will help prevent any unnecessary crashes. Next we define our async image load function. This function will find all our are images that need to load, load them, then fade them in. Inside the function we grab each element with the data-my-sync-img attribute. This is how we can easily determine which images to async load or not. Once we have the element, we grab the data-my-async-img attribute and the data-my-anim-duration attribute (no need to include the data prefix). Next we load the image via JavaScript. Upon successful load, we set the element image src or background image, then animate the opacity. That is all the core functionality to loading and fading the image. After defining asyncImageLoad we then simply call it after page load. You can modify this to load images at any point you want. Perhaps you want a person to click a button first, no problem, simply call asyncImageLoad from within the button click handler.

    <script>
        if (window.jQuery) {

            window.asyncImageLoad = function (){

                jQuery('[data-my-async-img]').each(function() {

                    // helper
                    let element = jQuery(this);

                    // get atts
                    let img = element.data("my-async-img");
                    let duration = element.data("my-anim-duration");
                    if(duration === null || duration === undefined){
                        duration = 500;
                    }

                    // new image
                    let newImage = new Image();

                    // after img load
                    newImage.onload = function () {
                        if(element.is('img')){
                            element.attr("src",this.src);
                        }else{
                            element.css('background-image', 'url(' + this.src + ')');
                        }
                        // fade
                        element.animate({ opacity: 1 }, { duration: duration });
                    };

                    // set src
                    newImage.src = img;

                });
            };

            jQuery(document).ready(function() {
                window.asyncImageLoad();
            });


        }else{
            console.error("Oh no! You need jQuery for this to work.")
        }
    </script>
    

Summary

Now you can easily asynchronously load images and fade the image in with CSS and jQuery. Whether it is a img or a div, you can make your web pages load faster and have create them more visually appealing. For complete demo source, you can find the code here.

Image Fade In on HTML page
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Image Fade In</title>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

    <style>
        .demo-container{
            -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
            -moz-box-sizing: border-box;    /* Firefox, other Gecko */
            box-sizing: border-box;         /* Opera/IE 8+ */
            width:100%;
            padding: 10px;
        }

        .my-async-img{
            background-repeat: no-repeat;
            background-size: cover;
            background-position: center;
            opacity: 0;
            height:400px;
            width:400px;
            display: inline-block;
        }


    </style>
</head>
<body>

<div class="demo-container">
    <img class="my-async-img" data-my-async-img="/workheavy-web-dev-examples/img/lizard.png"/>
    <div class="my-async-img" data-my-async-img="/workheavy-web-dev-examples/img/lizard.png" data-my-anim-duration="5000"></div>
</div>
<script>
    if (window.jQuery) {

        window.asyncImageLoad = function (){

            jQuery('[data-my-async-img]').each(function() {

                // helper
                let element = jQuery(this);

                // get atts
                let img = element.data("my-async-img");
                let duration = element.data("my-anim-duration");
                if(duration === null || duration === undefined){
                    duration = 500;
                }

                // new image
                let newImage = new Image();

                // after img load
                newImage.onload = function () {
                    if(element.is('img')){
                        element.attr("src",this.src);
                    }else{
                        element.css('background-image', 'url(' + this.src + ')');
                    }
                    // fade
                    element.animate({ opacity: 1 }, { duration: duration });
                };

                // set src
                newImage.src = img;

            });
        };

        jQuery(document).ready(function() {
            window.asyncImageLoad();
        });


    }else{
        console.error("Oh no! You need jQuery for this to work.")
    }

</script>
</body>
</html>