How to create a breakpoint mixin with styled-components
What is styled-components? ๐คท
CSS-in-JS is getting more common within modern frontend and styled-components is one of these libraries. It's one the most popular libraries within CSS-in-JS because of its innovation and familiarity with zero-configuration. Developers don't have to think about unique selector names, styled-components takes care of this.
Utilising tagged template literals (a recent addition to JavaScript) and the power of CSS, styled-components allows you to write actual CSS code to style your components. It also removes the mapping between components and styles โ using components as a low-level styling construct could not be easier!
Useful information ๐
This blog post is based on a mobile-first architecture. If your project is based on some other architecture you just have to tweak the function a little.
You'll notice that I'm using _
(underscore) as the first character in the stylesheet
filenames, the reason for that is to easily recognize a file that contains styling
and to reflect the partial logic from SCSS.
Doing it with SCSS
Just to compare with a common usecase of a SCSS breakpoint mixin I've written the most simple:
// Define breakpoints
$breakpoints: (
sm: 768px,
md: 992px,
lg: 1200px
);
// Create mixin
@mixin respond-to($breakpoint) {
@media (min-width: #{map-get($breakpoints, $breakpoint)}) {
@content;
}
}
// Example usage
html {
background-color: lime;
@include respond-to(sm) {
background-color: aqua;
}
}
Doing it with styled-components ๐
Now it's time to build the same logic but with styled-components. We'll do it in the same order as I explained in the SCSS usecase.
Define breakpoints
Create a file named _variables.js and export a const as below. The keys in the object will be used throughout your application and will relate to the defined value. There's no limit to these breakpoints, but to keep a consistent application I recommend around four breakpoints.
export const breakpoints = {
xs: '480px',
sm: '768px',
md: '992px',
lg: '1200px'
};
Create mixin
Now it's time to create the mixin, do it in a file named _respondTo.js. We have
to import two things for this mixin to work, css
from styled-components
and
breakpoints
that we just created from _variables.js.
import { css } from 'styled-components';
import { breakpoints } from './_variables';
export const respondTo = Object.keys(breakpoints).reduce(
(accumulator, label) => {
accumulator[label] = (...args) => css`
@media (min-width: ${breakpoints[label]}) {
${css(...args)};
}
`;
return accumulator;
},
{}
);
Example usage
Lets try using our mixin in a component. Import styled
from styled-components
and our mixin respondTo
from _respondTo.js. It could look something like this:
import styled from 'styled-components';
import { respondTo } from './_respondTo';
// Background color changes to
// aqua from breakpoint sm (768px)
export const ExampleComponent = styled.div`
background-color: lime;
${respondTo.sm`
background-color: aqua;
`}
`;
Add breakpoint
Now lets say that you want a new breakpoint and use it in our ExampleComponent
,
then you have add it within _variables.js and use it as following:
export const breakpoints = {
xs: '480px',
sm: '768px',
md: '992px',
lg: '1200px',
xl: '1400px' // This one is new};
import styled from 'styled-components';
import { respondTo } from './_respondTo';
// Background color changes to aqua
// from breakpoint sm (768px) and
// changes to purple from our newly
// created breakpoint xl (1400px)
export const ExampleComponent = styled.div`
background-color: lime;
${respondTo.sm`
background-color: aqua;
`}
${respondTo.xl`
background-color: purple; `}
`;
Good job ๐
You've just learned how to create a consistent and scaleable breakpoint mixin for an mobile-first application.
Do you want to learn more? Go to their documentation and have fun ๐คก