Inline Styles

Apply styles directly to elements using the style attribute, but it takes a Javascript object instead of a string unlike HTML inline CSS

  • Styles are scoped to element automatically
  • No media queries
  • No pseudo-classes (:hover, :focus, etc.).
  • CSS properties are camelCase for inline styling in JSX
// JSS

const styleObj = {
    backgroundColor: 'blue', 
    color: 'white', 
    padding: '10px'
}

function Button() {
  return (      // style attribute accepts a Javascript object
    <button style={{ backgroundColor: 'blue', color: 'white', padding: '10px' }}>Click Me</button>
    <button style={styleObj}>Click Me</button>
  );
}

Regular CSS Stylesheets

Like normal external CSS files, you can import it into your components

  • Exactly the same as normal CSS
  • Good for global styles
  • Same rule of CSS where last imported css file override previous ones
// JSS

// In App.jsx
import './App.css';            // Global css rules
import Child from './Child';    // Child.css will override App.css because it's imported after

function App() {
  return (
    <div className='main-container'>
      <Child />
    </div>
  );
}

// In Child.jsx
import './Child.css';

function Child() {
  return <button className='button'>Child Button</button>;
}

CSS Modules

Write CSS rules in *.module.css file and scope styles to component automatically

  • Do NOT use id selectors in */module.css
  • Class names should be camelCase otherwise assigning the hyphen will result in an error when assigning a class from a module.css file
  • Syntax of CSS module files are exactly the same as normal CSS files
  • Styles are automatically scoped so no naming conflicts
  • Harder to share global styles unless combined with normal .css files
// JSX

import styles from './Button.module.css';

function Button() {
  return <button className={styles.btn}>Click Me</button>;
}

function Button2() {
  return  <button className={`${styles.example} ${styles.hoverExample}`}>Click Me</button>;
}

Setting up dark mode css variables in module.css :

// CSS
:global([data-theme="dark"]) {
    --example-bg-color: #222222;
    --example-border-color: #dfdfdf;
}
  • The module.css will OVERRIDE any naming conflict with the global.css and will be persistent even after user leave the page

Styled Components (CSS-in-JS)

Uses external libraries to write styles inside the Javascript file and attach them to components

  • Scoped styles automatically
  • Supports props for dynamic styling
  • Harder to separate styles from logic so avoid if planning for mobile development afterward
  • Uses backtick ` to declare style
// JSX

import styled from 'styled-components';

const Button = styled.button`
  background-color: blue;
  color: white;
  padding: 10px;
  border-radius: 8px;

  &:hover {
    background-color: darkblue;
  }
`;

function App() {
  return <Button>Click Me</Button>;
}

Tailwind CSS

Styles are directly defined onto the class names

  • Fast UI
  • Consistent design system
  • JSX will become cluttered with classes
// JSX
function Button() {
  return (
    <button className='bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-700'>
      Click Me
    </button>
  );
}