Build overrideable styled components

May 13, 2020

If you're anything like me, there are few things as frustrating as when you need to customize a third-party component's styles and you just cant. Now that I'm actually working on building a component library myself, I want to share with you how you can build components that can be overridden and how to override them.

This blog post is for people who use styled-components. I'm sure other CSS-in-JS solutions have this functionality too, but this post won't delve into that!

Let's take a look at a Tabs component for an example:

Implementation

import React from "react"; import { css } from "styled-components"; const baseTabsStyles = css` border: 1px solid blue; background: red; `; const StyledTabs = styled.section` ${baseTabsStyles}; `; export default function Tabs({ selectedTab, onChange, tabs, className, }: Props) { return ( <StyledTabs className={classnames("tabs", className)}> // implementation details </StyledTabs> ); }

When you implement the component, the library author needs to make sure to pass className as a prop to the Tabs component.

The classnames library allows you to pass multiple classNames to a React component. You can use it to add your own className to it, as well as pass any classNames that are passed into the Tabs component. You must remember to add a className prop to the Tabs component and pass it to the styled component. If you forget this step, you won't be able to override the the styles the library author has applied.

Usage

Now, consumers of this component can override the baseTabStyles in the following way:

import styled from "styled-components"; import { Tabs } from "<component-library-that-uses-styled-components>"; const StyledTabs = styled(Tabs)` && { border: 1px solid red; background: red; } `;

Using && {} allows you to increase the specificity of the styles and allows them to override the base styles the library author applied.

Do you want design systems tips and tricks sent to your inbox?