react-burger-menu
:hamburger: An off-canvas sidebar component with a collection of effects and styles using CSS transitions and SVG path animations
Top Related Projects
React components for efficiently rendering large lists and tabular data
Bootstrap components built with React
Accessible modal dialog component for React
Build forms in React, without the tears 😭
Drag and Drop for React
An accessible and easy tab component for ReactJS.
Quick Overview
React-burger-menu is a popular off-canvas sidebar React component with a collection of effects and styles. It provides an easy way to create animated sidebar menus for React applications, offering various customization options and smooth transitions.
Pros
- Easy to implement and customize
- Multiple animation styles available out of the box
- Responsive and mobile-friendly
- Well-documented with clear examples
Cons
- Limited to sidebar menus only
- Some users report issues with TypeScript definitions
- Occasional conflicts with other libraries or CSS frameworks
- Not actively maintained (last update was in 2021)
Code Examples
Basic usage:
import { slide as Menu } from 'react-burger-menu'
function App() {
return (
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
)
}
Customizing styles:
<Menu styles={ styles }>
{/* Menu items */}
</Menu>
const styles = {
bmBurgerButton: {
position: 'fixed',
width: '36px',
height: '30px',
left: '36px',
top: '36px'
},
bmMenuWrap: {
position: 'fixed',
height: '100%'
}
}
Using state to control the menu:
function App() {
const [isOpen, setOpen] = useState(false)
const handleStateChange = (state) => {
setOpen(state.isOpen)
}
return (
<Menu
isOpen={isOpen}
onStateChange={handleStateChange}
>
{/* Menu items */}
</Menu>
)
}
Getting Started
-
Install the package:
npm install react-burger-menu
-
Import and use in your React component:
import { slide as Menu } from 'react-burger-menu' function App() { return ( <Menu> <a id="home" className="menu-item" href="/">Home</a> <a id="about" className="menu-item" href="/about">About</a> <a id="contact" className="menu-item" href="/contact">Contact</a> </Menu> ) }
-
Customize as needed using props and styles objects.
Competitor Comparisons
React components for efficiently rendering large lists and tabular data
Pros of react-window
- Optimized for rendering large lists and tabular data efficiently
- Supports both fixed-size and variable-size lists/grids
- Offers better performance for long lists by only rendering visible items
Cons of react-window
- Less suitable for creating navigation menus or sidebars
- Requires more setup and configuration for basic use cases
- Limited built-in styling options compared to react-burger-menu
Code Comparison
react-window:
import { FixedSizeList } from 'react-window';
const Example = () => (
<FixedSizeList
height={400}
itemCount={1000}
itemSize={35}
width={300}
>
{({ index, style }) => <div style={style}>Row {index}</div>}
</FixedSizeList>
);
react-burger-menu:
import { slide as Menu } from 'react-burger-menu';
const Example = () => (
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
);
Summary
react-window is optimized for rendering large lists efficiently, while react-burger-menu is designed for creating customizable navigation menus. react-window offers better performance for long lists but requires more setup, whereas react-burger-menu provides easier implementation for sidebar menus with built-in styling options.
Bootstrap components built with React
Pros of react-bootstrap
- Comprehensive UI component library with a wide range of pre-built components
- Seamless integration with Bootstrap's CSS framework
- Large community support and regular updates
Cons of react-bootstrap
- Larger bundle size due to the extensive component library
- Less flexibility for custom styling compared to react-burger-menu
- Steeper learning curve for developers unfamiliar with Bootstrap
Code Comparison
react-bootstrap example:
import { Navbar, Nav, Container } from 'react-bootstrap';
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#link">Link</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
react-burger-menu example:
import { slide as Menu } from 'react-burger-menu';
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
react-bootstrap offers a more structured and comprehensive approach to building navigation components, while react-burger-menu provides a simpler and more focused solution for creating slide-out menus.
Accessible modal dialog component for React
Pros of react-modal
- More versatile, can be used for various modal types beyond menus
- Highly customizable with extensive API and styling options
- Better accessibility support out-of-the-box
Cons of react-modal
- Requires more setup and configuration for basic use cases
- Less specialized for side menu implementations
- Larger bundle size due to its broader feature set
Code Comparison
react-modal:
import Modal from 'react-modal';
<Modal
isOpen={modalIsOpen}
onRequestClose={closeModal}
contentLabel="Example Modal"
>
<h2>Hello</h2>
<button onClick={closeModal}>close</button>
</Modal>
react-burger-menu:
import { slide as Menu } from 'react-burger-menu'
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
react-modal is more generic and requires explicit configuration for content and behavior, while react-burger-menu is specifically designed for side menus with pre-built animations and styles. react-modal offers greater flexibility but requires more setup, whereas react-burger-menu provides a more streamlined solution for side menu implementations.
Build forms in React, without the tears 😭
Pros of Formik
- Specialized for form handling, offering robust validation and error management
- Integrates well with popular UI libraries and form validation schemas
- Reduces boilerplate code for complex form implementations
Cons of Formik
- Limited to form-specific functionality, unlike react-burger-menu's broader UI focus
- Steeper learning curve for developers new to form libraries
- May be overkill for simple form implementations
Code Comparison
react-burger-menu:
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
Formik:
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={(values) => console.log(values)}
>
<Form>
<Field name="email" type="email" />
<Field name="password" type="password" />
<button type="submit">Submit</button>
</Form>
</Formik>
The code snippets highlight the different focuses of the libraries: react-burger-menu for creating navigation menus, and Formik for handling form state and submissions.
Drag and Drop for React
Pros of react-dnd
- More versatile, supporting complex drag and drop interactions
- Extensive documentation and community support
- Highly customizable with various built-in hooks and components
Cons of react-dnd
- Steeper learning curve due to its complexity
- Potentially overkill for simple drag and drop requirements
- Requires more setup and configuration
Code Comparison
react-burger-menu:
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
react-dnd:
import { useDrag, useDrop } from 'react-dnd'
function DraggableItem({ id, text }) {
const [{ isDragging }, drag] = useDrag(() => ({
type: 'ITEM',
item: { id },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
}))
return <div ref={drag}>{text}</div>
}
While react-burger-menu focuses on creating side menus with various animations, react-dnd provides a comprehensive solution for implementing drag and drop functionality in React applications. react-dnd offers more flexibility and power for complex interactions, but it comes with a steeper learning curve and more setup compared to the simpler, more focused react-burger-menu.
An accessible and easy tab component for ReactJS.
Pros of react-tabs
- Focused on tab functionality, providing a more specialized and optimized solution for tabbed interfaces
- Offers accessibility features out-of-the-box, ensuring better usability for all users
- Lightweight and easy to integrate into existing React projects
Cons of react-tabs
- Limited to tab functionality, lacking the versatility of a full-fledged navigation menu
- May require additional styling and customization to match specific design requirements
- Less suitable for mobile-first or responsive designs compared to a burger menu
Code Comparison
react-tabs:
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
<Tabs>
<TabList>
<Tab>Title 1</Tab>
<Tab>Title 2</Tab>
</TabList>
<TabPanel>Content 1</TabPanel>
<TabPanel>Content 2</TabPanel>
</Tabs>
react-burger-menu:
import { slide as Menu } from 'react-burger-menu';
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
</Menu>
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
react-burger-menu
An off-canvas sidebar React component with a collection of effects and styles using CSS transitions and SVG path animations.
Using Redux? Check out redux-burger-menu for easy integration of react-burger-menu into your project.
Demo & examples
Live demo: negomi.github.io/react-burger-menu
To build the examples locally, first make sure you're using Node <11.0.0. Then run:
npm install
npm start
Then open localhost:8000
in a browser.
Tests
The test suite uses Mocha, Chai and Sinon, with jsdom.
To run the tests once, run:
npm test
To run them with a watcher, run:
npm run test:watch
Installation
The easiest way to use react-burger-menu is to install it from npm and include it in your own React build process (using Browserify, Webpack, etc).
You can also use the standalone build by including dist/react-burger-menu.js
in your page. If you use this, make sure you have already included React, and it is available as a global variable.
Version 3.x uses Hooks, so if you're using React 16.8+:
npm install react-burger-menu --save
If you're using an earlier version of React:
npm install react-burger-menu@^2.9.2 --save
Usage
Items for the sidebar should be passed as child elements of the component using JSX.
import { slide as Menu } from 'react-burger-menu'
class Example extends React.Component {
showSettings (event) {
event.preventDefault();
.
.
.
}
render () {
// NOTE: You also need to provide styles, see https://github.com/negomi/react-burger-menu#styling
return (
<Menu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
<a id="contact" className="menu-item" href="/contact">Contact</a>
<a onClick={ this.showSettings } className="menu-item--small" href="">Settings</a>
</Menu>
);
}
}
Animations
The example above imported slide
which renders a menu that slides in on the page when the burger icon is clicked. To use a different animation you can substitute slide
with any of the following (check out the demo to see the animations in action):
slide
stack
elastic
bubble
push
pushRotate
scaleDown
scaleRotate
fallDown
reveal
Properties
Some animations require certain other elements to be on your page:
-
Page wrapper - an element wrapping the rest of the content on your page (except elements with fixed positioning - see the wiki for details), placed after the menu component
<Menu pageWrapId={ "page-wrap" } /> <main id="page-wrap"> . . . </main>
-
Outer container - an element containing everything, including the menu component
<div id="outer-container"> <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } /> <main id="page-wrap"> . . . </main> </div>
If you are using an animation that requires either/both of these elements, you need to give the element an ID, and pass that ID to the menu component as the pageWrapId
and outerContainerId
props respectively.
Check this table to see which animations require these elements:
Animation | pageWrapId | outerContainerId |
---|---|---|
slide | ||
stack | ||
elastic | ✓ | ✓ |
bubble | ||
push | ✓ | ✓ |
pushRotate | ✓ | ✓ |
scaleDown | ✓ | ✓ |
scaleRotate | ✓ | ✓ |
fallDown | ✓ | ✓ |
reveal | ✓ | ✓ |
Position
The menu opens from the left by default. To have it open from the right, use the right
prop. It's just a boolean so you don't need to specify a value. Then set the position of the button using CSS.
<Menu right />
Width
You can specify the width of the menu with the width
prop. The default is 300
.
<Menu width={ 280 } />
<Menu width={ '280px' } />
<Menu width={ '20%' } />
Open state
You can control whether the sidebar is open or closed with the isOpen
prop. This is useful if you need to close the menu after a user clicks on an item in it, for example, or if you want to open the menu from some other button in addition to the standard burger icon. The default value is false
.
// To render the menu open
<Menu isOpen />
<Menu isOpen={ true } />
// To render the menu closed
<Menu isOpen={ false } />
You can see a more detailed example of how to use isOpen
here.
Note: If you want to render the menu open initially, you will need to set this property in your parent component's componentDidMount()
function.
Open menu handler
If you keep the menu state yourself it might be convenient to pass a custom function to be used when the user triggers something that should open the menu.
Called when:
- The user clicks on the burger icon
<Menu onOpen={ handleOnOpen } />
Note: The menu will NOT open automatically if you pass this prop, so you must handle it yourself.
Close menu handler
If you keep the menu state yourself it might be convenient to pass a custom function to be used when the user triggers something that should close the menu.
Called when:
- The user clicks on the cross icon
- The user clicks on the overlay
- The user hits the escape key
<Menu onClose={ handleOnClose } />
Note: The menu will NOT close automatically if you pass this prop, so you must handle it yourself.
State change
You can detect whether the sidebar is open or closed by passing a callback function to onStateChange
. The callback will receive an object containing the new state as its first argument.
var isMenuOpen = function(state) {
return state.isOpen;
};
<Menu onStateChange={ isMenuOpen } />
Close on Escape
By default, the menu will close when the Escape key is pressed. To disable this behavior, you can pass the disableCloseOnEsc
prop. This is useful in cases where you want the menu to be open all the time, for example if you're implementing a responsive menu that behaves differently depending on the browser width.
<Menu disableCloseOnEsc />
Custom keydown
handler
For more control over global keypress functionality, you can override the handler that this component sets for window.addEventListener('keydown', handler)
, and pass a custom function. This could be useful if you are using multiple instances of this component, for example, and want to implement functionality to ensure that a single press of the Escape key closes them all.
const closeAllMenusOnEsc = (e) => {
e = e || window.event;
if (e.key === 'Escape' || e.keyCode === 27) {
this.setState({areMenusOpen: false});
}
};
<MenuOne customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} />
<MenuTwo customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} />
Note: Using this prop will disable all the default 'close on Escape' functionality, so you will need to handle this (including determining which key was pressed) yourself.
Overlay
You can turn off the default overlay with noOverlay
.
<Menu noOverlay />
You can disable the overlay click event (i.e. prevent overlay clicks from closing the menu) with disableOverlayClick
. This can either be a boolean, or a function that returns a boolean.
<Menu disableOverlayClick />
<Menu disableOverlayClick={() => shouldDisableOverlayClick()} />
Transitions
You can disable all transitions/animations by passing noTransition
.
<Menu noTransition />
This is useful if you want the menu to remain open across re-mounts, for example during SPA route changes.
Custom icons
You can replace the default bars that make up the burger and cross icons with custom ReactElement
s. Pass them as the customBurgerIcon
and customCrossIcon
props respectively.
<Menu customBurgerIcon={ <img src="img/icon.svg" /> } />
<Menu customCrossIcon={ <img src="img/cross.svg" /> } />
You should adjust their size using the .bm-burger-button
and .bm-cross-button
classes, but the element itself will have the class .bm-icon
or .bm-cross
if you need to access it directly.
You can also disable the icon elements so they won't be included at all, by passing false
to these props.
<Menu customBurgerIcon={ false } />
<Menu customCrossIcon={ false } />
This can be useful if you want exclusive external control of the menu, using the isOpen
prop.
Custom ID and/or classNames
There are optional id
and className
props, which will simply add an ID or custom className to the rendered menu's outermost element. This is not required for any functionality, but could be useful for things like styling with CSS modules.
<Menu id={ "sidebar" } className={ "my-menu" } />
You can also pass custom classNames to the other elements:
<Menu burgerButtonClassName={ "my-class" } />
<Menu burgerBarClassName={ "my-class" } />
<Menu crossButtonClassName={ "my-class" } />
<Menu crossClassName={ "my-class" } />
<Menu menuClassName={ "my-class" } />
<Menu morphShapeClassName={ "my-class" } />
<Menu itemListClassName={ "my-class" } />
<Menu overlayClassName={ "my-class" } />
And to the html
and body
elements (applied when the menu is open):
<Menu htmlClassName={ "my-class" } />
<Menu bodyClassName={ "my-class" } />
Note: Passing these props will prevent the menu from applying styles to the html
or body
elements automatically. See here for more explanation.
Focusing the first menu item
By default, the menu will set focus on the first item when opened. This is to help with keyboard navigation. If you don't want this functionality, you can pass the disableAutoFocus
prop.
<Menu disableAutoFocus />
Custom item list element
The menu's children are all wrapped in a nav
element by default, as navigation is likely the most common use case for this component. However, it's a general purpose sidebar, so you can change this to a div
if you're not using it for navigation:
<Menu itemListElement="div" />
Styling
All the animations are handled internally by the component. However, the visual styles (colors, fonts etc.) are not, and need to be supplied, either with CSS or with a JavaScript object passed as the styles
prop.
CSS
The component has the following helper classes:
/* Position and sizing of burger button */
.bm-burger-button {
position: fixed;
width: 36px;
height: 30px;
left: 36px;
top: 36px;
}
/* Color/shape of burger icon bars */
.bm-burger-bars {
background: #373a47;
}
/* Color/shape of burger icon bars on hover*/
.bm-burger-bars-hover {
background: #a90000;
}
/* Position and sizing of clickable cross button */
.bm-cross-button {
height: 24px;
width: 24px;
}
/* Color/shape of close button cross */
.bm-cross {
background: #bdc3c7;
}
/*
Sidebar wrapper styles
Note: Beware of modifying this element as it can break the animations - you should not need to touch it in most cases
*/
.bm-menu-wrap {
position: fixed;
height: 100%;
}
/* General sidebar styles */
.bm-menu {
background: #373a47;
padding: 2.5em 1.5em 0;
font-size: 1.15em;
}
/* Morph shape necessary with bubble or elastic */
.bm-morph-shape {
fill: #373a47;
}
/* Wrapper for item list */
.bm-item-list {
color: #b8b7ad;
padding: 0.8em;
}
/* Individual item */
.bm-item {
display: inline-block;
}
/* Styling of overlay */
.bm-overlay {
background: rgba(0, 0, 0, 0.3);
}
JavaScript
The same styles can be written as a JavaScript object like this:
var styles = {
bmBurgerButton: {
position: 'fixed',
width: '36px',
height: '30px',
left: '36px',
top: '36px'
},
bmBurgerBars: {
background: '#373a47'
},
bmBurgerBarsHover: {
background: '#a90000'
},
bmCrossButton: {
height: '24px',
width: '24px'
},
bmCross: {
background: '#bdc3c7'
},
bmMenuWrap: {
position: 'fixed',
height: '100%'
},
bmMenu: {
background: '#373a47',
padding: '2.5em 1.5em 0',
fontSize: '1.15em'
},
bmMorphShape: {
fill: '#373a47'
},
bmItemList: {
color: '#b8b7ad',
padding: '0.8em'
},
bmItem: {
display: 'inline-block'
},
bmOverlay: {
background: 'rgba(0, 0, 0, 0.3)'
}
}
<Menu styles={ styles } />
Browser support
Because this project uses CSS3 features, it's only meant for modern browsers. Some browsers currently fail to apply some of the animations correctly.
Chrome and Firefox have full support, but Safari and IE have strange behavior for some of the menus.
Help
Check the FAQ (https://github.com/negomi/react-burger-menu/wiki/FAQ) to see if your question has been answered already, or open a new issue.
License
MIT
Top Related Projects
React components for efficiently rendering large lists and tabular data
Bootstrap components built with React
Accessible modal dialog component for React
Build forms in React, without the tears 😭
Drag and Drop for React
An accessible and easy tab component for ReactJS.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot