Styled Components are an excellent way to write reusable and easily manageable CSS-in-JS code. If you’ve been following my posts here, you might have noticed styled components quite often. In this article, I will share how I personally like to organize styled components in Reactjs projects so that you can use them in your web apps and personalize them according to your aesthetics.
What should be the Folder Structure of styled components?
Maintaining proper folder structure is important for a project’s scalability, as well as for your own personal convenience and organization. A poor folder structure can make management difficult. It also happens that we don’t take structuring seriously in the start while it's apparently easier to manage, but once the project starts growing and more is added to it, organization and management start to become a pain and we regret not having taken care of the basics early on.
The most common and basic “best practice” for folder structuring in Reactjs or gatsbyjs projects is creating the src
folder at the root in React. For styled components, we can create a styles
folder inside the src
folder. All styles are then kept in the styles
folder. In my case, it has four main files:
Styled Components File Structure
- Theme.js
- Global.js
- Breakpoints.js
- Fonts.module.css
Let us discuss them one by one.
1. Theming in styled components
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, and use them wherever you want them in your app.
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: 'Anek Malayalam',},paddings: {container: '15px',pageTop: '30px',},margins: {pageTop: '30px',},}
How to use theme in styled components
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 Styled Components
In global styles, we reset all the default styling.
You may have noticed I have defined font-family
, color
(font/text color), and background-color
in body, so it impacts the whole application.
import styled, { createGlobalStyle, css } from 'styled-components'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.anekMalayalam}, sans-serif;font-size: 1rem;color: ${({ theme }) => theme.colors.text};background-color: ${({ theme }) => theme.colors.background};line-height: 1;}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 in Styled Components
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 mobilesm: '600px', // for mobile screenmd: '900px', // for tabletslg: '1280px', // for laptopsxl: '1440px', // for desktop / monitorsxxl: '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 in media queries in styled components
To use break point in styled component we have imported the device
object from BreakPoints file, and after that use the required size.
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. Using woff2 and Woff font in Styled Components
I have downloaded fonts in woff2
and woff
format, the lighter and recommended font format to use, and added them to assets/fonts
folder.
/* woff2 : Super Modern Browsers *//* woff :Modern Browsers */@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 100;src: url('../assets/fonts/anek-malayalam-v4-malayalam-100.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-100.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 200;src: url('../assets/fonts/anek-malayalam-v4-malayalam-200.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-200.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 300;src: url('../assets/fonts/anek-malayalam-v4-malayalam-300.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-300.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 400;src: url('../assets/fonts/anek-malayalam-v4-malayalam-400.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-400.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 500;src: url('../assets/fonts/anek-malayalam-v4-malayalam-500.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-500.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 600;src: url('../assets/fonts/anek-malayalam-v4-malayalam-600.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-600.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 700;src: url('../assets/fonts/anek-malayalam-v4-malayalam-700.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-700.woff') format('woff');font-display: swap;}@font-face {font-family: 'Anek Malayalam';font-style: normal;font-weight: 800;src: url('../assets/fonts/anek-malayalam-v4-malayalam-800.woff2') format('woff2'),url('../assets/fonts/anek-malayalam-v4-malayalam-800.woff') format('woff');font-display: swap;}
Note
JS file for fonts was reloading on every activity on the screen. We used a CSS file for fonts to fix this issue.
Testing Fonts in Styled Components
It’s time to test the fonts to see if we have it all set up correctly. For that, I have tested fonts from font-weight: 100
to font-weight: 800
in App.js
.
Besides I used WhatFont google chrome extension to verify it.
And that’s it, guys. We looked at folder structuring in the context of styled components, as well as the files that are part of the styles folder. Hope it added to your knowledge.
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. 😉