DEV Community

Cover image for A scalable approach to Styled Component Variants
Adrien Rahier
Adrien Rahier

Posted on

8 2

A scalable approach to Styled Component Variants

On several occasions I saw people asking the question: "What's the best way to create variants using Styled components?"

And, because this variant feature is not natively supported by Styled Components I saw different people have different ways to approach this issue.

So, today I wanted to show you a couple of solutions that actually scales.

Note that this post will be split into two parts.
In this first one we are going to focus on how to create Styled Component variants within the same file.

The problem with if else or switch statements

Let's start by creating a simple Styled Component button with 3 variants:

const ButtonStyle = styled.button`
  color: ${({ theme, flashy, disabled }) => {
    if (flashy) return "fuchsia";
    else if (disabled) return theme.grey;
    else return theme.primary;
  }};
`;
Enter fullscreen mode Exit fullscreen mode

As you can see, here you will have to maintain an if else (or switch) condition every time.
Obviously you could externalise this to a specific function determineColor but, still, the problem remains.

Solution 1

I have seen some people writing the same code as above in a more readable fashion:

const ButtonStyle = styled.button`
  color: ${(props) => props.theme.primary};
  ${({ variant }) =>
    variant == "flashy" &&
    css`
      color: "fushia";
    `}
  ${({ variant }) =>
    variant == "disabled" &&
    css`
      color: ${(props) => props.theme.grey};
    `};
`;
Enter fullscreen mode Exit fullscreen mode

Unfortunately, here again, you are kinda using an if-else statement.

Solution 2 using inheritance

My preferred solution is actually to use the built-in inheritance property of styled-components.

const ButtonStyle = styled.button`
    color: ${(props) => props.theme.primary};
`;

const ButtonStyleFlashy = styled(ButtonStyle)`
    color: fuchsia;
`;

const ButtonDisabled = styled(ButtonStyle)`
    color: ${(props) => props.theme.grey};
`;
Enter fullscreen mode Exit fullscreen mode

Here, ButtonStyleFlashy and ButtonDisabled inherits the CSS from ButtonStyle.

Zooming out

As a rule of thumb when I am creating styled component variants within the same file

▶️ If I am sure that the component will have exactly 2 variants I will use a Boolean props

const ParagraphVariant = styled.p`
    font-weight: ${(props) => (props.$bold ? `bold` : `normal`)};
`;
Enter fullscreen mode Exit fullscreen mode

▶️ If the component has x variants then I will use inheritance as seen above.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (1)

Collapse
 
redbar0n profile image
Magne

Nice post!

Stitches has the optimal solution to this, if one dares to leave styled-components: stitches.dev/blog/migrating-from-s...

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay