I would like to use styled-components
in a React app to create a menu component that contains the styles in the same file thus making it very modular. I'm using react-burger-menu
for the menu. Everything works correctly if I wrap BurgerMenu
in a styled div
like so (styles copied from react-burger-menu
README.md):
import React from 'react';
import { slide as BurgerMenu } from 'react-burger-menu';
import styled from 'styled-components';
const StyledBurgerMenu = styled.div`
/* 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;
}
/* Position and sizing of clickable cross button */
.bm-cross-button {
height: 24px;
width: 24px;
}
/* Color/shape of close button cross */
.bm-cross {
background: #bdc3c7;
}
/* 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);
}
`;
export class Menu extends React.Component {
showSettings(event) {
event.preventDefault();
}
render() {
return (
<StyledBurgerMenu>
<BurgerMenu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
</BurgerMenu>
</StyledBurgerMenu>
);
}
}
export default Menu;
Now this is of course totally okay. However, to learn a lesson and make things a bit more elegant, I'd like to get rid of nesting BurgerMenu
inside of StyledBurgerMenu
by passing the former to styled()
. However, this leads to the burger button being not styled (as per the docs, it's overlaid transparently across all of the screen, so I can click anywhere to open the menu and see that everything else is styled correctly). Is it possible to style the burger button in this fashion or do I have to use the outer div
? Here is how I've tried to solve this:
import React from 'react';
import { slide as BurgerMenu } from 'react-burger-menu';
import styled from 'styled-components';
const StyledBurgerMenu = styled(BurgerMenu)`
/* 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;
}
/* Position and sizing of clickable cross button */
.bm-cross-button {
height: 24px;
width: 24px;
}
/* Color/shape of close button cross */
.bm-cross {
background: #bdc3c7;
}
/* 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);
}
`;
export class Menu extends React.Component {
showSettings(event) {
event.preventDefault();
}
render() {
return (
<StyledBurgerMenu>
<a id="home" className="menu-item" href="/">Home</a>
<a id="about" className="menu-item" href="/about">About</a>
</StyledBurgerMenu>
);
}
}
export default Menu;
Thanks!
Is it possible to style the burger button in this fashion or do I have to use the outer div?
By passing your BurgerMenu
to styled, you are not adding an outer div, the styled component only ensures your css is added to the document and passes the className
to BurgerMenu
. So in order for this to work, BurgerMenu
has to render its className
prop. If it does that it will work without an outer div (or any other parent).
According to https://github.com/negomi/react-burger-menu/blob/95a58dd41e546730f5661dd7ad8deb7296a725ff/src/menuFactory.js#L251 it assigns its className
prop to an inner div, which is not ideal for styled-components
but your styles will apply to that div
. If you want to style the other elements at or above that level, you will either need to come up with some fancy selectors or assign them from outside.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With