Course
CSS-in-JS
Next.js Mastery: From Fundamentals to Full-Stack
Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.
CSS-in-JS
Introduction
CSS-in-JS refers to the technique of writing CSS directly within JavaScript files instead of using separate
.css
, .scss
, or other stylesheet files. This allows you to leverage JavaScript features like variables, functions, and conditional logic within your CSS.The popularity of CSS-in-JS is closely tied to the rise of frameworks like React and Vue, where the concept of "components" has become central. While Vue has its own CSS solutions, React does not, making CSS-in-JS more prevalent in the React ecosystem.
Popular CSS-in-JS libraries supported in Next.js client components include:
If you need to style server components, it’s recommended to use CSS modules or other solutions that output CSS files, such as PostCSS or Tailwind CSS.
Configuration in Next.js
Configuring CSS-in-JS in Next.js generally involves three main steps:
- Create a style registry that holds all CSS rules during rendering.
- Use the
useServerInsertedHTML
hook to inject these CSS rules before content is rendered. - Wrap your application in a client component that includes the style registry.
Using styled-jsx
Let’s walk through these steps using
styled-jsx
as an example. Note that you need to use at least version 5.1.0
of styled-jsx
in client components.Step 1: Create a Style Registry
'use client';// app/registry.jsimport React, { useState } from 'react';import { useServerInsertedHTML } from 'next/navigation';import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
export default function StyledJsxRegistry({ children }) { const [jsxStyleRegistry] = useState(() => createStyleRegistry());
useServerInsertedHTML(() => { const styles = jsxStyleRegistry.styles(); jsxStyleRegistry.flush(); return <>{styles}</>; });
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>;}
Step 2: Wrap the Root Component
// app/layout.jsimport StyledJsxRegistry from './registry';
export default function RootLayout({ children }) { return ( <html> <body> <StyledJsxRegistry>{children}</StyledJsxRegistry> </body> </html> );}
Step 3: Use
styled-jsx
in a Pageexport default function Page() { return ( <div> <div className="container">text</div>
<style jsx>{` .container { display: grid; grid-template-columns: repeat(1, minmax(0, 1fr)); gap: 1.5rem /* 24px */; }
@media (min-width: 1024px) { .container { grid-template-columns: repeat(3, minmax(0, 1fr)); } } `}</style> </div> );}
Using Styled Components
The setup for
styled-components
follows a similar approach. Make sure you’re using styled-components@6
or later.Step 1: Create a Global Style Registry
'use client';// lib/registry.jsimport React, { useState } from 'react';import { useServerInsertedHTML } from 'next/navigation';import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
export default function StyledComponentsRegistry({ children }) { const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
useServerInsertedHTML(() => { const styles = styledComponentsStyleSheet.getStyleElement(); styledComponentsStyleSheet.instance.clearTag(); return <>{styles}</>; });
if (typeof window !== 'undefined') return <>{children}</>;
return ( <StyleSheetManager sheet={styledComponentsStyleSheet.instance}> {children} </StyleSheetManager> );}
Step 2: Wrap the Root Component
// app/layout.jsimport StyledComponentsRegistry from './lib/registry';
export default function RootLayout({ children }) { return ( <html> <body> <StyledComponentsRegistry>{children}</StyledComponentsRegistry> </body> </html> );}
Step 3: Use Styled Components in a Page
'use client';
import styled from 'styled-components';
const Container = styled.div` display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem /* 24px */;`;
const SkeletonInner = styled.div` padding: 1rem /* 16px */; background-color: rgb(24 24 27 / 0.8); border-radius: 1rem /* 16px */;`;
const SkeletonImg = styled.div` height: 3.5rem /* 56px */; border-radius: 0.5rem /* 8px */; background-color: rgb(63 63 70 / 1);`;
const SkeletonBtn = styled.div` margin-top: 0.75rem /* 12px */; width: 25%; height: 0.75rem /* 12px */; border-radius: 0.5rem /* 8px */; background-color: rgb(255 0 128 / 1);`;
const Skeleton = () => ( <SkeletonInner> <SkeletonImg /> <SkeletonBtn /> </SkeletonInner>);
export default function Page() { return ( <div className="space-y-4"> <h1 className="text-xl font-medium text-gray-400/80"> Styled with Styled Components </h1> <Container> <Skeleton /> <Skeleton /> <Skeleton /> </Container> </div> );}