Media Queries, Pseudo Classes and more with Emotion / Styled Components for React Native.
Wendell Misiedjan
Posted on April 23, 2020
React Native styling with responsive media queries, math operations, rem units, pseudo classes and more!
As a React (Native) developer I don’t like writing too much CSS, although I love creating beautiful interfaces. Recently I started a new Expo project to create a cross-platform app, thinking about the libraries I wanted to use, I was thinking of using Emotion with Styled System.
Emotion is a CSS-in-JS library, like Styled Components, designed for high performance style composition, while Styled System allows you to use style props for rapid UI development.
I discovered that, since React Native doesn’t support Media Queries, the responsive features of Styled System won’t work on native, and I personally really love this feature.
Looking for a solution, I found a package called React Native Extended Stylesheet, a library that adds more CSS features to React Native, like Media Queries, Math Operations, Rem Units, Pseudo Classes and more!
I found a way to combine Emotion with this package to support these extended style features with this CSS-in-JS library, I packaged them both together with a responsive component wrapper, in a package.
Emotion Native Extended — Github
Better styling support for Emotion (React Native): Media Queries, Relative Units, Percents, Operations and more…
There is a example on the GitHub of this package, written using Expo for Web, Android and iOS.
Wanna know more about CSS-in-JS and Styled System’s style props? Continue Reading…
What is CSS-in-JS / Emotion / Styled Components?
CSS-in-JS libraries like Emotion and Styled Components, allow you to use CSS styling within your React files, here’s a quick example:
import styled from 'emotion-native-extended';
*const Box = styled.View`
padding: 8px;
display: flex;
align-items: center;
justify-content: center;
`;
const HelloWorld = () => (<Box>Hello World</Box>);
export default Component;*
Instead of writing styling objects or using StyleSheet.create(), you can define your components like CSS files within your React files.
Using a ThemeProvider, you can pass a theme property to all the styled components, for example, I can change the background color of this Box we created to our primary theme color.
import styled from 'emotion-native-extended';
const theme = {
colors: {
primary: '#03a87c',
}
};
const Box = styled.View`
padding: 16px;
background-color: ${({ theme }) => theme.colors?.primary || 'red'};
`;
<ThemeProvider theme={theme}>
<Box>Hi</Box>
</ThemeProvider>
Now, let’s talk about how Styled System can make your life even a easier for styling and responsive layouts.
What is Styled System?
Styled System is a nice addition to the CSS-in-JS ecosystem, as they describe it themselves on their website:
Styled System is a collection of utility functions that add style props to your React components and allows you to control styles based on a global theme object with typographic scales, colors, and layout properties.
— https://styled-system.com/getting-started
To add style properties to your react components, you can import those utility functions, here’s an example defining our extended box component, with an example of the usage.
import styled from 'emotion-native-extended';
import { space, layout, color } from 'styled-system';
const Box = styled.div`
${space}
${layout}
${color}
`;
export default Box;
Space, layout and color are groups of properties that you add, in this case all spacing properties, like margin’s and padding’s, all layout properties, like width and height and all color properties, and all color properties, like color and backgroundColor.
Now, instead of adding CSS to the component, we can dynamically using properties add styling to our box component, and also include styling for breakpoints, here is again, our Box component being used.
<Box color='white' backgroundColor='primary' padding={[2, 4]}>
Hello World, I'm a responsive View component with my theme's primary color as background, white text and on mobile a padding of 8px and all the above breakpoints a padding of 32px!
</Box>
Let’s explain the padding property, since I defined that value as an array of integers, the array represents breakpoints, and the integers represent an index of an array in our space theme property, by default these breakpoint and spacing values are set in the theme:
// theme.js
export default {
space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
breakpoints: ['40em', '52em', '64em'],
};
The breakpoints are rendered as mobile-first min-width media queries.
That mean’s that in the array we set as padding, 2 refers to a padding of of 8px, and a breakpoint of min-width 40em. 4 refers to a padding 32px and a min-width breakpoint of 52em.
Pretty neat right?
To sum it all up
By default, React Native doesn’t support some CSS features like Media Queries and calculations, but using React Native Extended Stylesheet, you can use those. I created a package called Emotion Native Extended that allows you to use Emotion (a CSS-in-JS library) together with extended stylesheets to support more CSS features.
I did this to fully support Styled System for React Native in the project’s that I am working on. It’s my preferred way of working since I prevent writing a lot of wrapper components and I can keep my code nice and clean.
Resources
Emotion Native Extended - Better styling support for Emotion Native: Media queries, relative units, percents, operations and more…
Emotion - CSS-in-JS library designed for high performance style composition
React Native Extended Stylesheet - Drop-in replacement of React Native StyleSheet with media-queries, relative units, percents, math operations, scaling and more!
-
Styled System - Style props for rapid UI development
Thank you for reading! Feel free to leave any questions in the comments below! If you liked this article, please leave some claps behind and follow me here on medium and other social media, I’ll be posting about React (Native), TypeScript, Node and more!
Medium | Twitter | LinkedIn
Posted on April 23, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.