Broad Network


How to Create a Tabbed Image Gallery using CSS and JavaScript

Image Gallery

How To, for Front End and Web Applications

By: Chrysanthus Date Published: 23 Apr 2025

A tab is a button around the top of the webpage. When the button is clicked, all the content that appears below the tab in the browser window, belongs to the tab. This tutorial explains How to Create a Tabbed Image Gallery using CSS and JavaScript. For this teaching project, there are four large images with correspondingly, four tabs. Each tab is actually an image thumbnail. The four thumbnails are in a horizontal row. When any of the thumbnails is clicked, its much larger form, appears in a large pane below the row. A short description or name of the large image, appears at the bottom-left of the large image.

The complete webpage code is at the end of this tutorial. The reader should copy the complete code into a text editor. Save the file with any name, but with the extension, .html . Open the file in the browser. Click some tabs (thumbnails) to see their corresponding large image appear below, in the large pane. Scroll down the webpage, to see the short description (name) of the large image, at the bottom-left of the image. The reader is advised to do that before carrying on to read the rest of this tutorial.

The Webpage Skeleton Code

The skeleton code for the webpage to which more useful code will be added is:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Tab Gallery</title>
        <link rel='icon' href='https://www.examplee.com/images/logo.jpg' type='image/x-icon'>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Description of the Web Page.">
        
        <style>

        </style>

        <script type="text/javascript">

        </script>
    </head>
    <body>

    </body>
    </html>

Any modern professional webpage should have at least the first four tags in the HTML head element above. The HTML style element will have quit some good amount of code. The JavaScript code will respond to the click of a thumbnail, to show its much larger image in the large pane below. The HTML body element will have the HTML divs for the images.

HTML body Element Content

The content of the HTML body element is:

        <div style="text-align:center">
            <h2>Tabbed Image Gallery</h2>
            <p>Click on the images below:</p>
        </div>

        <!-- The four columns -->
        <div class="row">
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_nature.jpg" alt="Nature" style="width:100%" onclick="myFunction(this);">
            </div>
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_snow.jpg" alt="Snow" style="width:100%" onclick="myFunction(this);">
            </div>
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_mountains.jpg" alt="Mountains" style="width:100%" onclick="myFunction(this);">
            </div>
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_lights.jpg" alt="Lights" style="width:100%" onclick="myFunction(this);">
            </div>
        </div>

        <div class="container" style='display:block'>
            <span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
            <img id="expandedImg" style="width:100%" src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_nature.jpg">
            <p id="imgtext">Nature</p>
        </div>

For the scheme, there is one principal div element, with class-name "row". There are four inner divs in this div.row. Each of these inner divs, has the class-name "cell" . Each of these four divs has a image tag that downloads one of the four images.

After the div.row in the code, is another outer div whose class-name is "container". The div should be considered as the large pane. For its content, it has a span element, an image tag and a paragraph element, in that order.

If the reader had tested the complete code, he/she would have noticed that there is a transparent close button at the top-right corner of the large image. The code for the X is "×" . This as content is in the span element. This span element has the onclick event, with the JavaScript statement, "this.parentElement.style.display='none'" . When the close button is clicked, this statement is executed, and the value of the display property of the parent container, div.container is made none. The div.container goes off the screen with its large image (off); and there is no replacement. In order to have a replacement, the user has to click another tab (thumbnail), and the div will reappear, with another large image.

The image tag in the div.container downloads the large image, whose size is naturally much larger than that of the tab (thumbnail). The image here is the same with that of one of the thumbnails, but CSS makes the instance in the thumbnail, much smaller in size.

If the reader had tested the complete code, and if he/she scrolled down the webpage, then the reader would have noticed that a short description or name of the large image, appears at the bottom-left of the large image. The paragraph element in the div.container is used for that purpose.

Content for the HTML Style Element

Apart from the attribute, "style='display: block;' " to display the first image, in the large pane, when the webpage is loaded (for the first time), and the "style='width:100%' " 's in the first four image tags, the rest of the styling is within the start and end tags of the HTML style element, in the HTML head element.

At the top within the style element content, is the CSS rule:

                   * {
                       box-sizing: border-box;
                     }

This is called the box-sizing property. The asterisk, * in front of the rule, means that it is applied to all the containers, such as the div element. The box-sizing property means that the width of each element is measured from the left edge of the left border, to the right edge of the opposite border, instead of from the left edge of the element's content, to the right edge of the element's content. The box-sizing property also means that the height of each element is measured from the top edge of the top border, to the bottom edge of the opposite border, instead of from the top edge of the element's content, to the bottom edge of the element's content. The box-sizing property makes coding convenient for projects like this one.

Styling the body Element

The CSS rule for the body element is:

            body {
                margin: 0;
                font-family: Arial;
            }

The font the browser should use is Arial. The gap for all the four margins is 0px. This means that the left edge of the main content will align with the left edge of the webpage; the top edge of the main content will align with the top edge of the webpage; and the right edge of the main content will align with the right edge of the webpage.

Styling the Large Pane Div

The class-name of the div of the large pane is "container". It has one image tag. For a different image, JavaScript replaces the value of the src (source) attribute of the image tag, with the URL of the new image. The CSS rule for the div is:

            div.container {
                position: relative;
                display: none;
            }

Remember that there is only one div for the large pane, in this project. The class-name for the div is "container".

If the reader had tested the complete code, he/she would have observed the short description (name) of the large image, at the bottom-left of the image. Such text is in a paragraph element and the paragraph element is in another layer, placed in front of the image. The paragraph element will have a CSS absolute position property; so its parent element, the div.container, needs to have a position property. In this case, it is the relative position property (for the parent).

Styling the divs for the Tabs

Do not forget that a tab is actually a thumbnail. The CSS rule for each of the four tabs is:

            div.cell {
                float: left;
                width: 25%;
                padding: 10px;
            }

where "cell" is the class-name for each of the four tab divs. Each of these four divs is floated left, in the parent div.row. When floating of divs is done like this, the floating effect has to be stopped with a last unseen pseudo element (see below).

The width of each of the four divs is 25% of the width of the parent container (100% divided by 4 equals 25%). The padding (gap between content and border) for each div rectangle, is 10px.

Styling for the Short Description

At the bottom-left corner of the large image, is the short description or name for the large image. The div with the class-name, "container" has a paragraph element with the ID, "imgtext". For any image displayed, JavaScript copies the value of its alt text, to this paragraph element. Well, the paragraph needs to be styled. And the CSS rule for the paragraph is:

            #imgtext {
                position: absolute;
                bottom: 15px;
                left: 15px;
                color: white;
                font-size: 20px;
            }

This paragraph, has the absolute position property, and it is in a layer in front of the large pane div. Its bottom will be 15px from the bottom of the large pane div ("bottom: 15px;"). Its left will be 15px from the left of the large pane div ("left: 15px;"). Since text in a paragraph element starts on the left, so each short-description will be on the left of the paragraph, putting the short-description at the bottom-left area of the image (large pane div). It is assumed at this point, that the reader knows the meanings of the rest of the CSS properties in the p element (of ID imgtext) CSS rule. In the CSS rule, the paragraph element has been accessed through its ID (imgtext), and not through the p element and class-name.

Styling the Close Button

The CSS rule for the close button is:

            span.closebtn {
                position: absolute;
                top: 10px;
                right: 15px;
                color: white;
                font-size: 35px;
                cursor: pointer;
            }

The short description text at the button-left area of the image is in a paragraph element. The close button at the top-right area of the image, is in a span element. These two elements are in a different layer in front of the image (div.container). It should not be forgotten, that the div.container is in the same layer as its image tag content.

And so, the CSS rule for this span element, like the paragraph element, has the absolute position property. Its top end is 10px down from the top end of its container, and its right end is 15px leftward, from the right end of its container. Its text color is white and its font-size is 35px. The "cursor: pointer;" property, means that when the mouse pointer goes over it, it becomes a hand. It is fashionable to have it like that, today. There is no background color, because this close button is intended to be transparent.

Tab Image Dullness

In order to make an image dull, give it some degree of transparency. The class-name for each of the thumbnail (tab) images is "cell". The CSS rule to have the tab image dull, when the mouse pointer is not over it is:

            div.cell img {
                opacity: 0.8; 
            }

By default, all thumbnail images are made dull, with "opacity: 0.8;". No transparency means an opacity of 1.

Tab On-hover

When the mouse pointer goes over any thumbnail image, the thumbnail gets the "opacity: 1;" property, meaning, brightness and no transparency. When the mouse pointer goes over a tab (thumbnail) image, it becomes a hand. It is fashionable today to have it like that. The CSS rule for all that is:

            div.cell img:hover {
                opacity: 1;
                cursor: pointer; 
            }

Ending the float-left Effect of the Tab divs

There are four tab divs in the div.row. These four divs are each floated left. If this floating effect is not terminated by a fifth element, then there will be serious issues in the operation of the webpage. This fifth element is a pseudo element. It is not coded in the HTML body element. It is coded in the CSS style-sheet. The code for this pseudo fifth element is:

            div.row::after {
                content: "";
                display: table;
                clear: both;
            }

It is the fifth element in div.row. It has no content (no text, no image, etc.). It is a table element with no row and no column. "clear: both;" means it is floated neither left nor right. It ends the floating effect in the div HTML element with class-name, row.

Webpage On-load

When the webpage is loaded (for the first time), the image of the first thumbnail has to be displayed in the large pane; the short description (name) of the first image, has to be at the bottom-left area of the large pane; and the first thumbnail has to be highlighted. These three features are obtained as follows:

Let the src attribute of the image tag in the div.container have the first image URL.

Secondly, let the paragraph element in the div.container, have as content, "Nature" which is the short description (name) of the first image.

Thirdly, give the div.container, the attribute, "style='display:block' ", and the image, whose URL is the value of the src attribute in the image tag of div.container, will be displayed, when the webpage loads (the first time).

JavaScript

When a thumbnail (tab) is clicked, it should become highlighted and its image should appear in the large pane. JavaScript does that. The script code is:

        <script type="text/javascript">
            function myFunction(imga) {
                var expandImg = document.getElementById("expandedImg");
                var imgText = document.getElementById("imgtext");
                expandImg.src = imga.src;
                imgText.innerHTML = imga.alt;
                expandImg.parentElement.style.display = "block";
            }
        </script>

Each tag image has the onclick event which calls the myFunction(this) function. The argument, "this" is the JavaScript image object that was clicked.

The first statement in the function, obtains the image tag object of the image tag in the large pane (div.container) as the variable, expandImg. The second statement in the function, obtains the paragraph element object of the paragraph element in the large pane (div.container) as the variable, imgText. The third statement copies the value of the src attribute of the image clicked, to the src attribute value of the image tag in the large pane. With that, the image is loaded into the large pane, but it is not visible yet. The fourth statement copies the value of the alt attribute of the image clicked, to become content, of the paragraph element, in the large pane. The last statement makes the image in the large pane visible.

The Complete Webpage Code

And there you have it: the complete webpage code is:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Tab Gallery</title>
        <link rel='icon' href='https://www.examplee.com/images/logo.jpg' type='image/x-icon'>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Description of the Web Page.">
        <style>
            * {
                box-sizing: border-box;
            }

            body {
                margin: 0;
                font-family: Arial;
            }
            
            /* The expanding image container */
            div.container {
                position: relative;
                display: none;
            }
            
            /* The grid: Four equal cells next to each other */
            div.cell {
                float: left;
                width: 25%;
                padding: 10px;
            }

            /* Expanding image text */
            #imgtext {
                position: absolute;
                bottom: 15px;
                left: 15px;
                color: white;
                font-size: 20px;
            }

            /* Closable button inside the expanded image */
            span.closebtn {
                position: absolute;
                top: 10px;
                right: 15px;
                color: white;
                font-size: 35px;
                cursor: pointer;
            }

            /* Style the images inside the grid */
            div.cell img {
                opacity: 0.8; 
            }

            div.cell img:hover {
                opacity: 1;
                cursor: pointer; 
            }
            
            /* Clear floats after the columns */
            div.row::after {
                content: "";
                display: table;
                clear: both;
            }
        </style>

        <script type="text/javascript">
            function myFunction(imga) {
                var expandImg = document.getElementById("expandedImg");
                var imgText = document.getElementById("imgtext");
                expandImg.src = imga.src;
                imgText.innerHTML = imga.alt;
                expandImg.parentElement.style.display = "block";
            }
        </script>
    </head>
    <body>
        <div style="text-align:center">
            <h2>Tabbed Image Gallery</h2>
            <p>Click on the images below:</p>
        </div>

        <!-- The four columns -->
        <div class="row">
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_nature.jpg" alt="Nature" style="width:100%" onclick="myFunction(this);">
            </div>
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_snow.jpg" alt="Snow" style="width:100%" onclick="myFunction(this);">
            </div>
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_mountains.jpg" alt="Mountains" style="width:100%" onclick="myFunction(this);">
            </div>
            <div class="cell">
                <img src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_lights.jpg" alt="Lights" style="width:100%" onclick="myFunction(this);">
            </div>
        </div>

        <div class="container" style='display:block'>
            <span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
            <img id="expandedImg" style="width:100%" src="https://www.broad-network.com/Internet/articles/_general/dir0/images/img_nature.jpg">
            <p id="imgtext">Nature</p>
        </div>
    </body>
    </html>

The reader should copy the complete code into a text editor. Save the file with any name, but with the extension, .html . Open the file in the browser. Click some tabs (thumbnails) to see their corresponding large image appear below, in the large pane. Scroll down the webpage, to see the short description (name) of the large image, at the bottom-left of the image.

Chrys





Related Links

More Related Links

Cousins

BACK NEXT

Comments