Design and styling are equally important aspects in mobile applications as they are in web development. Who doesn’t like an attractive and visually appealing UI?
Styling in React Native applications determines how React components or elements will be displayed on the mobile screen or browser. Developers have several options to choose from to style their React Native components:
styled-components is a popular library for React and React Native that enables developers to use component-level styles in their applications by writing a mixture of JavaScript and CSS, called CSS-in-JS. styled-components is thus a tool that bridges the gap between components and styling in React and React Native applications. We’ll be using this library in a later section of this post.
A developer can create styles using plain JavaScript objects, for example:
const styles = { textformat: { fontFamily: 'Lora', fontSize: 25, color: 'maroon', textAlign:'center', marginTop: 40, } };
This can then be applied to a React Native component through the style
property (prop) as follows:
<Text style = {styles.textformat}>Hi there</Text>
The React Native team introduced the StyleSheet API as an alternative approach to CSS stylesheets. As of today, they recommend using the API for the following reasons:
render()
functionrender()
functionThus, the StyleSheet API in React Native offers a clean way to abstract styles for various components, which in turn lead to a better-looking UI. Styling in React Native has been further enhanced with CSS custom properties, also called CSS variables. We’ll be exploring CSS variables in this article as well as make use of the StyleSheet API.
CSS custom properties can be defined by developers to store custom style settings. As a developer, you want to look for ways to modernize your application, speed up productivity, and apply reusability strategies wherever you can.
Using CSS custom properties or CSS variables to implement styling is one way to achieve this. With CSS variables, you can apply the same styles to several components at one time. You can attach them to a selector so that they can be inherited by all descendants of the selector. You can even design a theme for the entire application using sets of custom properties.
With CSS variables, you can achieve several styling outcomes that are not possible with vanilla JavaScript. CSS variables are also quite useful in implementing animations in React Native.
Wisely using CSS variables can also go a long way to improve the maintainability of React Native applications. Since they’re variables, they can be named appropriately and meaningfully, and then referenced easily when required.
Say you developed an application today with a CSS variable forecolor
and applied it to a bunch of text components and buttons. Six months later, you are asked to change the foreground color to something darker. Having defined the CSS variable earlier, it now becomes much easier to track that variable and update only the single value to a darker color, passing the required change in all the necessary components.
Thus, using the CSS variable has made a significant difference in the maintainability of your code.
You declare a CSS variable as follows:
--forecolor: magenta;
It can be then be used like this:
color: var(--forecolor);
--
var
functionStyleSheet.create()
, which uses commas, each property in a CSS variable definition is delimited with a semicolon, like so:
--forecolor: magenta; --fontSize: 25px; --font-family: 'Lora';
Let’s assume that you have a React Native application where you want to apply CSS styles to the paragraph
element and Text
component.
Create your HTML markup as follows:
<div id="react-root"></div> <p> Testing CSS variables</p>
Then, create your CSS/SCSS code with CSS variables, as follows:
:root { --forecolor: magenta; --fontSize: 25px; --font-family: 'Lora'; } p{ color: var(--forecolor); font-family: var(--font-family); text-align: center; font-size: 25px; marginTop: 40; }
Here, you first define three CSS variables, forecolor
, fontSize
, and font-family
. Then you use these variables to set values for the paragraph
element.
The corresponding JavaScript for the application is given here:
const { Text, View, StyleSheet } = ReactNative; const App = () => { return ( Demonstrating CSS Vars in React Native! ); }; const styles = StyleSheet.create({ text: { fontFamily: 'Lora', fontSize: 25, color: 'maroon', textAlign:'center', marginTop: 40, } }); ReactDOM.render(, document.getElementById("react-root"));
Notice that the style for the Text
component is defined only using StyleSheet.create()
.
The code for the entire application is available in a CodePen I created for the article, CSSVarsDemo01. Executing it produces this output:
See the Pen
CSSVarsDemo01 by Mamta Dalal (@mamta_d)
on CodePen.
If you take a hard look at the CSS variable declarations and their usage in the CSS section above, you might wonder what the big deal was about. You could pretty much have set those style values for the paragraph element directly, rather than doing it this way. So what’s the big win here?
The benefit of doing it this way is that the same root styles can now be applied to any other elements, as well as React Native components. We’ll explore this in the next section.
We’ll make a few global style variables that can be reused for both p
and Text
.
The HTML markup remains the same, but our CSS has changed:
:root { --forecolor: magenta; --fontSize: 25px; --font-family: 'Lora'; } p{ color: var(--forecolor); font-family: var(--font-family); text-align: center; font-size: 25px; marginTop: 40; } .main{ color: maroon; font-family: var(--font-family); text-align: center; font-size: 25px; }
Here, we have defined an additional set of CSS variables within a class named main
. Let’s see how we can use this in JavaScript.
const { Text, View, StyleSheet } = ReactNative; const App = () => { return ( <div className="main"> <View> <Text>Demonstrating CSS Vars in React Native!</Text> </View> </div> ); }; ReactDOM.render(<App />, document.getElementById("react-root"));
Observe the bolded lines. They indicate how the main
class containing the CSS variables is now used in our JavaScript code to apply styles to components.
Since the entire View
is enclosed in the <div>
block, any components defined within the View
will have the same styles applied.
The outcome in the viewport will be similar to that seen earlier, just that the way we implemented it is different.
The code for this example is available at CSSVarDemo02.
What if we wanted to use the styled-components library in addition to or in place of native components? You can apply CSS variables to those, too.
The styled-components library can be installed via the CDN link or via the npm install
command.
Let’s see how to do this. We’ll use the same HTML markup as earlier, but we’ll modify the CSS.
:root { --forecolor: indigo; --bgcolor: orchid; --fontSize: 15px; --font-family: 'Lora'; } p{ color: var(--forecolor); font-family: var(--font-family); text-align: center; font-size: 15px; marginTop: 40; }
The JavaScript code will use both native components (View
and Text
) and one from the styled-components library (Button
).
const {Text, View, StyleSheet} = ReactNative; const styled = window.styled.default; const Button = styled.button` background: var(--bgcolor); font-size: var(--fontSize); border: 3px solid purple; border-radius: 100%; display: inline-flex; height: 84px; width: 84px; align-items:center; margin: 30px 0px 0 0px; justify-content: center; align-self: center`; const App = () => { return ( <View> <Button>Begin Game!</Button> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', paddingLeft: 16, paddingRight: 16 }, }); ReactDOM.render(<App />, document.getElementById("react-root"));
The Button
component has some predefined styles from styled-components, but it uses the CSS variables bgcolor
and fontSize
to set the background color and font size for the button.
Without any style set or any CSS variable defined, the styled-components Button
will look like this:
After defining and applying our CSS variables, the outcome will be:
You could have defined these styles using plain JavaScript objects as well, but if your application uses multiple components and more than one screen, using CSS variables will be a good strategy. This is because you can ensure all the button backgrounds and other button properties are consistent across the application — instead of always having to recall the font size across various screens for various components, you can maintain a uniform size by setting a CSS variable for it.
The code for this application is available at CSSVarDemo03.
It’s also possible to set and retrieve CSS variables programmatically at runtime through JavaScript. This would be useful when, say, you want to dynamically change styles based on certain conditions or inputs.
Consider a scenario where you’d want to change the display color of text to a specific color based on user input in a React component. You also want this to happen across all text elements in the application. You can achieve this by dynamically updating the CSS variables through JavaScript code.
Reusing our earlier example, keep the HTML markup and CSS declarations the same; change only the JavaScript for the button component from styled-components:
<Button onClick={() => { console.log(`Current background color:`); //Retrieve the background color from the CSS variable const bg = getComputedStyle(document.documentElement).getPropertyValue('--bgcolor'); console.log(bg); // Set the CSS variable value to a new value console.log(`Setting background color to: green`); document.documentElement.style.setProperty('--bgcolor', 'green');}} > Begin Game!</Button>
The console displays the following output upon clicking the button:
The code for this application is available at CSSVarDemo04.
Now, let’s add another button and a ScrollView
component, create a global theme, and apply it to the button
component, ScrollView
component, and Text
and paragraph
elements.
Our CSS defines the same styles for our globaltheme
and paragraph
elements.
:root { --forecolor: maroon; --bgcolor: orchid; --font-family: 'Lora'; } .globaltheme, p{ color: var(--forecolor); font-family: var(--font-family); text-align: center; font-size: 15px; }
The JavaScript code needs some additions:
const { Text, ScrollView, View, StyleSheet} = ReactNative; const styled = window.styled.default; const Button = styled.button` background: var(--bgcolor); font-size: var(--fontSize); border: 8px solid navy; border-radius: 100%; display: inline-flex; height: 84px; width: 84px; align-items:center; margin: 30px 0px 0 0px; justify-Content: center; align-self: center`; const App = () => { return ( <div className="globaltheme"> <View> <Button onClick={() => {console.log(`Updating color to: green`); document.documentElement.style.setProperty('--bgcolor', 'green');}} >Begin Game!</Button> <Button onClick={() => {console.log(`Exiting`); }} >Exit</Button> <ScrollView > <Text style={styles.listItem}>'Beginner Level 1'</Text> <Text style={styles.listItem}>'Intermediate Level'</Text> <Text style={styles.listItem}>'Advanced/Expert Level'</Text> </ScrollView> </View> </div> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', paddingLeft: 16, paddingRight: 16 }, listItem: { backgroundColor: "orange", borderWidth: 4, borderColor: "navy", padding: 5, }, }); ReactDOM.render(<App />, document.getElementById("react-root"));
The outcome of the code is:
As you can observe, the font size, font family, and foreground color props are applied uniformly across the paragraph
element, the ScrollView
list items, and the buttons.
The code for this application is available at CSSVarDemo05.
You should be cautious about using too many CSS variables in your application and changing them frequently via JavaScript because, at some point, they may also affect performance adversely.
The effects of CSS variables on performance are well-known, but here is a benchmark that examines the effect of a large number of CSS variables on performance if you’re interested.
CSS variables offer many benefits to React Native developers. They are easy to use and can significantly improve productivity and visual appeal.
It would be a good practice to name your CSS variables meaningfully and use them to separate the logical sections in your application from the design sections. In simple terms, one could define variables and properties separately, and not club them together.
Variables, by their very definition, also mean that the value contained in them is likely to change over the course of the application — hence, keep styling values which are likely to change under CSS variables. And when you need to make changes, you can just change the values using selectors and media queries.
It would make sense to keep a few (but not too many) global-scoped properties under your :root
selector.
Although these articles are not React Native-specific, you can tweak them for use in your React Native applications:
LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your React Native apps — try LogRocket for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
One Reply to "Using CSS variables in React Native"
Updating CSS variables that are at * {} do not work with this solution or any variation we can find. Every source says it does, but it doesn’t