Open In App

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

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:

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




<!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>




@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);
    }
}




//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:

 


Article Tags :