DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Using Tailwind CSS in React Native
Santhosh Umapathi
Santhosh Umapathi

Posted on

Using Tailwind CSS in React Native

Introduction

When it comes to styling, React Native is in a pretty good spot. The built-in StyleSheet approach allows you to easily decouple the styles outside of JSX.

But it can be difficult to maintain styles in some external locations to reuse them. Another issue is managing proper naming conventions throughout the whole codebase. These issues can be resolved by using Tailwind in React Native.

Tailwind CSS completely changes the common approach to structuring CSS. While learning good code practices, developers quickly understand the importance of separation of concerns and splitting HTML and CSS between two files. Utility-first CSS seems completely different.

The utility-first class approach

In React Native, utility-first classes apply specific CSS properties to an element via its class or style property. The previous approach was to apply the style object to the element inline or reference the keys of the StyleSheet object with custom names applied.

The utility-first class approach allows you to simply add a class name to the element without needing to write custom styles. The decision to implement colors, typography, and structure, as well as provide a meaningful name to every styled element, is already made.

Tailwind gives you default values based on a solid design system, which results in consistency throughout the whole codebase. The learning curve may seem steep at first, but a developer who is proficient with that type of styling is able to work faster and in a more unified way. In addition, when a team uses a curated set of limited options, it’s easier to onboard a new developer and maintains consistency in your styling approach.

Lastly, because StyleSheets are reused, the codebase will stop growing and therefore easier to maintain.

Considering inline styles

When it comes to mixing code with Tailwind classes, one downside is that our code can quickly become verbose. Usually, we avoid inline styles at all costs because they negatively impact the readability of the code and may impair overall performance. There has been some suggestion from the developer community that the StyleSheet approach is more performant than inline styles because it sends the whole object through the bridge at once. This is further clarified in the React Native Source Code.

Using Tailwind in React Native

While there are a few Tailwind packages well suited for React Native, I chose to use tailwind-react-native-classnames over tailwind-rn. tailwind- react-native-classnames is based on Classnames, a JavaScript utility that is used to improve Tailwind code on the Web, and therefore should be more familiar to developers using Tailwind CSS.

You can feel free to use different libraries as you please, but to me, the tagged template function approach is more visually appealing than styles passed to the array like in react-native-tailwindcss. You may also choose to simply import React Native components from the react-native-tailwind library and pass classes to the className prop.

There are two approaches to applying Tailwind classes to the element using the tailwind-react-native-classnames library. The basic one uses the ES6 tagged template function, which simply wraps class names in backticks like in the View element below. The second approach, which uses the Classnames package, allows for combining classes and handling more complex cases. Notice it in the Text element below:

import tw from 'tailwind-react-native-classnames';<

const MyComponent = () => (
<View style={tw`bg-blue-100`}>
<Text style={tw.style('text-md', invalid && 'text-red-500')}>Hello</Text>
</View>
);

React Native specific classes

We have two React Native classes for using platform-specific styles, which can be safely used with the tagged template function:

tw`ios:pt-4 android:pt-2`;

Tailwind class names

If you look at the menu on the left side of the Tailwind homepage, you’ll see several sections. Only some of these are relevant to React Native, but if you already know how to style components in React Native, you’ll quickly grasp what you can use. The most interesting sections for you to read are:

  • Layout: handles things like size and position
  • Flexbox: positioning elements with Flexbox
  • Spacing: classes for paddings and margins
  • Sizing: width and size classes
  • Typography: everything related to fonts, letter spacings, and text
  • Backgrounds: classes such as background color, image, and background opacity
  • Borders: radius, width, and color classes

There is also the Effects section where you can find opacity, but it is also possible to use classes. Use shadow in tailwind-react-native-classnames, which is located in the Box Shadow part of this section.

I also found this cheat sheet very useful. When trying to specify values, you can check for the proper code for element attributes. For example, when you set element width, you can use the w- class name and set the number w-40 to get 160px.

Example with Stylesheet Approach:

const ListItem = ({
uri,
selected = false,
text=''
}) => {
return (
<View style={[styles2.container, { ...(!selected && { backgroundColor: '#FFFFFF'})}]}>
<View style={styles2.logoBackground}>
<Image
style={styles2.logo}
source={ uri }
/>
</View>
<Text style={[styles2.text, { ...(!selected && { color: 'black'})}]}>{ text }</Text>
<TouchableOpacity style={styles2.button}>
<Text style={styles2.buttonText}>Details</Text>
</TouchableOpacity>
</View>
)
}


const styles2 = StyleSheet.create({
container: {
height: 256,
width: 160,
backgroundColor: 'rgba(59,130,246,1)',
borderRadius: 12,
padding: 15,
margin: 5,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 3,
},
shadowOpacity: 0.27,
shadowRadius: 4.65,
elevation: 6,
},
logoBackground:{
width: 112,
height: 112,
borderRadius: 55,
backgroundColor: '#E4F0FE'
},
logo: {
width: 110,
height: 110,
borderRadius: 55
},
text: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
marginVertical: 10
},
button: {
height: 40,
width:'100%',
backgroundColor: 'white',
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: 'rgba(59,130,246,1)'
},
buttonText: {
color: 'rgba(59,130,246,1)',
fontSize: 17,
fontWeight: 'bold'
}
});

Example with Tailwind CSS approach:

import React from 'react';
import { Text, View, TouchableOpacity, Image } from 'react-native';
import tw from 'tailwind-react-native-classnames';

export const ListItemTW = ({
uri,
selected = false,
text=''
}) => (
<View style={tw.style(
'h-64 w-40 bg-blue-500 rounded-xl p-4 m-1 items-center justify-center shadow-lg',
!selected && 'bg-white'
)}>
<View style={tw`w-28 h-28 rounded-full bg-indigo-50`}>
<Image
style={tw`w-28 h-28 rounded-full`}
source={ uri }
/>
</View>
<Text style={tw.style(
'text-white text-lg font-bold my-4',
!selected && 'text-black'
)}>
{ text }
</Text>
<TouchableOpacity
style={
tw`h-10 w-full bg-white rounded-full items-center justify-center border border-blue-500`
}
>
<Text style={tw`text-lg text-blue-500 font-bold`}>
Details
</Text>
</TouchableOpacity>
</View>
)

So, what’s the difference? Notice that the Tailwind component has 36 lines compared to the normal component with StyleSheet which has 76 lines. The biggest drawback is that there are several long lines of code. Two of these are even multi-line on account of using Classname’s tw.style to join classes with conditionally added styles.

Using predefined styles has its pros and cons. As mentioned, benefits include faster development time and ease of maintenance. The biggest downside is that if you use some uncommon value, like a size or color that is not included in standard values, you would have to customize your styles. I think that the simplest approach would be to pass the style object to the tw.style, which should be recognized without any problem.

Summary

Using Tailwind CSS in your project provides unification of the whole codebase. Instead of giving custom names to the styles in StyleSheet, you can apply class names from the predefined list that is well known by many developers.

Additionally, the speed of development should be improved because it’s easier to style components and assess what styles are applied to particular elements. This approach also has its downsides, like making some components too verbose. I believe that these problems can be resolved by either exporting some of the longer, reusable parts as styled-components or exporting them to the external file, but it’s up to you to decide the best approach for your project.

Thank you for reading all the way through.

Hope this post was useful to improve your Developer Journey !!

Originally published on: https://blogs.appymango.com/blogs/62f87dcd6769db1f12095542

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.