Open In App

How to create a stack visualizer using HTML CSS & Javascript ?

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will see how to create a stack visualizer using HTML, CSS & Javascript, along with understanding its implementation through the illustration.

Stack is a well-known linear data structure that may follow the order LIFO(Last In First Out) or FILO(First In Last Out).

 

There are many real-life examples of a stack. Like, the stack of books in a library is a good real-life example of a stack. If we want to clear the stack then we have to remove the first book or the top book of the stack, i.e. the book which has been placed at the bottommost position remains in the stack for the longest period of time. So, it follows the order LIFO(Last In First Out)/FILO(First In Last Out) order.

In this article, we are going to tell how to build the stack visualizer from the scratch using HTML, CSS and Javascript. In this stack visualizer, we have a bucket in which we can put the elements and the bucket has a limit of containing a certain number of elements. When the limit is crossed, but we try to put an element the stack overflow message will be displayed in the message box and then we need to pop the element from the stack to insert new elements. Also when we want to pop an element from an empty stack then the stack underflow message will be displayed in the message box. 

Approach: The following approach will be utilized to create the Stack Visualizer:

  • Create a project folder and inside it create three files “index.html”(for writing the HTML), “style.css”(for writing the CSS), and “index.js”(for writing the js). You can also create a separate file to keep the CSS code for the responsiveness of the page.
  • Now first create the interface of the visualizer using HTML & CSS. First Create a heading. Then after the heading create a container box which will contain the whole visualizer. Now inside this container add one input box and three buttons for pushing an element, popping an element and resetting the visualizer.
  • Then below the input and the buttons create a bucket using a div and give the border left, right and the bottom and make the top border none in the CSS. This way you can create the bucket.
  • On the left side of the bucket make four options to show the top of the stack, recently popped element, recently pushed element and the size of the stack. Also, create a message box under the info section to show the message. Use flexbox properties to align and justify all content in the right place.
  • Now add some javascript to create the visualizer totally working. First, select all elements which you need to use in javascript using the “document.querySelector” and store them inside variables. Also, declare an empty array which we use and maintain as an internal stack.
  • Now make two functions, one to disable the three buttons and the second one to enable three buttons. Use the “button.disabled = true” to disable the button and “button.disabled = false“. You can also add any style for disabled buttons by “classList.add” if needed.
  • Now write the function for the push button. First, add a click “eventListener” to the push button. Then add a call-back function to the event listener. In this function, first, add an if condition for blank input and show an error message and return. After that add another if condition for checking the stack overflow condition. At last, write the code to a new element in the bucket. Use document.createElement(“div”) to create a new element and add this element to the bucket using the “bucket.appendChild( )” function. Also, update the internal stack or the array. You can also add the setTimeout function to show the adding element delay. Also, disable the three buttons during the element pushing time. After pushing the element, update the value of the top, recently pushed element details and show a successful message in the message box.
  • Now write the function for the Pop button. first, check the stack underflow condition using the if statement. If the stack has no element then show a message of stack underflow. If not, then pop the last element by using “bucket.removeChild” and also delete the last element of the internal stack. At last update the top and the recently popped element. You can also add the setTimeout function to show the popping element delay with animation.
  • At last, write the function of the reset button. First, clear the internal stack. Then make all info content blank by using “.innerHTML” and delete all elements from the bucket by using “bucket.removeChild”.

Example: This example illustrates how to build a stack visualizer using HTML CSS & Javascript.

HTML




<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible"
          content="IE=edge">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <title>GeeksforGeeks</title>
    <link rel="stylesheet" href="style.css">
</head>
 
<body>
    <!-- heading -->
    <header>
        <h1 class="heading">GeeksforGeeks</h1>
        <h3 class="title">Stack Visualizer</h3>
    </header>
 
    <div class="container">
        <div class="container-header">
            <input type="number" class="text" required>
            <button class="push">Push</button>
            <button class="pop ">Pop</button>
            <button class="reset">Reset</button>
        </div>
 
        <div class="container-body">
            <div class="stack">
                <div class="main-stack-bucket"></div>
            </div>
 
            <div class="info">
                <div class="sec1">
                    <h3>Top of the Stack:-</h3>
                    <button class="box"></button>
                </div>
                <div class="sec2">
                    <h3>Last Pushed Item:-</h3>
                    <button class="box"></button>
                </div>
                <div class="sec3">
                    <h3>Last Popped Item:-</h3>
                    <button class="box"></button>
                </div>
                <div class="sec3">
                    <h3>Size of the Stack:-</h3>
                    <button class="box">5</button>
                </div>
 
                <div class="massage-box">
                    <h2>Massage Box</h2>
                    <div class="massage"></div>
                </div>
            </div>
 
        </div>
    </div>
 
    <!-- script -->
    <script src="./index.js"></script>
</body>
 
</html>


  • Style.css

CSS




@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
 
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Poppins", sans-serif;
}
body {
    height: 100vh;
    width: 100vw;
    display: flex;
    justify-content: start;
    align-items: center;
    flex-direction: column;
    gap: 20px;
    background-color: rgb(231, 231, 231);
}
header {
    height: 100px;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.heading {
    color: green;
}
 
.container {
    height: 620px;
    width: 1000px;
    background-color: white;
    box-shadow: 8px 8px 20px rgb(128, 128, 128);
    position: relative;
    overflow: hidden;
    border-radius: 20px;
}
 
.container-header {
    height: 90px;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 20px;
    margin-bottom: 20px;
    margin-top: 10px;
}
 
.container-header input {
    height: 50px;
    width: 400px;
    font-size: 25px;
    border-radius: 10px;
    padding-left: 20px;
    padding-right: 5px;
}
 
.push,
.pop,
.reset,
.box {
    height: 50px;
    width: 140px;
    font-size: 25px;
    background-color: green;
    color: white;
    border-radius: 10px;
    cursor: pointer;
    transition: 0.2s;
    border: none;
}
.disable-button {
    background-color: rgb(0, 59, 0);
}
 
.container-header button:active {
    transform: scale(0.95);
}
.container-body {
    width: 1000px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
}
 
.stack {
    width: 500px;
    height: 470px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-width: 0 3px 0 0;
    border-color: black;
    border-style: solid;
}
 
.main-stack-bucket {
    height: 450px;
    width: 200px;
    border-width: 0 4px 4px 4px;
    border-color: black;
    border-style: solid;
    border-radius: 0 0 10px 10px;
    display: flex;
    justify-content: end;
    align-items: center;
    flex-direction: column-reverse;
    gap: 5px;
    padding-bottom: 5px;
}
 
.ele {
    height: 80px;
    width: 170px;
    background-color: green;
    color: white;
    border: 4px black solid;
    border-radius: 10px;
    font-size: 25px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.ele-add {
    animation: pushAnimation 0.3s infinite linear;
}
.ele-remove {
    animation: popAnimation 0.3s infinite linear;
}
@keyframes pushAnimation {
    0% {
        background-color: green;
    }
    100% {
        background-color: rgb(17, 92, 255);
    }
}
@keyframes popAnimation {
    0% {
        background-color: green;
    }
    100% {
        background-color: rgb(255, 15, 59);
    }
}
 
.info {
    height: 470px;
    width: 500px;
    padding-left: 20px;
}
 
[class^="sec"] {
    display: flex;
    width: 350px;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    justify-content: space-between;
}
 
.massage-box {
    height: 180px;
    width: 400px;
    margin-top: 30px;
    padding: 10px;
    border-radius: 10px;
    background-color: bisque;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
 
.massage-box h2 {
    text-align: center;
    font-weight: 600;
}
 
.massage {
    height: 160px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 30px;
}
.error-massage {
    animation: errorMassage 0.4s infinite linear;
}
@keyframes errorMassage {
    0% {
        background-color: bisque;
    }
    100% {
        background-color: rgb(255, 15, 59);
    }
}


  • Index.js:

Javascript




//variable Declaration
const push = document.querySelector(".push");
const pop = document.querySelector(".pop");
const reset = document.querySelector(".reset");
const bucket = document.querySelector(".main-stack-bucket");
const input = document.querySelector(".text");
const massage = document.querySelector(".massage");
const massageBox = document.querySelector(".massage-box");
const box = document.querySelectorAll(".box");
const stack = [];
 
//for disable all buttons
const buttonDisable = () => {
    push.disabled = true;
    push.classList.add("disable-button");
    pop.disabled = true;
    pop.classList.add("disable-button");
    reset.disabled = true;
    reset.classList.add("disable-button");
    input.disabled = true;
};
 
//for enable all buttons
const buttonEnable = () => {
    push.disabled = false;
    push.classList.remove("disable-button");
    pop.disabled = false;
    pop.classList.remove("disable-button");
    reset.disabled = false;
    reset.classList.remove("disable-button");
    input.disabled = false;
};
 
//When the push button will be clicked
push.addEventListener("click", () => {
    //if input box is empty
    if (input.value == "") {
        massage.innerHTML = "Please Enter a value.";
        massageBox.classList.add("error-massage");
        setTimeout(() => {
            massageBox.classList.remove("error-massage");
        }, 1200);
        return;
    }
 
    //if the stack is full
    if (stack.length == 5) {
        input.value = "";
        massage.innerHTML = "Stack Overflow";
        massageBox.classList.add("error-massage");
        setTimeout(() => {
            massageBox.classList.remove("error-massage");
        }, 1200);
        return;
    }
    const itemValue = input.value; //for store the input value
    stack.push(itemValue); //push the value into the stack
 
    //creating a new element
    const element = document.createElement("div");
    element.classList.add("ele");
    element.innerText = stack[stack.length - 1];
    bucket.appendChild(element);
 
    //update the top
    box[0].innerHTML = stack[stack.length - 1];
 
    //clear the input box
    input.value = "";
 
    //adding the animation for a new pushed element
    element.classList.add("ele-add");
 
    //disable all buttons
    buttonDisable();
 
    //after pushing the element
    setTimeout(() => {
        //remove the animation
        element.classList.remove("ele-add");
 
        //update the Last Pushed Item Value
        box[1].innerHTML = itemValue;
 
        //Display the massage
        massage.innerHTML = `Item ${stack[stack.length - 1]} is Pushed.`;
 
        //Enable all buttons
        buttonEnable();
    }, 1500);
});
 
//When the pop button will be clicked
pop.addEventListener("click", () => {
    //if Stack is Empty
    if (stack.length == 0) {
        massageBox.classList.add("error-massage");
        massage.innerHTML = "Stack Underflow";
        setTimeout(() => {
            massageBox.classList.remove("error-massage");
        }, 1200);
        return;
    }
 
    //adding the popping animation
    bucket.lastElementChild.classList.add("ele-remove");
 
    //disable all buttons
    buttonDisable();
 
    //start popping the element
    setTimeout(() => {
        //delete the element from the bucket
        bucket.removeChild(bucket.lastElementChild);
         
        //Storing the popped value
        const itemValue = stack.pop();
         
        //updating the last popped item
        box[2].innerHTML = itemValue;
 
        //updating the Top
        if (stack.length == 0) {
            box[0].innerHTML = "";
        } else {
            box[0].innerHTML = stack[stack.length - 1];
        }
 
        //adding the massage
        massage.innerHTML = `Item ${itemValue} is Popped.`;
 
        //Enable all buttons
        buttonEnable();
    }, 1500);
});
 
//When the reset button will be clicked
reset.addEventListener("click", () => {
    //clear the full array
    while (stack.length > 0) {
        stack.pop();
    }
 
    //clear all fields
    box[0].innerHTML = "";
    box[1].innerHTML = "";
    box[2].innerHTML = "";
    massage.innerHTML = "";
 
    //clear all elements from the bucket
    while (bucket.firstChild) {
        bucket.removeChild(bucket.firstChild);
    }
});


Output:

 



Last Updated : 03 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads