Responsive Image Gallery like Shutterstock, Pixabay and Adobe Stock using HTML CSS & JavaScript
Tags: imagegallery, responsiveimage, javascript, css
Published: 2022-07-31 18:04:23

🖐 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](https://responsiveimage.netlify.app/)
[Git Repository](https://github.com/krishnasoni007/imageGallery)
##Let's see how it looks like
![Responsive image layout or image gallery](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnxcpxxmpfk18ah1nfst.png)
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
```html
<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>
```
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.
```css
 @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;
            }
        }
```
Now check how's our gallery looks like

![html css image gallery](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/purt161tjo5vpqubvdi4.png)
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
```js
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
            }
        }
```
I have created a function named setratio() now apply this function onload body
```html
<body onload="setratio()">
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nymtw9hz3laxn5noj325.png)
👍 Thanks for Reading my post