14
.
11
.
2023
6
.
03
.
2018
Ruby on Rails
Frontend
Tutorial

Styling React Components

Umit Naimian
Frontend Developer

So far we've been introduced with a couple of preprocessors like Less, SASS, Stylus and a lot of tools and methods for composing, organizing and managing stylesheets for our modern web applications. React, as a powerful JS library of contemporary front-end development also had its own particular need for more capable styling options for its reusable components.

So what is the best approach for styling React components? Regarding this matter, there is no acknowledged common approach or best practice yet but you can find couple of ways to do it.

Styled Components

Styled Components is a well-known example for CSS-in-JS approach. Instead of following traditional pattern with classnames to compose stylesheets, you can create encapsulated styles and even engage them with props of the components. This pattern also allows us to have reusable and separated UI from the other stateful/stateless React components.

Styled components simply act like a wrapper component by being mapped to HTML tags to style itself and child elements. It empowers you to write regular, vanilla CSS inside a JS file which is also reinforced and leveraged with tagged template literals.

Basic usage:

import styled from 'styled-components';

export const Wrapper = styled.div`
  border: 1px solid #ddd;
  padding: 10px;

   // Any nested selector is allowed here
   h1 {
     color: #000;
   }
`;
import React from 'react';
import { Wrapper } from './Wrapper;

export default function Header() { 
  return(
    <Wrapper>
      <h1>This is a simple styled component</h1>
    </Wrapper>
  );
}

Adapting Props

This is an example of the magic of CSS-in-JS approach. You can easily pass a function or any prop to a Styled component’s template literals to adapt it based on its props.

const Button = styled.button`
  background: ${props => props.primary ? 'red' : 'white'};
  color: ${props => props.primary ? 'white' : 'red'};
  font-size: 1.6rem;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 0.5em 1em;
`;

render(
  <div>
    <Button>Default</Button>
    <Button primary>Primary</Button>
  </div>
);

CSS Modules

CSS Modules

CSS modules, regardless of React, have already made a significant contribution to the front-end community by introducing us to an isolated local scope and bringing a more modular approach to the good old CSS. It also worked well with React, thinking of every component gets its own stylesheet file with its own styling.

Since this is not a direct CSS-in-JS approach like Styled Components, you will simply need to write CSS (can be also SASS) in separate stylesheet files. For the basic usage in React, all you need to do is referring to the desired selector within className attribute.

Basic usage:
.flex {
  display: flex;
  align-items: center;
  justify-content: center;
}
import styles from './styles.scss';

const Sample = () => (
  <section className={styles.flex}>
    <p>This is a simple component styled with CSS Modules</p>
  </section>
);

export default Sample;
Extending/Inheritance

As all class selectors are local by default, extending rulesets and communicating with other modules plays a relatively more significant role in CSS modules. Our old-pre-processor friend 'extending' is named as 'composition' here. To share rule-sets between the modules, extend or overwrite, you simply need to use 'composes' property in the stylesheet.

.customTable {
  composes: table from "./table.css";
}

Inline

Even though React itself encourages to use inline styling it comes with a bunch of disadvantages which makes it one of the least preferable option to style React components due to its restrictive usage. Here are the biggest concerns for traditional inline styling for React, unless you don't use any additional library or come up with workaround solutions;

  • Duplication. You might need to recompose same style code once again and use repetitive rules for another component. This flow itself looks like anti-pattern when it comes to reflecting the main principle of React which is described as 'reusable components'.

  • No pseudo-classes: It's not possible to use one of the most fundamental features of CSS such as pseudo-classes (:hover, :active, :focus etc.)

  • No vendor prefixes: You can't use vendor prefixes and override a rule on the same selector

  • No media queries: Using media queries is not possible here, which is a pretty important issue in terms of RWD.

To sum up, this might not be the best approach for using in large-scale and UI-heavy applications as you may end up with a mess and limited range of motion. However, there are several libraries such as Radium, React style, React JSS which provide solutions and workarounds to deal with the deficiency of inline styling.

Basic usage:
const wrapperStyle = {
  width: '50px',
  height: '50px',
  border: '1px solid #ddd',
};

const textStyle = {
  fontSize: '1rem',
  color: '#000',
};

const Sample = () => (
  <div style={wrapperStyle}>
    <p style={textStyle}>This is a sample for inline styling in React</p>
  </div>
);

export default Sample;

Approaches and libraries to style React are not limited only to these mentioned above. There are also other projects such as state-driven styling approach fela, glamorous, styletron and few more.

Umit Naimian
Frontend Developer

Check my Twitter

Check my Linkedin

Did you like it? 

Sign up To VIsuality newsletter

READ ALSO

Writing Chrome Extensions Is (probably) Easier Than You Think

14
.
11
.
2023
Antoni Smoliński
Tutorial
Frontend
Backend

Bounded Context - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

The origin of Poltrax development - story of POLTRAX (part 2)

29
.
11
.
2023
Stanisław Zawadzki
Ruby on Rails
Startups
Business
Backend

Ruby Meetups in 2022 - Summary

14
.
11
.
2023
Michał Łęcicki
Ruby on Rails
Visuality
Conferences

Repository - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Example Application - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

How to launch a successful startup - story of POLTRAX (part 1)

14
.
11
.
2023
Michał Piórkowski
Ruby on Rails
Startups
Business

How to use different git emails for different projects

14
.
11
.
2023
Michał Łęcicki
Backend
Tutorial

Aggregate - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Visuality at wroc_love.rb 2022: It's back and it's good!

14
.
11
.
2023
Patryk Ptasiński
Ruby on Rails
Conferences
Ruby

Our journey to Event Storming

14
.
11
.
2023
Michał Łęcicki
Visuality
Event Storming

Should I use Active Record Callbacks?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Tutorial

How to rescue a transaction to roll back changes?

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Backend
Ruby
Tutorial

Safe navigation operator '&.' vs '.try' in Rails

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Ruby
Tutorial

What does the ||= operator actually mean in Ruby?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Ruby
Tutorial

How to design an entity - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Entity - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Should I use instance variables in Rails views?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Frontend
Backend
Tutorial

Data Quality in Ruby on Rails

14
.
11
.
2023
Michał Łęcicki
Ruby on Rails
Backend
Software

We started using Event Storming. Here’s why!

14
.
11
.
2023
Mariusz Kozieł
Event Storming
Visuality

First Miłośnicy Ruby Warsaw Meetup

14
.
11
.
2023
Michał Łęcicki
Conferences
Visuality

Should I use Action Filters?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Tutorial

Value Object - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial