Introduction to React Native Styling: CSS-in-JS Libraries

React Native is a popular framework for building cross-platform mobile applications using JavaScript. One of the key aspects of building user interfaces in React Native is styling components. Traditionally, CSS has been used for styling web applications, but in the React Native ecosystem, CSS-in-JS libraries provide a more convenient and efficient way of styling components.

In this tutorial, we will explore different CSS-in-JS libraries for React Native and learn how to use them effectively. We will cover the popular libraries such as Styled Components, Emotion, Glamorous, JSS, Radium, and Aphrodite.

react native styling css js libraries

What is React Native Styling?

React Native Styling refers to the process of defining and applying styles to components in a React Native application. Styles in React Native are similar to CSS stylesheets, but they are written in JavaScript. This allows for a more dynamic and flexible approach to styling, as styles can be defined and modified programmatically.

CSS-in-JS libraries for React Native provide a way to write styles directly in JavaScript code, eliminating the need for separate stylesheets. This approach offers several benefits, including better encapsulation, improved code reusability, and enhanced developer experience.

Introduction to React Native

React Native is an open-source framework developed by Facebook for building mobile applications using JavaScript and React. It allows developers to write code once and deploy it on both iOS and Android platforms. React Native utilizes native components to render UI elements, resulting in a highly performant and native-like user experience.

CSS-in-JS Libraries

CSS-in-JS libraries provide a way to write CSS styles directly in JavaScript code. They offer a range of features and advantages over traditional CSS stylesheets, including improved modularity, better code organization, and enhanced developer experience. These libraries generate CSS styles dynamically at runtime, making it easier to create dynamic and responsive user interfaces.

Benefits of CSS-in-JS in React Native

Using CSS-in-JS libraries for styling React Native components offers several benefits:

  1. Improved Modularity: Styles are scoped to individual components, making it easier to manage and reuse styles across the application.

  2. Enhanced Developer Experience: Writing styles in JavaScript provides better tooling support, including code completion, linting, and easier debugging.

  3. Dynamic Styling: CSS-in-JS libraries allow for dynamic styling based on props or state, making it easier to create interactive and responsive user interfaces.

  4. Theming: Styles can be easily customized and themed, allowing for consistent branding across the application.

  5. Performance Optimization: CSS-in-JS libraries generate optimized styles at runtime, reducing the size of the generated CSS and improving performance.

There are several CSS-in-JS libraries available for styling React Native components. In this tutorial, we will explore the following popular libraries:

  • Styled Components
  • Emotion
  • Glamorous
  • JSS
  • Radium
  • Aphrodite

Each of these libraries has its own unique features and advantages. We will go through the installation process and explore the basic usage, styling components, dynamic styling, theming, and media queries for each library.

Styled Components

Styled Components is a popular CSS-in-JS library for React Native that allows you to write styles directly in your JavaScript code. It provides a clean and intuitive API for defining and applying styles to components.

Installation

To install Styled Components, you can use npm or yarn:

npm install styled-components

or

yarn add styled-components

Basic Usage

Once installed, you can import the styled function from the styled-components package and use it to create styled components. Here's an example:

import styled from 'styled-components';

const Button = styled.View`
  background-color: #007bff;
  padding: 10px 20px;
  border-radius: 5px;
`;

const Text = styled.Text`
  color: white;
  font-size: 16px;
`;

const App = () => {
  return (
    <Button>
      <Text>Click me</Text>
    </Button>
  );
};

In this example, we define a Button component using the styled function. The styles are defined using a template literal syntax, similar to CSS stylesheets. The Button component is then rendered with a nested Text component.

Styling Components

Styled Components allow you to apply styles to components in a declarative manner. You can pass props to your styled components and use them to conditionally apply styles. Here's an example:

const Button = styled.View`
  background-color: ${props => (props.primary ? '#007bff' : 'white')};
  padding: 10px 20px;
  border-radius: 5px;
`;

const Text = styled.Text`
  color: ${props => (props.primary ? 'white' : '#007bff')};
  font-size: 16px;
`;

const App = () => {
  return (
    <Button primary>
      <Text primary>Click me</Text>
    </Button>
  );
};

In this example, the Button and Text components have a primary prop which determines their styles. If the primary prop is true, the background color and text color will be set to the primary color, otherwise, it will be set to the secondary color.

Dynamic Styling

Styled Components also support dynamic styling based on the component's props or state. This allows you to create interactive and responsive user interfaces. Here's an example:

const Button = styled.View`
  background-color: #007bff;
  padding: 10px 20px;
  border-radius: 5px;
  opacity: ${props => (props.disabled ? 0.5 : 1)};
  cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};
`;

const Text = styled.Text`
  color: white;
  font-size: 16px;
`;

const App = () => {
  const [disabled, setDisabled] = useState(false);

  const handleClick = () => {
    setDisabled(true);
  };

  return (
    <Button disabled={disabled} onPress={handleClick}>
      <Text>Click me</Text>
    </Button>
  );
};

In this example, the Button component has a disabled prop which determines its opacity and cursor style. If the disabled prop is true, the button will be partially transparent and the cursor will be set to 'not-allowed'. When the button is clicked, the disabled state is updated to true, disabling the button.

Theming

Styled Components make theming easy by allowing you to define global styles that can be easily customized. You can create a ThemeProvider component and pass a theme object to it. Here's an example:

import { ThemeProvider } from 'styled-components';

const theme = {
  primaryColor: '#007bff',
  secondaryColor: '#6c757d',
};

const Button = styled.View`
  background-color: ${props => props.theme.primaryColor};
  padding: 10px 20px;
  border-radius: 5px;
`;

const Text = styled.Text`
  color: ${props => props.theme.secondaryColor};
  font-size: 16px;
`;

const App = () => {
  return (
    <ThemeProvider theme={theme}>
      <Button>
        <Text>Click me</Text>
      </Button>
    </ThemeProvider>
  );
};

In this example, we define a theme object with primary and secondary colors. The Button component uses the theme.primaryColor for its background color, and the Text component uses the theme.secondaryColor for its text color. The ThemeProvider component wraps the Button and Text components, providing the theme object to them.

Media Queries

Styled Components also support media queries, allowing you to define styles based on the screen size or other media features. You can use the css helper function and the min-width or max-width media queries to define responsive styles. Here's an example:

const Button = styled.View`
  background-color: #007bff;
  padding: 10px 20px;
  border-radius: 5px;

  ${props =>
    props.theme.media.desktop`
    padding: 20px 40px;
  `}
`;

const Text = styled.Text`
  color: white;
  font-size: 16px;

  ${props =>
    props.theme.media.desktop`
    font-size: 24px;
  `}
`;

const App = () => {
  return (
    <ThemeProvider
      theme={{
        media: {
          desktop: `@media screen and (min-width: 768px)`,
        },
      }}
    >
      <Button>
        <Text>Click me</Text>
      </Button>
    </ThemeProvider>
  );
};

In this example, we define a media object in the theme with a desktop key that contains a media query for screens with a minimum width of 768px. The Button component and the Text component have styles defined within the props.theme.media.desktop block, which will be applied only on screens that match the media query.

Exploring Emotion

Emotion is another popular CSS-in-JS library for React Native that provides a powerful and flexible way to style components. It offers a wide range of features and has a focus on performance and developer experience.

Installation

To install Emotion, you can use npm or yarn:

npm install @emotion/react @emotion/native

or

yarn add @emotion/react @emotion/native

Basic Usage

Once installed, you can import the css function from the @emotion/native package and use it to create styled components. Here's an example:

import { css } from '@emotion/native';

const Button = ({ children }) => (
  <View
    style={css`
      background-color: #007bff;
      padding: 10px 20px;
      border-radius: 5px;
    `}
  >
    <Text
      style={css`
        color: white;
        font-size: 16px;
      `}
    >
      {children}
    </Text>
  </View>
);

const App = () => {
  return <Button>Click me</Button>;
};

In this example, we define a Button component using the css function from @emotion/native. The styles are defined using template literal syntax, similar to CSS stylesheets. The Button component is then rendered with a nested Text component.

Styled Components vs Emotion

Both Styled Components and Emotion provide similar functionality for styling React Native components. However, there are some differences in their APIs and features.

Styled Components has a more declarative API and allows you to define styles using tagged template literals. It also provides support for theming, dynamic styling, and media queries out of the box. On the other hand, Emotion has a more imperative API and allows you to define styles using the css function. It offers more fine-grained control over styles and provides better performance optimizations.

When choosing between Styled Components and Emotion, it ultimately comes down to personal preference and the specific requirements of your project.

Advanced Features

Emotion provides several advanced features that can help you build more complex and performant styles in your React Native applications. Some of these features include style composition, keyframes animations, and server-side rendering.

To learn more about these advanced features, refer to the Emotion documentation.

Glamorous: Simple and Elegant Styling

Glamorous is a lightweight CSS-in-JS library for React Native that focuses on simplicity and elegance. It provides a simple and intuitive API for styling components and supports advanced features like theming and global styles.

Installation

To install Glamorous, you can use npm or yarn:

npm install glamorous-native

or

yarn add glamorous-native

Basic Usage

Once installed, you can import the glamorous function from the glamorous-native package and use it to create styled components. Here's an example:

import glamorous from 'glamorous-native';

const Button = glamorous.view({
  backgroundColor: '#007bff',
  padding: 10,
  borderRadius: 5,
});

const Text = glamorous.text({
  color: 'white',
  fontSize: 16,
});

const App = () => {
  return (
    <Button>
      <Text>Click me</Text>
    </Button>
  );
};

In this example, we define a Button component using the glamorous.view function. The styles are defined using a JavaScript object syntax. The Button component is then rendered with a nested Text component.

Customizing Styles

Glamorous allows you to customize styles by passing a props object to the styled components. You can use the props argument in the style function to conditionally apply styles. Here's an example:

const Button = glamorous.view(props => ({
  backgroundColor: props.primary ? '#007bff' : 'white',
  padding: 10,
  borderRadius: 5,
}));

const Text = glamorous.text(props => ({
  color: props.primary ? 'white' : '#007bff',
  fontSize: 16,
}));

const App = () => {
  return (
    <Button primary>
      <Text primary>Click me</Text>
    </Button>
  );
};

In this example, the Button and Text components have a primary prop which determines their styles. If the primary prop is true, the background color and text color will be set to the primary color, otherwise, it will be set to the secondary color.

Dynamic Styling

Glamorous also supports dynamic styling based on the component's props or state. This allows you to create interactive and responsive user interfaces. Here's an example:

const Button = glamorous.view(props => ({
  backgroundColor: '#007bff',
  padding: 10,
  borderRadius: 5,
  opacity: props.disabled ? 0.5 : 1,
  cursor: props.disabled ? 'not-allowed' : 'pointer',
}));

const Text = glamorous.text({
  color: 'white',
  fontSize: 16,
});

const App = () => {
  const [disabled, setDisabled] = useState(false);

  const handleClick = () => {
    setDisabled(true);
  };

  return (
    <Button disabled={disabled} onPress={handleClick}>
      <Text>Click me</Text>
    </Button>
  );
};

In this example, the Button component has a disabled prop which determines its opacity and cursor style. If the disabled prop is true, the button will be partially transparent and the cursor will be set to 'not-allowed'. When the button is clicked, the disabled state is updated to true, disabling the button.

JSS: CSS-in-JS for React Native

JSS is a powerful CSS-in-JS library that allows you to write styles in JavaScript and apply them to React Native components. It provides a flexible and efficient way to manage styles and supports advanced features like style composition and dynamic styling.

Installation

To install JSS, you can use npm or yarn:

npm install jss react-jss

or

yarn add jss react-jss

Basic Usage

Once installed, you can import the create function from the jss package and use it to create a JSS instance. You can then use the useStyles hook from the react-jss package to apply styles to your components. Here's an example:

import { create } from 'jss';
import { useStyles } from 'react-jss';

const jss = create();

const styles = {
  button: {
    backgroundColor: '#007bff',
    padding: 10,
    borderRadius: 5,
  },
  text: {
    color: 'white',
    fontSize: 16,
  },
};

const Button = () => {
  const classes = useStyles(styles);

  return (
    <View style={classes.button}>
      <Text style={classes.text}>Click me</Text>
    </View>
  );
};

const App = () => {
  return <Button />;
};

In this example, we create a JSS instance using the create function from the jss package. We define the styles using a JavaScript object syntax. The useStyles hook from the react-jss package is used to apply the styles to the Button component. The classes object returned by the useStyles hook contains the generated class names for the styles.

Style Composition

JSS allows you to compose styles by merging multiple style objects together. This can be useful for creating reusable and modular styles. Here's an example:

const styles = {
  button: {
    backgroundColor: '#007bff',
    padding: 10,
    borderRadius: 5,
  },
  primaryButton: {
    color: 'white',
  },
};

const Button = ({ primary }) => {
  const classes = useStyles(styles);

  return (
    <View style={[classes.button, primary && classes.primaryButton]}>
      <Text>Click me</Text>
    </View>
  );
};

In this example, we define a primaryButton style object that contains additional styles for a primary button. We conditionally apply the primaryButton styles to the Button component based on the primary prop.

Dynamic Styling

JSS supports dynamic styling based on the component's props or state. This allows you to create interactive and responsive user interfaces. Here's an example:

const styles = {
  button: {
    backgroundColor: '#007bff',
    padding: 10,
    borderRadius: 5,
    opacity: props => (props.disabled ? 0.5 : 1),
    cursor: props => (props.disabled ? 'not-allowed' : 'pointer'),
  },
  text: {
    color: 'white',
    fontSize: 16,
  },
};

const Button = () => {
  const [disabled, setDisabled] = useState(false);
  const classes = useStyles(styles, { disabled });

  const handleClick = () => {
    setDisabled(true);
  };

  return (
    <View style={classes.button} onPress={handleClick}>
      <Text style={classes.text}>Click me</Text>
    </View>
  );
};

In this example, the button style object has dynamic styles for the opacity and cursor properties based on the disabled prop. When the disabled state is true, the button will be partially transparent and the cursor will be set to 'not-allowed'. When the button is clicked, the disabled state is updated to true, disabling the button.

Conclusion

In this tutorial, we explored various CSS-in-JS libraries for React Native and learned how to use them effectively. We covered popular libraries such as Styled Components, Emotion, Glamorous, JSS, Radium, and Aphrodite.

CSS-in-JS libraries provide a more convenient and efficient way to style React Native components compared to traditional CSS stylesheets. They offer benefits such as improved modularity, enhanced developer experience, dynamic styling, theming, and performance optimization.

By leveraging these CSS-in-JS libraries, you can create beautiful and responsive user interfaces in your React Native applications with ease. Experiment with different libraries and find the one that best suits your needs and preferences. Happy styling!