Search code examples
javascriptcssreactjsbootstrap-5react-bootstrap

Creating a mega menu using react-bootstrap


Currently I am working on creating mega menu for one of my projects. So far I was able to create a responsive navbar, however the requirement is to create a dropdown panel with 100% width. Tried various ways to make it full width but none get worked.

Note : All the other Nav.Link are too need to be same as NavDropdown.

import React from "react";
import {
  Nav,
  Navbar,
  NavDropdown,
  Col,
  Row,
  Container,
  Dropdown,
} from "react-bootstrap";
import { Link } from "react-router-dom";
import "./home.css";
export function Home() {
  return (
    <div>
      <h1>Home page</h1>
      <Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
        <Container>
          <Navbar.Toggle aria-controls="responsive-navbar-nav" />
          <Navbar.Collapse id="responsive-navbar-nav">
            <Nav className="me-auto">
              <Nav.Link href="#pricing">shoes</Nav.Link>
              <Nav.Link href="#features">handbags</Nav.Link>
              <Nav.Link href="#pricing">jewelry & accessaories</Nav.Link>
              <Nav.Link href="#pricing">men</Nav.Link>
              <Nav.Link href="#pricing">kids</Nav.Link>
              <Nav.Link href="#pricing">home</Nav.Link>
              <Nav.Link href="#pricing">sale</Nav.Link>

              <NavDropdown
                // className="pr-2 py-2 align-text-top"
                title="women"
                id="basic-nav-dropdown"
              >
                <Container className="eventsNav pt-0 mt-0">
                  <Row>
                    <Col xs="12" md="4" className="text-left">
                      <Dropdown.Header>Catering</Dropdown.Header>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Corporate
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Private
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Divider />
                      <Dropdown.Header>
                        {/* <FontAwesomeIcon
                          color="black"
                          icon={"chalkboard-teacher"}
                          size="1x"
                          className="pr-1"
                        /> */}
                        {"  "}
                        Classes
                      </Dropdown.Header>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Barista 101
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            History of Coffee
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Intro to Cafe Snobbery
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Divider className="d-md-none" />
                    </Col>

                    <Col xs="12" md="4" className="text-left">
                      <Dropdown.Header>
                        {/* <FontAwesomeIcon
                          color="black"
                          icon={"building"}
                          size="1x"
                          className="pr-1"
                        /> */}
                        {"  "}
                        Rentals
                      </Dropdown.Header>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Fireside Room
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Roasting Room
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Divider />
                      <Dropdown.Header>
                        {/* <FontAwesomeIcon
                          color="black"
                          icon={"sun"}
                          size="1x"
                          className="pr-1"
                        /> */}
                        {"  "}
                        Seasonal
                      </Dropdown.Header>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Coldbrew Night
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link text-wrap" role="button">
                            Campfire Coffee Class
                          </a>
                        </Link>
                      </Dropdown.Item>
                    </Col>
                    <Col xs="12" md="4" className="text-left">
                      <Dropdown.Header>
                        {/* <FontAwesomeIcon
                          color="black"
                          icon={"building"}
                          size="1x"
                          className="pr-1"
                        /> */}
                        {"  "}
                        Rentals
                      </Dropdown.Header>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Fireside Room
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Roasting Room
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Divider />
                      <Dropdown.Header>
                        {/* <FontAwesomeIcon
                          color="black"
                          icon={"sun"}
                          size="1x"
                          className="pr-1"
                        /> */}
                        {"  "}
                        Seasonal
                      </Dropdown.Header>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link" role="button">
                            Coldbrew Night
                          </a>
                        </Link>
                      </Dropdown.Item>
                      <Dropdown.Item>
                        <Link href="/">
                          <a className="nav-link text-wrap" role="button">
                            Campfire Coffee Class
                          </a>
                        </Link>
                      </Dropdown.Item>
                    </Col>
                  </Row>
                </Container>
              </NavDropdown>
            </Nav>
            <Nav>
              <Nav.Link href="#deets">More deets</Nav.Link>
              <Nav.Link eventKey={2} href="#memes">
                Dank memes
              </Nav.Link>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
    </div>
  );
}

.nav-link {
  font-size: 0.95rem;
}

#basic-nav-dropdown {
  font-size: 0.95rem;
}

#seeMoreLink {
  color: #607d8b;
}

#seeMoreLink:hover {
  color: black;
  font-weight: 400;
}
.dropdown-menu {
  padding: 1em;
}

.dropdown-item:hover {
  outline: none;
  box-shadow: none;
  background: none;
}
.dropdown-item a:hover {
  color: black;
}

.dropdown-item {
  height: 2em;
  padding-left: 0em;
}

.dropdown-header {
  font-weight: 600;
  padding-left: 0em;
}

.dropdown-menu {
  /* position: relative; */
  padding-top: 10px;
}

@media only screen and (min-width: 600px) {
  .eventsNav {
    position: absolute;
    left: -100px;
    background: #eaafc8 !important;
    background: -webkit-linear-gradient(to right, #eaafc8, #654ea3) !important;
    background: linear-gradient(to right, #eaafc8, #654ea3) !important;

    width: 44em;
    padding-bottom: 1em;
  }
}

Expected result expected result

Current implementation current implementation

Thanks and best regards


Solution

  • A Nav.Dropdown sets position: relative; on the nav-item (Nav.Link). Since dropdown-menu has position: absolute; it will be positioned relatively to the nav-item.

    Do:

    .nav-item.dropdown {
      position: inherit;
    }
    
    .dropdown-menu {
      width: 100%;
      transform: translate(0px, 70px); /* change numbers for your layout */
    }
    

    It's recommended to be more specific with the CSS selectors, to not affect any other dropdowns on your page.

    The reason for transform is because of React-Bootstrap's implementation of dropdown and the way they are positioned, are different than Bootstrap. Play with the position of dropdown-menu using Dev Tools, then apply the changes in your own stylesheet.

    It should also be possible to add position: relative; to nav and then position the dropdown-menu below it. Depends on your layout.

    Here's how it's done in Bootstrap (5.3), JSFiddle. Simply removing the class .dropdown from the nav-item and setting width: 100%; on the dropdown-menu is all it needs.