DEV Community 👩‍💻👨‍💻

Cover image for Responsive Image Gallery like Shutterstock, Pixabay and Adobe Stock using HTML CSS & JavaScript
Krishnasoni007
Krishnasoni007

Posted on

Responsive Image Gallery like Shutterstock, Pixabay and Adobe Stock using HTML CSS & JavaScript

🖐 Hello Guys!
In this post I will show you how to create image gallery like adobe stock and pixabay in very easy steps.
Live Demo
Git Repository

Let's see how it looks like

Responsive image layout or image gallery
We will create this layout in two easy steps:

  1. Creating the basic html and css layout

  2. Applying Javascript

    Creating basic html and css layout

    Start with html. In this code block I create heading and a main div inside this main div I created img div which contain an image and it's title

<body>
    <h1>My Favourite Anime List</h1>
    <div id="main">
        <div class="img"><img src="images/yourname.jpg" alt="yourname">
            <p>yourname</p>
        </div>
        <div class="img"><img src="images/dragon_ball_z.jpg" alt="dragon ball z">
            <p>dragon ball z</p>
        </div>
        <div class="img"><img src="images/your_lie_in_april.jpg" alt="your lie in april">
            <p>your lie in april</p>
        </div>
        <div class="img"><img src="images/grave_of_the_firefiles.jpg" alt="grave of the firefiles">
            <p>grave of the firefiles</p>
        </div>
        <div class="img"><img src="images/naruto.jpg" alt="naruto">
            <p>naruto</p>
        </div>
        <div class="img"><img src="images/demon_slayer.jpg" alt="demon slayer">
            <p>demon slayer</p>
        </div>
        <div class="img"><img src="images/spirited_away.jpg" alt="spirited away">
            <p>spirited away</p>
        </div>
        <div class="img"><img src="images/weathering-with-you-anime.jpg" alt="weathering with you anime">
            <p>weathering with you anime</p>
        </div>
        <div class="img"><img src="images/i_want_to_eat_your_pancreas.jpg" alt="i want to eat your pancreas">
            <p>i want to eat your pancreas</p>
        </div>
        <div class="img"><img src="images/spyxfamily.jpg" alt="spyxfamily">
            <p>spyxfamily</p>
        </div>
        <div class="img"><img src="images/death_note.jpg" alt="death note">
            <p>death note</p>
        </div>
    </div>
</body>
Enter fullscreen mode Exit fullscreen mode

Now css to give it better look and make it responsive.
In this css I use flexbox to make all images inline.
As our layout image height is fix an width is auto as image orientation.
I use simple fade effect on hover to show the title of and image.

 @import url('https://fonts.googleapis.com/css2?family=League+Spartan:wght@100;200;300;400;500;600;700;800;900&display=swap');

        * {
            margin: 0px;
            padding: 0px;
        }

        body {
            font-family: 'League Spartan', sans-serif;
        }
        /* css for main div  */
        #main {
            display: flex;
            flex-wrap: wrap;
            padding: 10px 0px;
            margin: auto;
        }
        /* css for title  */
        h1 {
            font-size: calc(18px + 3vw);
            background: url('images/text-bg.png');
            background-position: center;
            -webkit-background-clip: text;
            color: transparent;
            font-weight: 700;
            margin: 2% 1% -10px 1%;
        }
        /* css for img div  */
        .img {
            height: 250px;
            margin: 1%;
            overflow: hidden;
            box-shadow: 2px 5px 10px -.5px #afafaf;
            cursor: pointer;
            position: relative;
            overflow: hidden;
            transition: all .2s;
        }
        /* css for img title  */
        .img p {
            position: absolute;
            top: 0%;
            left: 0%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: calc(10px + 1.2vw);
            text-align: center;
            font-weight: 200;
            text-transform: uppercase;
            color: white;
            width: 100%;
            height: 250px;
            background: linear-gradient(#ffffff9e, #000000cf);
            margin: 0px;
            opacity: 0;
            transition: all .3s;
        }
        .img:hover p {
            opacity: 1;
        }
        /* css for image  */
        .img img {
            height: 250px;
            width: 100%;
            object-fit: cover;
            object-position: center;
        }
        /* writing media query for make it responsive  */
        @media(max-width: 1000px) {
            .img {
                height: 150px;
            }

            .img img {
                height: 150px;
            }

            .img p {
                height: 150px;
            }
        }
        @media(max-width: 650px) {
            .img {
                height: 130px;
            }

            .img p {
                height: 130px;
            }

            .img img {
                height: 130px;
            }

            #main {
                justify-content: center;
            }
        }
        @media(max-width: 350px) {
            .img {
                height: 100px;
            }

            .img p {
                height: 100px;
            }

            .img img {
                height: 100px;
            }
        }
Enter fullscreen mode Exit fullscreen mode

Now check how's our gallery looks like

html css image gallery
In this layout there's lot of white space at right side and it's look so bad. It must be fix.
To remove this space we use flex grow and shrink property. But we apply this property on the basis of image ratio.
To calculate image ratio and apply it to all image we use javascript.
So let's move on to our next step ⏯

Applying javascript

function setratio() {
            var main = document.getElementById("main"); //select the main div
            var images = main.querySelectorAll('.img'); //select div has class img
            // and now run the loop to to select all images 
            for (var i = 0; i < images.length; i++) {
                var mainImg = images[i].querySelectorAll('img')[0]; // select the image inside .img div
                var imgratio = mainImg.naturalWidth / mainImg.naturalHeight; // now we find the ratio of our images
                var maxWidth = mainImg.offsetHeight * imgratio + (mainImg.offsetHeight * imgratio) / 2; // now we set max-width
                function myFunction(x) {
                    if (x.matches) { // If media query matches
                        images[i].setAttribute('style', `flex-grow:${imgratio};flex-shrink: ${imgratio};`); // set a style attribute of our img div
                    } else {
                        images[i].setAttribute('style', `flex-grow:${imgratio};flex-shrink: ${imgratio};max-width:${maxWidth}px`); // set a style attribute of our img div
                    }
                }
                var x = window.matchMedia("(max-width: 550px)")
                myFunction(x) // Call listener function at run time
                x.addListener(myFunction) // Attach listener function on state changes
            }
        }
Enter fullscreen mode Exit fullscreen mode

I have created a function named setratio() now apply this function onload body

<body onload="setratio()">
Enter fullscreen mode Exit fullscreen mode

In my javascript code first I store main and image div in a variable than run a for loop to get all image. To find ratio of an image I use naturalWidth and naturalHeight javascrpt property than dived them to find ratio and store it in a variable named imgratio and now I use this ratio as image flex grow and shrink property now the extra space are removed our first problem solved.
But now we need to set a max-width for every image so the image grow as it's capacity. For finding the max width we use offsetheight javascript property now multiply mainImg.offsetHeight with imgratio and dived them by 4 and we get the max width value and now apply this max width property only for more than 550px width device for better look.
Now our final product is ready it's responsive for all devices and looks so cool.

Let's see how it looks like in all devices

final image
👍 Thanks for Reading my post

Top comments (4)

Collapse
liluleni profile image
Lilu

Cool script, worked fine on the browsers on desktop PC. Thank you! Unfortunately, the script doesn't work for me on mobile iOS 15.6 (all Browsers, Firefox, Safari, Chrome). Is it the same for you?

Collapse
krishnasoni007 profile image
Krishnasoni007 Author • Edited on

I tested this site in my mobile it's working perfectly but I will try my best to solve your problem I need your little help run this code and check in your ios which is giving output
var a = document.getElementById("main").main.querySelectorAll('.img')[0].naturalWidth
var b = document.getElementById("main").main.querySelectorAll('.img')[0].offsetWidth
alert(a);
alert(b);
and tell me which js property not working

Collapse
liluleni profile image
Lilu

I changed your script in:
var a = document.getElementById("main").querySelectorAll('.img')[0].naturalWidth
var b = document.getElementById("main").querySelectorAll('.img')[0].offsetWidth
alert(a);
alert(b);

var a is not working

Thread Thread
krishnasoni007 profile image
Krishnasoni007 Author

that's mean naturalWidth property not work on ios 15.6

DEV runs on 100% open source code known as Forem.

 
Contribute to the codebase or host your own.
 
Check these out! 👇