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?

Posted on by:

Discussion

markdown guide
 

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.

 

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

 

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).

 

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

 

how much power have you leveraged till now?