A Beginners Guide to Styled Components

8 min read

If you are following my articles, you might have noticed “Styled Components” in them. I am implementing styled-components in all my recent projects because I like their customization.

I thought to share all my styled components configs with you so that you can use them in your web apps and personalize them according to your aesthetics.

I will keep updating this guide from time to time. Feel free to incorporate them into your projects.

So, let us start this guide with 3 benefits of styled-components.

3 Real benefits of Styled Components over SCSS?

Once you have started using Styled Components with React, you won't like to go back to SCSS.

Here I found 3 real benefits of styled-components over CSS frameworks.

1. I found theming is a lot easier and maintainable with styled components.

We just have to wrap our app in theme provider, provided by styled components, pass our theme object in it, and get via props wherever we want in our app.

theming

This much simple. We will talk more in theme section.

2. Conditional and Dynamic styling is simpler, we write less CSS utilizing props.

dynamic styling

3. I don’t have to worry about giving a unique class name to a parent element, overlap styling, and misspellings, styled-components do it for me behind the scene.

What should be the Folder Structure of styled-components?

Folder structuring is very important for every project's scalability. The bad folder structure can make managing the project difficult. For styled components, I have created the styles folder inside src. I keep all the styles here. It has four main files.

1. Theme.js

2. Global.js

3. Breakpoints.js

4. Fonts.module.css

folder structure styled components

Let us discuss them one by one.

Theming

While working with styled-components I have noticed theming is a lot easier in styled components. You just need to create a theme object and define all your colors and other configs there like fonts, padding, margins, etc.

export const theme = {
colors: {
primary: '#FAFAFA',
secondary: '#FFC80A',
tertiary: '#303030',
background: '#ffffff',
text: '#000000',
primaryTextColor: '#594F43',
secondaryTextColor: '#777777',
inputPlaceholder: '#C7C7C7',
darkGrayText: '#303030',
darkText: '#1A1A1A',
black: '#000000',
white: '#ffffff',
dark: '',
medium: '',
light: '',
danger: '',
success: '#66A15A',
},
fonts: {
poppins: 'Poppins',
},
paddings: {
container: '15px',
pageTop: '30px',
},
margins: {
pageTop: '30px',
},
}

How to use theme

Import ThemeProvider from styled-components that takes a props theme. Now, get all the theme properties to the components wrapped inside ThemeProvider.

import styled, { ThemeProvider } from 'styled-components'
import { GlobalStyles } from './styles/Global'
import { theme } from './styles/Theme'
const Title = styled.h1`
color: ${(props) => props.theme.colors.primaryTextColor};
`
function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyles />
<Title>Hello World!</Title>
</ThemeProvider>
)
}
export default App

2. Global.js | Global Styles

In global styles, we reset all the default styling.

import styled, { createGlobalStyle, css } from 'styled-components'
import { device } from './BreakPoints'
import fontsCss from './fonts.module.css'
export const GlobalStyles = createGlobalStyle`
${fontsCss} // this works as a normal styled css
/* Box sizing rules */
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-size: 100%;
}
body {
margin: 0;
padding: 0;
overflow-x: hidden;
min-height: 100vh;
text-rendering: optimizeSpeed;
font-family: ${({ theme }) => theme.fonts.poppins}, sans-serif;
font-size: 1rem;
color: ${({ theme }) => theme.colors.text};
background-color: ${({ theme }) => theme.colors.background};
line-height: 1;
position: relative;
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
figure,
blockquote,
dl,
dd {
padding: 0;
margin: 0;
}
button {
border: none;
background-color: transparent;
font-family: inherit;
padding: 0;
cursor: pointer;
}
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role="list"],
ol[role="list"] {
list-style: none;
}
li {
list-style-type: none;
}
/* Set core root defaults */
html:focus-within {
scroll-behavior: smooth;
}
/* A elements that don't have a class get default styles */
a:not([class]) {
text-decoration-skip-ink: auto;
}
/* Make images easier to work with */
img,
picture {
max-width: 100%;
display: block;
}
/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}
/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
html:focus-within {
scroll-behavior: auto;
}
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
`

3. Breakpoints.js

Breakpoints are the points at which the website content adjusts to the device width, allowing you to present the best possible layout to the user. In the given code, I have used max-width if you like you can change it to min-width and play with breakpoints values as per your need.

const size = {
xs: '400px', // for small screen mobile
sm: '600px', // for mobile screen
md: '900px', // for tablets
lg: '1280px', // for laptops
xl: '1440px', // for desktop / monitors
xxl: '1920px', // for big screens
}
export const device = {
xs: `(max-width: ${size.xs})`,
sm: `(max-width: ${size.sm})`,
md: `(max-width: ${size.md})`,
lg: `(max-width: ${size.lg})`,
xl: `(max-width: ${size.xl})`,
xxl: `(max-width: ${size.xxl})`,
}

How to use breakpoint

import styled, { ThemeProvider } from 'styled-components'
import { device } from './styles/BreakPoints'
import { theme } from './styles/Theme'
const Title = styled.h1`
color: ${(props) => props.theme.colors.primaryTextColor};
font-size: 48px;
@media ${device.md} {
font-size: 32px;
}
`
function App() {
return (
<ThemeProvider theme={theme}>
<Title>Hello world</Title>
</ThemeProvider>
)
}
export default App

I learned this technique from Mario Kandut this article

4. Fonts.module.css

I have downloaded fonts in ttf format and added them to assets/fonts folder.

@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-Black.ttf') format('truetype');
font-style: normal;
font-weight: 900;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-ExtraBold.ttf') format('truetype');
font-style: normal;
font-weight: 800;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-Bold.ttf') format('truetype');
font-style: normal;
font-weight: 700;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-SemiBold.ttf') format('truetype');
font-style: normal;
font-weight: 600;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-Medium.ttf') format('truetype');
font-style: normal;
font-weight: 500;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-Regular.ttf') format('truetype');
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-Light.ttf') format('truetype');
font-style: normal;
font-weight: 300;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-ExtraLight.ttf') format('truetype');
font-style: normal;
font-weight: 200;
}
@font-face {
font-family: 'Poppins';
src: url('../assets/fonts/Poppins-Thin.ttf') format('truetype');
font-style: normal;
font-weight: 100;
}

Note: JS file for fonts was reloading on every activity on the screen. We used a CSS file for fonts to fix this issue.

Reusable Styled Components

Here, I have added some reusable styled components to use in multiple places in my project.

1. Container

The container component of styled components is similar to the container in bootstrap, material UI, and other CSS frameworks.

export const Container = styled.div`
width: 100%;
max-width: 1360px;
margin: 0 auto;
padding: 0 ${({ theme }) => theme.paddings.container};
${({ medium }) =>
medium &&
css`
max-width: 1200px;
`}
${({ small }) =>
small &&
css`
max-width: 1100px;
`}
`

2. Grid

Grids are implemented by only wrapping its children inside and passing the props.

export const Grid = styled.div`
display: grid;
grid-template-columns: repeat(${({ columns }) => columns || 2}, 1fr);
justify-items: ${({ end }) => end && 'end'};
grid-column-gap: calc(${({ cgp }) => cgp} * 1px);
${({ pt }) =>
pt &&
css`
padding-top: calc(${pt} * 1px);
`}
${({ pb }) =>
pb &&
css`
padding-bottom: calc(${pb} * 1px);
`}
${({ fullHeight }) =>
fullHeight &&
css`
height: 100%;
`}
${({ py }) =>
py &&
css`
padding-top: calc(${py}* 1px);
padding-bottom: calc(${py}* 1px);
`}
`

3. Box

Box component makes development faster. If we have an independent Button component and want to give it margin and align it on screen, we put it in div and position the div.

Box Component replaces this process, by wrapping the Button component inside the box and passing the related props.

export const Box = styled.div`
margin-top: calc(${({ mt }) => mt} * 1px);
${({ flxRight }) =>
flxRight &&
css`
display: flex;
justify-content: flex-end;
`}
${({ smNone }) =>
smNone &&
css`
${SmallDevicesHidden}
`}
`

Utility Classes in Styled Components

Utility classes are not like components. They behave like mixins, we have in SCSS.

We import CSS from styled-components. We call utility classes inside styled components and reduce a couple of lines of code and development time.

How to use Utility Classes

import styled from 'styled-components'
import { device } from 'styles/BreakPoints'
import { FlxCenter } from 'styles/Global'
const CardStyle = styled.nav`
display: flex;
justify-content: space-between;
@media ${device.md} {
${FlxCenter}
}
`

Horizontally and vertically center an element using flexbox

export const FlxCenter = css`
display: flex;
justify-content: center;
align-items: center;
`

For absolute center

export const AbsCenter = css`
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
`

Hide for small devices

export const SmallDevicesHidden = css`
@media ${device.sm} {
display: none;
}
`

I hope this starter guide has helped you understand styled components in ReactJS.

You can access these codes from this GitHub Repository. Moreover, if you like the information provided in the repository. consider giving it a star on GitHub. 😉