← Back to Course Overview

Module 4 - Advanced Styling Techniques

Introduction to Styled Components

Learn about the styled-components library and how it enables CSS-in-JS styling.

Styled Components is a popular CSS-in-JS library for React that allows you to write actual CSS code to style your components while keeping the styles scoped to the component. This helps eliminate many of the problems with traditional CSS, such as class name collisions, specificity issues, and the need for separate CSS files.

Key benefits of using styled-components include:

To get started with styled-components, first install the library:

npm install styled-components

Creating and Using Styled Components

Master the creation and usage of styled components in your React applications.

Creating a styled component is as simple as importing the styled object from the library and using it to create components with CSS. The styled object has methods for all HTML elements, which you can call and pass a template literal with CSS rules.

Here's a basic example of creating and using styled components:

import styled from 'styled-components';

// Create a styled button component
const Button = styled.button`
  background-color: #ff5722;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  
  &:hover {
    background-color: #ff7043;
  }
`;

// Create a styled heading component
const Heading = styled.h1`
  color: #333;
  font-size: 2rem;
  margin-bottom: 20px;
`;

// Use the styled components in your React component
function App() {
  return (
    <div>
      <Heading>Hello World</Heading>
      <Button>Click Me</Button>
    </div>
  );
}

Notice how you can use all the regular CSS syntax inside the template literal, including pseudo-selectors like &:hover. The ampersand (&) is a reference to the component itself, which makes it easy to create nested styles.

Dynamic Styling with Props

Learn how to create dynamic styles using props in styled components.

One of the most powerful features of styled-components is the ability to adapt styling based on props. You can make your styles dynamic by passing props to the styled components and using these props inside the template literals to determine styles.

Here's an example of dynamic styling using props:

import styled from 'styled-components';

// Create a Button with dynamic styling
const Button = styled.button`
  background-color: ${props => props.primary ? '#ff5722' : 'transparent'};
  color: ${props => props.primary ? 'white' : '#ff5722'};
  border: 2px solid #ff5722;
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-size: ${props => props.large ? '18px' : '14px'};
  margin: 5px;
  
  &:hover {
    background-color: ${props => props.primary ? '#ff7043' : '#ffebee'};
  }
`;

// Use buttons with different props
function App() {
  return (
    <div>
      <Button>Normal Button</Button>
      <Button primary>Primary Button</Button>
      <Button large>Large Button</Button>
      <Button primary large>Large Primary Button</Button>
    </div>
  );
}

You can also extend existing styled components to create variations:

// Extend the Button to create a new variant
const DangerButton = styled(Button)`
  background-color: ${props => props.primary ? '#f44336' : 'transparent'};
  border-color: #f44336;
  color: ${props => props.primary ? 'white' : '#f44336'};
  
  &:hover {
    background-color: ${props => props.primary ? '#e53935' : '#ffebee'};
  }
`;

Theme Provider and Global Styles

Understand how to use ThemeProvider and create global styles in your application.

Styled Components offers a ThemeProvider wrapper component that allows you to inject a theme into all styled components anywhere in your application. This is incredibly useful for creating consistent styling across your app and for implementing features like dark mode.

Here's an example of using ThemeProvider:

import styled, { ThemeProvider } from 'styled-components';

// Define your theme
const theme = {
  primary: '#ff5722',
  secondary: '#2196f3',
  danger: '#f44336',
  text: {
    light: '#ffffff',
    dark: '#333333'
  },
  spacing: {
    small: '8px',
    medium: '16px',
    large: '24px'
  }
};

// Create styled components that use the theme
const Button = styled.button`
  background-color: ${props => props.theme.primary};
  color: ${props => props.theme.text.light};
  padding: ${props => props.theme.spacing.small} ${props => props.theme.spacing.medium};
  border: none;
  border-radius: 4px;
  cursor: pointer;
`;

// Apply the theme to your app
function App() {
  return (
    <ThemeProvider theme={theme}>
      <div>
        <h1>Themed Components</h1>
        <Button>Themed Button</Button>
      </div>
    </ThemeProvider>
  );
}

You can also create global styles using the createGlobalStyle helper:

import { createGlobalStyle } from 'styled-components';

const GlobalStyles = createGlobalStyle`
  * {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
  
  body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f5f5f5;
    color: #333;
    line-height: 1.6;
  }
  
  a {
    color: ${props => props.theme.primary};
    text-decoration: none;
  }
`;

// Include GlobalStyles at the top level of your app
function App() {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyles />
      <div>
        <h1>App with Global Styles</h1>
        <!-- Rest of your app -->
      </div>
    </ThemeProvider>
  );
}

Animations and Advanced Techniques

Learn how to create animations and implement advanced styling techniques.

Styled Components provides a keyframes helper for creating CSS animations. You can define your animations and then use them in your styled components.

import styled, { keyframes } from 'styled-components';

// Create a keyframes animation
const fadeIn = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`;

const slideIn = keyframes`
  from {
    transform: translateY(-20px);
  }
  to {
    transform: translateY(0);
  }
`;

// Use the animation in a styled component
const AnimatedBox = styled.div`
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  animation: ${fadeIn} 0.5s ease-out, ${slideIn} 0.5s ease-out;
`;

// Create a Spinner component with rotation animation
const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

const Spinner = styled.div`
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #ff5722;
  border-radius: 50%;
  animation: ${rotate} 1s linear infinite;
  margin: 20px auto;
`;

Advanced techniques include:

// Adding attributes with .attrs
const Input = styled.input.attrs(props => ({
  type: props.type || 'text',
  placeholder: props.placeholder || 'Enter text...',
  required: props.required || false,
}))`
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  width: 100%;
  margin-bottom: 10px;
`;

// Responsive design with media queries
const Container = styled.div`
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
  
  @media (max-width: 768px) {
    padding: 10px;
  }
`;

// Targeting child components
const Card = styled.div`
  padding: 20px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  
  ${Button} {
    margin-top: 10px;
  }
`;

Module Project

Apply your knowledge by building a React application with advanced styling techniques using styled-components.

Additional Resources