Styling in Next.js - A beginner's guide

Blog image - Stylowanie w Next.js - Przewodnik dla początkujących

19/12/2023

9 min

Bartosz Lewandowski

Styling in Next.js - A beginner's guide

19/12/2023

9 min

Bartosz Lewandowski

Blog image - Stylowanie w Next.js - Przewodnik dla początkujących

Table of Contents

  1. Scss
  2. Tailwind CSS
  3. StyleX
  4. Summary

Check the previous post: Optimizations in Next.js - How to Speed Up Your Website?

If you are interested in giving your Next.js site a unique and eye-catching look, you've come to the right place! In this post, I will not only present practical styling approaches but also show you how to leverage the full potential of SCSS, Tailwind CSS, and StyleX. Get ready for a solid dose of tips that will make your projects not only beautiful but also functional. You will learn how these tools can completely change your approach to styling and help you achieve the "wow" effect! I invite you to a reading full of inspiration and creative solutions.

Scss

Using scss in Next.js applications is not just a matter of aesthetics but also efficiency and code organization. The Scss preprocessor, with its advanced functionalities such as variables, mixins, and nesting, allows for creating more organized and maintainable CSS code. Scss opens up new possibilities in designing responsive and dynamic user interfaces.

Scss installation

To start working with SCSS in Next.js, we first need to install the appropriate dependencies. For this, we will use pnpm to install sass. Once installed, we can directly start using .scss or .sass files in our project.

pnpm add -D sass

File organization

Organizing style files in a Next.js project is crucial for maintaining order and efficiency. In this context, it's worth applying certain practices that help in managing styles, especially in larger projects.

styles folder in src:

variables.scss: This file serves as a central place for global variables such as colors, typography, breakpoints, etc. Storing these values in one place makes managing them easier and ensures consistency throughout the project.

$breakpoints: (
	"ultra-mini": 350px,
	"mini": 400px,
	"ultra-smaller": 575px,
	"smaller": 768px,
	"small": 1024px,
	"mini-large": 1150px,
	"large": 1300px,
) !default; 
 
//colors
$white: #fff;
$gray: #f4f4f4;
$gray-2: #9699a3;
$gray-3: #e4e6eb;

global.scss: This file can contain global styles that will be applied throughout the application, such as style resets or global rules.

Storing component-related styles:

Separating component styles into two files, base.module.scss and rwd.module.scss, in Next.js projects is a practice that helps maintain code cleanliness and modularity. It allows for better style management, especially in the context of responsiveness. Here's a detailed explanation of this approach:

  1. base.module.scss

Basic component style: This file contains the main styles for a given component. It includes layout, typography, colors, margins, paddings, and other basic visual features. If you're creating a Button component, base.module.scss will contain the style for the button's appearance, such as its size, background color, text color, border, etc.

Organization and code cleanliness: By placing basic styles in a separate file, the code becomes more readable and easier to maintain. Changes regarding the basic appearance of the component are limited to this file only.

Importing variables: In base.module.scss, you can import variables from _variables.scss, which allows you to use global values like colors, font sizes, etc.

  1. rwd.module.scss

Responsive styling: The rwd.module.scss file in the context of Next.js projects is used to update and adjust component styles depending on the device screen size. This is crucial for creating responsive applications that look good and are functional on various types of devices. Here, we adjust layout, size, hiding or displaying elements, etc., on different devices (phones, tablets, laptops, large screens).

Modularity and separation: With this approach, it's easier to manage and maintain styles because responsive changes are isolated from the basic component styles.

Importing variables: In this file, media queries are used, often utilizing breakpoints defined in _variables.scss, to adjust the component's style to different screen sizes.

Example: Suppose you have a Button component that has a default size defined in base.module.scss. In rwd.module.scss, you can specify that on desktop screens, the button should be larger.

Usage example in a component

import Link from "next/link";
import type { CategoryProps } from "./types";
 
import styles from "./rwd.module.scss";
const { wrapper, wrapperTitle } = styles;
 
export const Category = ({ title, pageUrl }: CategoryProps) => {
	return (
		<li className={wrapper}>
			<Link href={`/blog/${pageUrl}`} className={wrapperTitle}>
				{title}
			</Link>
		</li>
	);
};

Scss writing scheme

The scheme presented in the attached image illustrates the CSS organization structure. This layout can be particularly useful in preprocessors like SCSS because it allows for better organization and easier style management. Applying such a scheme has several significant advantages:

  1. Ease of maintenance:
    • It simplifies making and reviewing changes in styles because similar properties are gathered in one place.
  2. Readability:
    • The code becomes more readable for developers, who can quickly understand the style structure without searching the entire file.
  3. Consistency:
    • It facilitates maintaining consistency in styles throughout the application because developers can more easily apply and reuse similar patterns.

Tailwind CSS

Integrating Tailwind CSS with Next.js forms a powerful combination, enabling the creation of responsive and aesthetically advanced web applications. Tailwind CSS, being a utility-first CSS framework, provides flexibility and speed in designing user interfaces. Meanwhile, Next.js, as a React-based framework, offers efficient routing and server-side rendering of components. Combining these two technologies allows for creating efficient, fast, and beautiful web applications.

Installation

In the project directory, execute the following commands:

pnpm add -D tailwindcss postcss autoprefixernpx tailwindcss init -p

This will install Tailwind CSS along with the necessary dependencies.

Configuration

In the tailwind.config.js file, configure the paths to all HTML, JS, JSX, TS, and TSX files where you will use Tailwind:

module.exports = {
	content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
 
	// other
};

In the main CSS file (usually globals.css), import Tailwind styling:

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities'

Writing styles with Tailwind CSS

Tailwind CSS is a utility-based CSS framework, which means styling elements is done by adding classes directly in the HTML, JSX, or TSX code. Here's how to do it:

  1. Understanding utility classes: Tailwind uses utility classes for everything from margins and paddings to colors and fonts. For example, the text-center class is used to center text, and bg-blue-500 gives an element a blue background.
  2. Applying classes in components: To apply a style, simply add the appropriate classes to the elements. For example:
<button className="bg-blue-500 text-white font-bold py-2 px-4 rounded">  Click me</button>
  1. Responsiveness: Tailwind includes responsive variants for most classes, which can be activated using prefixes like md:, lg:, etc. For example, md:bg-red-500 changes the background to red only on medium and larger screens.
  2. Customization: You can customize the Tailwind configuration to add your own colors, sizes, etc. This can be done by editing the tailwind.config.js file.

StyleX

StyleX is an innovative styling system that combines the convenience of CSS-in-JS libraries with the performance and scalability of static CSS. It is carefully designed to meet the demands of large applications, reusable component libraries, and statically typed code.

Key Features of StyleX:

  1. Expressiveness and Determinism: StyleX supports a rich subset of CSS, avoiding complex selectors and ensuring no specificity conflicts in the generated CSS.
  2. Optimization and Organization: Transforms and optimizes styles into "atomic" CSS class names, eliminating the need to manage separate utility classes.
  3. Style Merging: Allows merging styles across file and component boundaries, ideal for component libraries enabling customization.
  4. Type Safety: StyleX is fully typed, offering tools for precisely controlling acceptable properties and values in components.
  5. Benefits of StyleX:
  6. Speed: StyleX provides high performance both during compilation and at runtime.
  7. Scalability: It excels in large codebases, minimizing the size of CSS bundles.
  8. Predictability: Automatically manages CSS selector specificity, ensuring reliable style application.

How StyleX Works?

StyleX is a toolkit that includes a Babel plugin, a small runtime library, an ESLint plugin, and integrations with bundlers and frameworks. The key component is the Babel plugin, which finds, extracts, and transforms styles into atomic class names at compile time.

Installation

To our NextJS application, we need to add a few dependencies to run StyleX:

pnpm add @stylexjs/stylex @stylexjs/open-props @stylexjs/babel-plugin @stylexjs/nextjs-plugin
  1. @stylexjs/open-props: Packaged CSS (e.g., colors, fonts) used with StyleX, facilitating the creation of a consistent design.
  2. @stylexjs/babel-plugin: A Babel plugin enabling StyleX integration with the Babel configuration in the project.
  3. @stylexjs/nextjs-plugin: A Next.js plugin supporting StyleX, allowing easy integration with custom Babel configurations in Next.js.

Configuration

Create a new .babelrc.js file in the root directory of the NextJS application with the following configuration:

module.exports = {
	presets: ["next/babel"],
	plugins: [
		[
			"@stylexjs/babel-plugin",
			{
				dev: process.env.NODE_ENV === "development",
				runtimeInjection: false,
				genConditionalClasses: true,
				treeshakeCompensation: true,
				unstable_moduleResolution: { type: "commonJS", rootDir: __dirname },
			},
		],
	],
};

Configure the next.config.js file to use StyleX via the @stylexjs/nextjs-plugin:

/** @type {import('next').NextConfig} */ const stylexPlugin = require("@stylexjs/nextjs-plugin");
const nextConfig = { pageExtensions: ["js", "jsx", "ts", "tsx"] };
module.exports = stylexPlugin({ rootDir: __dirname })(nextConfig);

Creating styles

After installing StyleX, you can start creating styles for your components. StyleX uses an approach similar to CSS-in-JS, allowing you to define styles directly in components.

Sample styles:

import stylex from "@stylexjs/stylex";
const styles = stylex.create({
	button: {
		backgroundColor: "blue",
		color: "white",
		padding: "10px 15px",
		borderRadius: "5px",
		":hover": { backgroundColor: "darkblue" },
	},
});
export const Button = () => {
	return <button className={stylex(styles.button)}>Click Me</button>;
};

Dynamic Styling StyleX also allows dynamic style changes based on component properties or state. You can define a function that returns the appropriate set of styles.

export const Button = ({ primary }: ButtonProps) => {
	const dynamicStyle = stylex(styles.button, { backgroundColor: primary ? "navy" : "gray" });
	return <button className={dynamicStyle}>Click Me</button>;
};

Summary

In summary, you now know that Next.js offers three main styling methods: SCSS, Tailwind CSS, and StyleX. SCSS gives you control and advanced capabilities in managing CSS. Tailwind CSS, on the other hand, brings speed and simplicity with utility classes, making it great for quick and efficient projects. StyleX is a hybrid approach that combines the benefits of CSS-in-JS with the performance of static CSS, ideal for complex applications. These styling methods are the key to creating unique and functional interfaces in your Next.js projects.

This is the last post in the introductory series to Next.JS. If you stumbled upon this by accident, I would like to strongly encourage you to go through this path from the very beginning, starting with Introduction to Next.js 13 and its Innovations. I hope my guides have shown you how great a framework Next.js is and why it will revolutionize the e-commerce market.

Frequently Asked Questions

  1. What are the advantages of using SCSS in Next.js? SCSS provides advanced features such as variables, mixins, nesting, which make it easier to create organized and maintainable CSS code. This allows for more efficient design of responsive user interfaces.
  2. Do I need additional dependencies to work with SCSS in Next.js? Yes, to use SCSS in Next.js, you need to install sass using the command pnpm add -D sass.
  3. How can I organize SCSS files in a Next.js project? It is recommended to create a styles folder in /src, with files such as _variables.scss for global variables and global.scss for global styles. It is beneficial for each component to have base.module.scss and rwd.module.scss files to help maintain code cleanliness and modularity.
  4. How does StyleX differ from other styling systems? StyleX combines the convenience of CSS-in-JS with the performance of static CSS. It is ideal for large applications and component libraries, offering expressiveness, optimization, scalability, and type safety.
  5. What is Tailwind CSS and how can it be integrated with Next.js? Tailwind CSS is a utility-first CSS framework that enables rapid user interface design. It can be integrated with Next.js by installing pnpm add -D tailwindcss postcss autoprefixer and configuring the tailwind.config.js file.
  6. How can I install and configure StyleX in a Next.js project? To run StyleX, we need to add a few dependencies pnpm add @stylexjs/stylex @stylexjs/open-props @stylexjs/babel-plugin @stylexjs/nextjs-plugin. Configuration includes modifications to the .babelrc.js and next.config.js files in the root directory of the application.
  7. Does StyleX allow for dynamic styling? Yes, StyleX allows for dynamic style changes based on component properties or state, providing great flexibility in user interface design.
  8. What are the main benefits of using Tailwind CSS in Next.js? Tailwind CSS offers speed and flexibility in user interface design thanks to utility classes. It allows for easy creation of responsive applications and is well integrated with Next.js.
  9. Is StyleX suitable for every project? StyleX is particularly useful in large applications and projects with reusable components. However, it may be overly complex for smaller projects, where simpler solutions may be more appropriate.
Bartosz Lewandowski

Bartosz Lewandowski

CEO

Newsletter