Notes

Getting started with styled-components

Edit on GitHub

ReactJS
3 minutes
  • how do i get started? npm i styled-components and import styled from 'styled-components'
  • how do i do media query mixins in styled-components that i used to do in Sass? Write them as a JS template literal instead and export/import that file.

Basics

  • You can use & to reference the current selector, just like Sass
  • Nesting is supported
  • Since it’s inside a template string, you can use JS expressions for CSS values
1import React from 'react'
2import styled from 'styled-components'
3
4function export default Button () {
5	const 
6
7}

JS expressions and props

1const Button = styled.button`
2	background: ${props => (props.primary ? 'red' : 'green')};
3`;

Theming

Your theme would be a JS object

1const theme = {
2	primary: 'purple',
3	secondary: 'green'
4}

Wrap the app in <ThemeProvider> and pass it the theme you want to use (a JS object)

1<ThemeProvider theme={theme}>
2	// Code goes here
3</ThemeProvider>
 1import styled, { ThemeProvider } from 'styled-components'
 2
 3const theme = {
 4	primary: 'purple',
 5	secondary: 'green'
 6}
 7
 8const Button = styled.button`
 9	background: ${props => props.theme.primary};
10`;
11
12function App() {
13	return(
14		<ThemeProvider theme={theme}>
15			// Code goes here
16		</ThemeProvider>
17	)
18}

Media Queries with Mixins

You use the mixin as a regular JavaScript function or template string. And then inside the styled component you can call that function or template string.

Ideally, you’d have the media queriues in a separate file that you can import in other files

1// media-queries.js
2const device = {
3	phone-only: '(max-width: 599px)',
4	tablet-portrait-up: '(min-width: 600px)',
5	tablet-landscape-up: '(min-width: 900px)',
6	desktop-up: '(min-width: 1200px)',
7	big-desktop-up: '(min-width: 1800px)'
8}
9export default device
 1import styled from 'styled-components'
 2import device from './media-queries.js'
 3
 4const ContentWrapper = styled.div`
 5  display: flex;
 6  // Mobile friendly by default
 7  flex-direction: column;
 8
 9  // Switch to rows on large devices
10  @media ${device['tablet-landscape-up']} {
11    flex-direction: row;
12  }
13`

If you want to define your breakpoints as variables and then use them, you can do that as well. (I personally feel it’s an unncessary step.

 1// media-queries.js
 2
 3// taking the sizes from the breakpoints in Chrome Dev Tools
 4const size = {
 5  mobileS: '320px',
 6  mobileM: '375px',
 7  mobileL: '425px',
 8  tablet: '768px',
 9  laptop: '1024px',
10  laptopL: '1440px',
11  desktop: '2560px'
12}
13
14export const device = {
15  mobileS: `(min-width: ${size.mobileS})`,
16  mobileM: `(min-width: ${size.mobileM})`,
17  mobileL: `(min-width: ${size.mobileL})`,
18  tablet: `(min-width: ${size.tablet})`,
19  laptop: `(min-width: ${size.laptop})`,
20  laptopL: `(min-width: ${size.laptopL})`,
21  desktop: `(min-width: ${size.desktop})`,
22  desktopL: `(min-width: ${size.desktop})`
23};
 1// Wrapper.js
 2import styled from 'styled-components'
 3import { device } from './device'
 4
 5const Wrapper = styled.div`
 6  margin: 0 auto;
 7
 8  @media ${device.laptop} {  // -> "@media (min-width: ${size.laptop})" -> "@media (min-width: 1024px)"
 9    max-width: 800px;
10  }
11
12  @media ${device.desktop} {
13    max-width: 1400px;
14  }
15`