Skip
Arish's avatar

24. Styling Methods in React


Styling Methods in React

React offers many ways to style components. Let's explore the most popular approaches.

Inline Styles

JavaScript objects for styles:

jsx
1function Button() {
2  const styles = {
3    backgroundColor: 'blue',
4    color: 'white',
5    padding: '10px 20px',
6    border: 'none',
7    borderRadius: '4px',
8    cursor: 'pointer'
9  }
10  
11  return <button style={styles}>Click me</button>
12}
13
14// Dynamic styles
15function Box({ isActive }) {
16  return (
17    <div style={{
18      backgroundColor: isActive ? 'green' : 'gray',
19      opacity: isActive ? 1 : 0.5
20    }}>
21      Box
22    </div>
23  )
24}

CSS Stylesheets

Traditional CSS files:

css
1/* Button.css */
2.btn {
3  padding: 10px 20px;
4  border: none;
5  border-radius: 4px;
6  cursor: pointer;
7}
8
9.btn-primary {
10  background-color: blue;
11  color: white;
12}
13
14.btn-danger {
15  background-color: red;
16  color: white;
17}
jsx
1import './Button.css'
2
3function Button({ variant = 'primary', children }) {
4  return (
5    <button className={`btn btn-${variant}`}>
6      {children}
7    </button>
8  )
9}

CSS Modules

Scoped CSS to prevent conflicts:

css
1/* Button.module.css */
2.button {
3  padding: 10px 20px;
4  border: none;
5  border-radius: 4px;
6}
7
8.primary {
9  background-color: blue;
10  color: white;
11}
12
13.danger {
14  background-color: red;
15  color: white;
16}
jsx
1import styles from './Button.module.css'
2
3function Button({ variant = 'primary', children }) {
4  return (
5    <button className={`${styles.button} ${styles[variant]}`}>
6      {children}
7    </button>
8  )
9}
10
11// Classes become unique: Button_button__abc123

Tailwind CSS

Utility-first CSS framework:

jsx
1function Card({ title, children }) {
2  return (
3    <div className="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
4      <h2 className="text-xl font-bold text-gray-800 mb-4">{title}</h2>
5      <div className="text-gray-600">{children}</div>
6    </div>
7  )
8}
9
10// Conditional classes
11function Button({ variant, disabled, children }) {
12  return (
13    <button
14      className={`
15        px-4 py-2 rounded-md font-medium
16        ${variant === 'primary' ? 'bg-blue-500 text-white hover:bg-blue-600' : ''}
17        ${variant === 'secondary' ? 'bg-gray-200 text-gray-800 hover:bg-gray-300' : ''}
18        ${disabled ? 'opacity-50 cursor-not-allowed' : ''}
19      `}
20      disabled={disabled}
21    >
22      {children}
23    </button>
24  )
25}

clsx/classnames Library

jsx
1import clsx from 'clsx'
2
3function Button({ variant, size, disabled, children }) {
4  return (
5    <button
6      className={clsx(
7        'rounded-md font-medium',
8        {
9          'bg-blue-500 text-white': variant === 'primary',
10          'bg-gray-200 text-gray-800': variant === 'secondary',
11          'px-2 py-1 text-sm': size === 'small',
12          'px-4 py-2': size === 'medium',
13          'px-6 py-3 text-lg': size === 'large',
14          'opacity-50 cursor-not-allowed': disabled
15        }
16      )}
17    >
18      {children}
19    </button>
20  )
21}

Styled Components

CSS-in-JS library:

bash
1npm install styled-components
jsx
1import styled from 'styled-components'
2
3const Button = styled.button`
4  padding: 10px 20px;
5  border: none;
6  border-radius: 4px;
7  cursor: pointer;
8  background-color: ${props => props.primary ? 'blue' : 'gray'};
9  color: white;
10  
11  &:hover {
12    opacity: 0.9;
13  }
14  
15  &:disabled {
16    opacity: 0.5;
17    cursor: not-allowed;
18  }
19`
20
21const Card = styled.div`
22  background: white;
23  border-radius: 8px;
24  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
25  padding: 20px;
26`
27
28const Title = styled.h2`
29  font-size: 1.5rem;
30  color: #333;
31  margin-bottom: 1rem;
32`
33
34// Usage
35function App() {
36  return (
37    <Card>
38      <Title>Hello World</Title>
39      <Button primary>Primary</Button>
40      <Button>Secondary</Button>
41    </Card>
42  )
43}

Extending Styles

jsx
1const Button = styled.button`
2  padding: 10px 20px;
3  border-radius: 4px;
4`
5
6const PrimaryButton = styled(Button)`
7  background: blue;
8  color: white;
9`
10
11const DangerButton = styled(Button)`
12  background: red;
13  color: white;
14`

Emotion

Another CSS-in-JS library:

bash
1npm install @emotion/react @emotion/styled
jsx
1/** @jsxImportSource @emotion/react */
2import { css } from '@emotion/react'
3import styled from '@emotion/styled'
4
5// css prop
6function Button({ children }) {
7  return (
8    <button
9      css={css`
10        padding: 10px 20px;
11        background: blue;
12        color: white;
13        border: none;
14        border-radius: 4px;
15        
16        &:hover {
17          background: darkblue;
18        }
19      `}
20    >
21      {children}
22    </button>
23  )
24}
25
26// styled API
27const Card = styled.div`
28  background: white;
29  padding: 20px;
30  border-radius: 8px;
31`

CSS Variables with React

jsx
1// Define in CSS
2:root {
3  --primary-color: #3498db;
4  --secondary-color: #2ecc71;
5  --text-color: #333;
6}
7
8// Use in components
9function ThemedButton() {
10  return (
11    <button style={{ backgroundColor: 'var(--primary-color)' }}>
12      Themed Button
13    </button>
14  )
15}
16
17// Dynamic theme switching
18function ThemeProvider({ theme, children }) {
19  return (
20    <div
21      style={{
22        '--primary-color': theme.primary,
23        '--secondary-color': theme.secondary,
24        '--text-color': theme.text
25      }}
26    >
27      {children}
28    </div>
29  )
30}

Comparison

MethodScopedDynamicBundle SizeDX
InlineNoneOK
CSS FilesSmallGood
CSS ModulesSmallGood
TailwindVariesGreat
Styled Components~12KBGreat
Emotion~7KBGreat

Choose based on your team's preferences and project needs!