DEV Community

Paul Newsam
Paul Newsam

Posted on

Problems with naming in Styled Components

For a while now, our company has been using styled-components. I'm generally a fan. When you've got to update some component's styles, it's easy. The styles are scoped, and they're co-located with the other markup.

What I don't love is the fact that you have to give every styled component a name. You end up having a lot more names in the code than you would otherwise. And everybody seems to follow a different tack, when it comes to naming.

Adding a generic prefix

Often, developers will just add a generic prefix, like Styled- to the name.

const StyledH1 = styled.h1`
  font-size: 64px;
`
<StyledH1>My Big Heading</StyledH1>
Enter fullscreen mode Exit fullscreen mode

This sort of circumvents the naming requirement altogether. Which in principle is a good thing. Because every time you add a new name to a codebase, it's like you're saying to the next developer:

Hey! This thing is meaningfully different from that other thing, pay attention to this!

This avoids that.

But in practice, you end up having to come up with new names anyway, because you can't have name clashes. You can't have, say, two <StyledDiv>s. So you end up with something like this:

const StyledWrapper = styled.div`...`
const StyledHeader = styled.div`...`
const StyledBody = styled.div`...`

<StyledWrapper>
  <StyledHeader>
    <h1>{heading}</h1>
  </StyledHeader>
  <StyledBody>
    <p>{description}</p>
  </StyledBody>
</StyledWrapper>
Enter fullscreen mode Exit fullscreen mode

Which is a lot of words just to say, "I've got 3 divs here".

Dropping the prefix

Since you're creating a new name anyway, you might as well just drop the prefix:

<Wrapper>
  <Header>
    <h1>{heading}</h1>
  </Header>
  <Body>
    <p>{description}</p>
  </Body>
</Wrapper>
Enter fullscreen mode Exit fullscreen mode

But then you're left with the problem of distinguishing "styled" components from components with that have added functionality too.

/**
 * 🤔
 * Which of these is defined in our Design system, and which of these is
 * defined locally?
 */

<OutlinedButton>Click me</OutlinedButton>
<GhostButton>Click me</GhostButton>
Enter fullscreen mode Exit fullscreen mode

Maybe that's okay. After all, this approach aligns better with the component paradigm. Everything's a component after all, so why bother distinguishing between components that are just styled, and other components?

Well, sometimes, using a generic prefix actually seems best. Like when you're augmenting an imported component with a couple of extra style declarations. Positioning is a common example:

import { Button } from '@/ui'
const StyledButton = styled(Button)`
  margin-left: 8px;
`
<StyledButton>Click me</StyledButton>
Enter fullscreen mode Exit fullscreen mode

In this case, you could do one better by giving it a more meaningful name, like <PositionedButton>. But as soon as you add more styles, you quickly think, maybe a generic Styled- prefix was best after all.

// ❌ What does box-shadow have to do with positioning?
const PositionedButton = styled(Button)`
  box-shadow: 0 0 0 2px #000;
  margin-left: 8px;
`
Enter fullscreen mode Exit fullscreen mode

More names == good?

Maybe we're thinking about this all wrong. Maybe names are an opportunity and not a burden. After all, names give us the opportunity to communicate intent. And it can pretty difficult deriving intent from markup like this:

<div className="container padded card border-light text-center">{/**/}</div>
// or this (CSS modules):
<div className={styles.wrapper}>{/**/}</div>
// or this (Tailwind):
<div className="shadow-sm border-b left-4 relative">{/**/}</div>
Enter fullscreen mode Exit fullscreen mode

styled-components gives us the opportunity to name almost everythng in our markup. Because almost every element needs at least one style declaration.

Ultimately though, whether those names are helpful or harmful depends on the quality of those names. And anybody knows, naming things is hard.

No easy solutions

I don't think there's an easy answer here. What I can say is that introducing styled-components to your codebase also introduces a heck of a lot of names. And that's sure different from a library like Tailwind, which requires no new names at all by default.

I think there are definitely cases for going with a CSS-in-JS solution like styled-components. But these days I'm spending more time with Tailwind. Time will tell whether Tailwind is more or less maintainable.

Top comments (0)