DEV Community

loading...

What do you think about nested styles in Styled Components?

titungdup profile image dhondup ・1 min read

For example I have nested styled component for a navbar like this

const Navbar = styled.nav`
    // some style 
    .logo{ 
        // logo style 
    } 
    .nav-items{ 
        //nav-items styles 
    } 
    .nav-item{ 
    // list styles 
}`

I am only defining one styled component and using that as a base to style other elements of the navbar with nested style. Sometimes the nested style inside the styled components gets very large with many classes which might be difficult to read.
I looked at spectrum code and found that they almost never nest style inside styled component. Is it a bad practice to use nested style inside styled component? Should i create styled component for each elements like logo, nav-items? What are your thoughts?

Discussion

pic
Editor guide
Collapse
ofhouse profile image
Felix Haus

That's exactly the point why styled-components is different from nested styles because it follows a component pattern instead of a nesting pattern.

To illustrate this, let's take a look how your code would be written completely in styled-components:

// navigation.js
import * as React from 'react';
import styled from 'styled-components';

const Navbar = styled.nav`
  border-bottom: 1px solid #eee;
`;

const Logo = styled.div`
  background-image: url('https://example.com/logo.png');
`;

const NavItems = styled.ul`
  list-style: none;
`;

const NavItem = styled.li`
  color: blue;
`;

const Navigation = () => {
  return (
    <Navbar>
      <Logo />
      <NavItems>
        <NavItem>Link 1</NavItem>
        <NavItem>Link 2</NavItem>
        <NavItem>Link 3</NavItem>
      </NavItems>
    </Navbar>
  );
};

So each styled-component applies it's style to the global CSS-scope independent from the other components.
If you would rewrite it in in pure CSS it would look like this:

/* navigation.css */

.navigation__navbar {
  border-bottom: 1px solid #eee;
}

.navigation__logo {
  background-image: url('https://example.com/logo.png');
}

.navigation__nav-items {
  list-style: none;
}

.navigation__nav-item {
  list-style: none;
}
// navigation.js
import * as React from 'react';
import './navigation.css';

const Navigation = () => {
  return (
    <nav className="navigation__navbar">
      <div className="navigation__logo" />
      <ul className="navigation__nav-items">
        <li className="navigation__nav-item">Link 1</li>
        <li className="navigation__nav-item">Link 2</li>
        <li className="navigation__nav-item">Link 3</li>
      </ul>
    </nav>
  );
};

Each CSS class here is also independent from each other like in styled-components.
The only difference between the pure CSS approach and styled-components is where you define the name of the component.
In the CSS part you do it with the className property and in the styled-components approach you define it with the const ComponentName = styled.div() variable name.

Styled-components simply reuses a different approach to CSS where you write component-based code in CSS (which is much older than styled-compoents itself, for example see BEM) and because of this it makes sense to follow this paradigm also in styled-components.

Collapse
titungdup profile image
dhondup Author

Thank you for detailed explanation. I will follow this approach as much as possible.

Collapse
dorshinar profile image
Dor Shinar

I think that the power of styled components is defining separate styles for each element. Nested styles are useful for example when an external resource applies classes to your components (namely react-transition-group).

Collapse
titungdup profile image
dhondup Author

Thanks. I'll try to leverage this power as much as i can.

Collapse
vikrantsingh47 profile image
vikrant singh

how much power have you leveraged till now?