Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
Write CSS as JavaScript objects or template literals
Styles scoped to components automatically
Dynamic styling based on props/state
Popular libraries: styled-components, Emotion
No separate CSS files needed
Used by major companies (Netflix, Airbnb)
.css files, you write it directly in your JavaScript. This keeps styles right next to the components they style, makes styles dynamic, and automatically scopes them to prevent conflicts!.css files.button {
background: blue;
padding: 10px;
}const Button = styled.button`
background: blue;
padding: 10px;
`;Most popular CSS-in-JS library. Uses tagged template literals.
40M+ downloads/monthHigh-performance CSS-in-JS. Similar to styled-components but faster.
15M+ downloads/monthUsed by Material-UI. CSS as JavaScript objects.
10M+ downloads/monthZero-runtime CSS-in-TypeScript. Generates static CSS.
Modern, type-safenpm install styled-components
# TypeScript users
npm install @types/styled-components -Dimport styled from 'styled-components';
// Create a styled button
const Button = styled.button`
background: #3b82f6;
color: white;
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
&:hover {
background: #2563eb;
}
`;
// Use it like a regular component
function App() {
return (
<Button>Click Me</Button>
);
}// Button that changes based on props
const Button = styled.button`
background: ${props => props.primary ? '#3b82f6' : '#6b7280'};
color: white;
padding: ${props => props.large ? '16px 32px' : '12px 24px'};
border: none;
border-radius: 6px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
`;
// Usage with different props
function App() {
return (
<>
<Button primary>Primary Button</Button>
<Button>Secondary Button</Button>
<Button primary large>Large Primary</Button>
<Button disabled>Disabled</Button>
</>
);
}// Base button
const Button = styled.button`
padding: 12px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
`;
// Extend the base button
const PrimaryButton = styled(Button)`
background: #3b82f6;
color: white;
`;
const DangerButton = styled(Button)`
background: #ef4444;
color: white;
`;
// Usage
function App() {
return (
<>
<PrimaryButton>Save</PrimaryButton>
<DangerButton>Delete</DangerButton>
</>
);
}npm install @emotion/react @emotion/styled
# Usage with styled API (similar to styled-components)
import styled from '@emotion/styled';
const Button = styled.button`
background: #3b82f6;
color: white;
padding: 12px 24px;
`;/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
// Use css prop directly on elements
function Button() {
return (
<button
css={css`
background: #3b82f6;
color: white;
padding: 12px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
&:hover {
background: #2563eb;
}
`}
>
Click Me
</button>
);
}import styled from 'styled-components';
// Styled components
const CardContainer = styled.div`
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
&:hover {
transform: translateY(-4px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
`;
const CardTitle = styled.h3`
margin: 0 0 12px 0;
font-size: 20px;
color: #1f2937;
`;
const CardContent = styled.p`
margin: 0 0 16px 0;
color: #6b7280;
line-height: 1.6;
`;
const CardButton = styled.button`
background: ${props => props.variant === 'primary' ? '#3b82f6' : '#6b7280'};
color: white;
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
`;
// Use the styled components
function Card({ title, content }) {
return (
<CardContainer>
<CardTitle>{title}</CardTitle>
<CardContent>{content}</CardContent>
<CardButton variant="primary">Read More</CardButton>
</CardContainer>
);
}
export default Card;💡 Modern Alternative: Consider Tailwind CSS or CSS Modules for simpler projects. Use CSS-in-JS when you need highly dynamic styling based on props/state.
import { ThemeProvider } from 'styled-components';
// Define your theme
const lightTheme = {
colors: {
primary: '#3b82f6',
background: '#ffffff',
text: '#1f2937',
},
};
const darkTheme = {
colors: {
primary: '#3b82f6',
background: '#1f2937',
text: '#f3f4f6',
},
};
// Styled component using theme
const Button = styled.button`
background: ${props => props.theme.colors.primary};
color: white;
padding: 12px 24px;
`;
const Container = styled.div`
background: ${props => props.theme.colors.background};
color: ${props => props.theme.colors.text};
min-height: 100vh;
`;
// Use ThemeProvider
function App() {
const [isDark, setIsDark] = useState(false);
return (
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<Container>
<Button onClick={() => setIsDark(!isDark)}>
Toggle Theme
</Button>
</Container>
</ThemeProvider>
);
}Component-based styling works great with React
Styles that change based on props/state
Themeable component libraries
Type-safe styling with prop validation
shouldForwardProp to avoid prop forwardingTailwind CSS: Utility-first CSS (no runtime, static)
CSS Modules: Scoped CSS without JavaScript (built into Next.js)
Vanilla Extract: Zero-runtime CSS-in-TypeScript
Panda CSS: Build-time CSS-in-JS (no runtime)