Open In App

CSS Popover Menu

Last Updated : 27 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will see how we can display contextual information or secondary actions in a compact and accessible manner. To design and implement a popover element that should provide a visually pleasing overlay that appears when triggered by UI with a specific element, offering additional information.

Popover is a UI element that helps display additional information or options when a user interacts with a trigger element, such as a button or link. It is commonly used to provide contextual information, tooltips, or quick access to secondary actions without navigating to a different page or disrupting the user’s workflow.

Approach

  • Design an HTML structure with a trigger element and a popover container.
  • Style the popover’s appearance, including positioning and initial hidden state.
  • Use CSS pseudo-classes like :hover, :focus, or :active to toggle popover visibility.
  • Adjust the popover’s position relative to the trigger using CSS properties.
  • Manage the stacking order with the z-index property to ensure the popover appears above other content.

Adding some links in our HTML code for using the icons, if you want to add icons in your code use it.

Syntax

.popover__content:before {
    position: absolute;
    z-index: -1;
    visibility: hidden;
}
/* For popover on hover*/ 
.popover__wrapper:hover .popover__content {
    z-index: 10;
    opacity: 1;
    visibility: visible;
}

 

Example 1: In this example, Create a Popover by using CSS only.

HTML




<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet"
        href="style.css" />
    <title>
          CSS Popover Menu
      </title>
</head>
  
<body>
    <div class="popover__wrapper">
        <a href="#">
            <h2 class="popover__title">
                GeeksforGeeks
            </h2>
        </a>
        <div class="popover__content">
            <p class="popover__message">
                GeeksforGeeks
            </p>
            <img alt="gfg_logo"
                src=
        </div>
    </div>
    </body>
</html>


CSS




/* style.css */
/* Base styling*/
body {
    background: linear-gradient(50deg, yellow, green);
    max-width: 768px;
      text-align: center;
    margin: 0 auto;
    padding: 1em 0;
    font-family: "Helvetica Neue", Helvetica, Arial,
        sans-serif;
}
  
/* Popover styling */
  
a {
    text-decoration: none;
}
  
.popover__title {
    background-color: white;
    border-radius: 20px;
    font-size: 24px;
    line-height: 36px;
    text-decoration: none;
    color: rgb(35, 172, 71);
    text-align: center;
    padding: 15px;
}
  
.popover__wrapper {
    position: relative;
    margin-top: 1.5rem;
    display: inline-block;
}
.popover__content {
    opacity: 0;
    visibility: hidden;
    position: absolute;
    left: -150px;
    transform: translate(0, 10px);
    background-color: #22b143;
    padding: 1.5rem;
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
    color: white;
    width: auto;
}
.popover__content:before {
    position: absolute;
    z-index: -1;
    content: "";
    right: calc(50% - 10px);
    top: -8px;
    border-style: solid;
    border-width: 0 10px 10px 10px;
    border-color: transparent transparent #22b143
        transparent;
    transition-duration: 0.3s;
    transition-property: transform;
}
.popover__wrapper:hover .popover__content {
    z-index: 10;
    opacity: 1;
    visibility: visible;
    transform: translate(0, -12px);
    transition: all 0.5s
        cubic-bezier(0.75, -0.02, 0.2, 0.97);
}
.popover__message {
    text-align: center;
}


Output:

Peek-2023-09-25-10-54

Example 2: In this example, Create a Popover using JavaScript.

HTML




<!-- index.html -->
<!DOCTYPE html>
<html>
  
<head>
    <title>
          CSS POPOVER
      </title>
    <link rel="stylesheet"
          href="style.css" />
</head>
  
<body>
    <div id="popoverOpener">
        <button type="button"
            class="btn btn-default">
            Open popover
        </button>
    </div>
  
    <div id="popoverWrapper">
        <div class="popover"
            role="tooltip">
            <div class="arrow"></div>
            <h3 class="popover-title">
                geeksforgeeks</h3>
            <div
                class="popover-content">
                <div>
                    <a href=""
                        class="top">Jobs</a>
                    <a href="#"
                        class="right">Contest</a>
                    <a href="#"
                        class="bottom">Problem
                        Solving</a>
                    <a href="#"
                        class="left">Courses</a>
                </div>
            </div>
        </div>
    </div>
    <script src="script.js"></script>
</body>
  
</html>


CSS




/* Style.css */
* {
    margin: 0;
}
#popoverOpener {
    position: absolute;
    left: 50%;
    margin-left: -10vw;
    text-align: center;
    /* top: 45vh; */
    bottom: 10rem;
    width: 20vw;
}
.btn-default {
    margin: auto;
    padding: 15px;
    border-radius: 10px;
    border: none;
    color: green;
    font-size: 20px;
}
#popoverWrapper {
    margin-top: 6rem;
}
.bootstrap .popover {
    transition: left 400ms ease-out, top 250ms ease-in;
}
  
.popover-content > div {
    text-align: center;
}
  
.popover-content > div > a:link {
    /* border: 1px solid rgb(225, 225, 225); */
    border-radius: 8px;
    display: inline-block;
    padding: 4px;
    text-decoration: none;
    transition: all 250ms;
    margin: 2rem;
    padding: 15px;
    background-color: #22b143;
    color: white;
}
  
.popover-content > div > a:hover {
    background-color: #919191ae;
    border-color: #afafbf;
    border-radius: 4px;
    box-shadow: 0 0 4px #ccc;
    color: white;
}
h3 {
    text-align: center;
    font-size: 30px;
    background-color: #22b143;
    padding: 10px;
}


Javascript




// Script.js
  
"use strict";
class Popover {
    constructor(element, trigger, options) {
        this.options = {
            // defaults
            position: Popover.BOTTOM,
        };
        this.element = element;
        this.trigger = trigger;
        this._isOpen = false;
        Object.assign(this.options, options);
        this.events();
        this.initialPosition();
    }
  
    events() {
        this.trigger.addEventListener(
            "click",
            this.toggle.bind(this)
        );
    }
  
    initialPosition() {
        let triggerRect =
            this.trigger.getBoundingClientRect();
        this.element.style.top = ~~triggerRect.top + "px";
        this.element.style.left = ~~triggerRect.left + "px";
    }
  
    toggle(e) {
        e.stopPropagation();
        if (this._isOpen) {
            this.close(e);
        } else {
            this.element.style.display = "block";
            this._isOpen = true;
            this.outsideClick();
            this.position();
        }
    }
  
    targetIsInsideElement(e) {
        let target = e.target;
        if (target) {
            do {
                if (target === this.element) {
                    return true;
                }
            } while ((target = target.parentNode));
        }
        return false;
    }
  
    close(e) {
        if (!this.targetIsInsideElement(e)) {
            this.element.style.display = "none";
            this._isOpen = false;
            this.killOutSideClick();
        }
    }
    outsideClick() {
        document.addEventListener(
            "click",
            this.close.bind(this)
        );
    }
  
    killOutSideClick() {
        document.removeEventListener(
            "click",
            this.close.bind(this)
        );
    }
  
    isOpen() {
        return this._isOpen;
    }
}
  
Popover.TOP = "top";
Popover.RIGHT = "right";
Popover.BOTTOM = "bottom";
Popover.LEFT = "left";
  
document.addEventListener("DOMContentLoaded", function () {
    let btn = document.querySelector(
            "#popoverOpener button"
        ),
        template = document.querySelector(".popover"),
        pop = new Popover(template, btn, {
            position: Popover.RIGHT,
        }),
        links = template.querySelectorAll(
            ".popover-content a"
        );
    for (let i = 0, len = links.length; i < len; ++i) {
        let link = links[i];
        console.log(link);
        link.addEventListener("click", function (e) {
            e.preventDefault();
            pop.position(this.className);
            this.blur();
            return true;
        });
    }
});


Output:

Untitled-ddadaesign



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads