10 useful tips for Styled Components

Pitipat Srichairat
4 min readJul 13, 2018

--

Here at Forviz, it has been 10 months since we introduced styled-components as our main tool for styling UI components. Here’s little takeaway notes.

It is great for both web and mobile dev

It is practically the same in both web and native. So dev can switch around web / mobile projects with relatively ease. (It might takes a few hours to remember it is View in React Native, not div. LOL with tears)

Styled Component is a great choice for a team who is looking for a learn-once-write-everywhere solution.

// For web
import styled from 'styled-components';
const MyBox = styled.div`
background: salmon;
padding: 20px;
`;
---// For Native
import styled from 'styled-components/native';
const MyBox = styled.View`
background: salmon;
padding: 20px;
`;

It is great for new comers

Raise your hand if you know the pain of learning web technologies in 2017.

It is challenging.

The list of things you have to mention to new comers is endless; Javascript, React, React Native, Babel, ECMA, Webpack, Redux, SASS, PostCSS, and so on, and so on…

Styled Components make React, React Native learning experiences great because it doesn’t feel like another language (css, sass), it still feels like Javascript. New comers can still wrap their head around their Javascript knowledge while creating stylesheet. For them it’s not another language, it is just a styling text that reside in Javascript. They don’t have to learn the “css way” and “javascript way”.

1. It’s auto-prefixing

This should go without mentioned, but for some starters (including me), who came from css, sass land this is a HUGE deal. What does it mean by auto-prefixing? Well basically it automatically add prefixes to your css

display: flex;
flex-direction: row;

automatically become

-ms-flex: 1;
flex: 1 1;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: row;
flex-direction: row;

2. attrs

Don’t forget you still have the ‘attrs’, and it’s can be passed down from your props.

const InputText = styled.input.attrs({
type: 'text',
placeholder: props => props.placeholder || 'Please fill',
})`
padding: 6px 12px;
`;

3. You can use styled component with any css frameworks

With attrs, you can obviously use className attribute, thus converting existing css framework to styled component is a breeze.

const Button = styled.button.attrs({
className: 'btn btn-primary'
})``;
// With some dynamic props
const Button = styled.button.attrs({
className: `btn btn-primary btn-${props => props.size || 'medium'}`
})``;
<Button size="small" />

4. withComponent

You can switch component around, let’s say button to a with “withComponent”. It’s handy for some situation.

const PrimaryButton = styled.button`
background-color: blue;
`;

const PrimaryLink = PrimaryButton.withComponent('a');

5. Nested rules, media query are OK

const MyBox = styled.div`
width: 500px;
height: 300px;
::before {
content: '';
}
::after {
content: '';
}
li::first-child {
content: '';
}
@media (max-width: 700px) {
background: palevioletred;
}
`;

6. Reverse Selector Pattern

Now this is something interesting, with styled components it is possible to reference to element’s parent

const Link = styled.a`
display: flex;
align-items: center;
padding: 5px 10px;
background: papayawhip;
color: palevioletred;

&:hover svg { ... } // <-- This is what we normally do.
`;

const Icon = styled.svg`
transition: fill 0.25s;
width: 48px;
height: 48px;

${Link}:hover & { // <-- This is what we can do now.
fill: rebeccapurple;
}
`;

7. It has built in theme context api

import styled, { ThemeProvider } from 'styled-components';const theme = {
primaryColor: 'salmon',
fontFamily: 'Bebas',
};

const Button = styled.button`
background: ${props => props.theme.primaryColor}
font-family: ${props => props.theme.fontFamily}
`;

<ThemeProvider theme={theme}>
<Button />

{/* Or you can override */}
<Button theme={{ primaryColor: 'green' }} />
</ThemeProvider>

8. You can do Compositions & Mixins pattern

Because it’s just string. So there are many ways to do a composition. It is fairly easy with existing css helper or polished package, or you can write your own function as well.

Psss. There is

import { css } from 'styled-components';

const boxShadowMixin = css`
box-shadow: 0 0 0 rgba(0, 0, 0, 0.5);
`;

const boxShadowMixinFunc = (top, left, blur, color, inset = false) => {
return `box-shadow: ${inset ? 'inset' : ''} ${top}px ${left}px ${blur}px ${color};`;
}

const StyledComp = styled.div`
${boxShadowMixin}
${boxShadowMixinFunc(0, 0, 4, 'rgba(0, 0, 0, 0.5)')}
`;

9. To override existing / inline style

Just in case of occasion arise and you need to override some style. The repeated & will bump generated className for each &.

const MyStyledBox = styled(AlreadyStyledComponent)`
&&& {
color: palevioletred;
font-weight: bold;
}
`;
// Became
.MyBox.MyBox.MyBox {
color: palevioletred;
font-weight: bold;
}
// Override Inline style
const MyStyledComponent = styled(InlineStyledComponent)`
&[style] {
font-size: 12px !important;
color: blue !important;
}
`;

10. Short if

To write a ‘not-so-simple’ condition, this is a nice snippet.

background-color: ${props =>
(props.type === 'primary' && 'blue') ||
(props.type === 'danger' && 'red') ||
(props.type === 'warning' && 'yellow') ||
}

There you have it folk, wish you all well and happy

--

--