• Basics
  • Extending styles

Extending Styles

Quite frequently you might want to use a component, but change it slightly for a single case. Now, you could pass in another class.

To easily make a new component that inherits the styling of another, just wrap it in the styled() constructor. Here we use the button from the last section and create a special one, extending it with some color-related styling:

.button {
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
}
 
.tomatoButton {
  color: tomato;
  border-color: tomato;
}
import styles from './Button.module.css'
 
const Button = styled.button(styles.button)
const TomatoButton = styled(Button)(styles.tomatoButton)
 
const MyComponent = () => (
  <div>
    <Button>Normal Button</Button>
    <TomatoButton>Tomato Button</TomatoButton>
  </div>
)

We can see that the new TomatoButton still resembles Button, while we have only added two new rules.

In some cases you might want to change which tag or component a styled component renders. This is common when building a navigation bar for example, where there are a mix of anchor links and buttons but they should be styled identically.

For this situation, we have an escape hatch. You can use the "as" polymorphic prop to dynamically swap out the element that receives the styles you wrote:

.button {
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
}
 
.tomatoButton {
  color: tomato;
  border-color: tomato;
}
import styles from './Button.module.css'
 
const Button = styled.button(styles.button)
const TomatoButton = styled(Button)(styles.tomatoButton)
 
render(
  <div>
    <Button>Normal Button</Button>
    <Button as="a" href="#">
      Link with Button styles
    </Button>
    <TomatoButton as="a" href="#">
      Link with Tomato Button styles
    </TomatoButton>
  </div>
)

This works perfectly fine with custom components too!

.button {
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
}
import styles from './Button.module.css'
 
const Button = styled.button(styles.button)
 
const ReversedButton = (props) => (
  <Button {...props} children={props.children.split('').reverse()} />
)
 
render(
  <div>
    <Button>Normal Button</Button>
    <Button as={ReversedButton}>Custom Button with Normal Button styles</Button>
  </div>
)