Lesson 05-Next.js Application Routing-Styling

CSS

Global Styles

Global style files are typically placed in the project’s root directory or included in the _app.js file to ensure all pages can access these styles.

Example Code

Create a global style file globals.css:

// styles/globals.css
body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
}

Import the global style file in _app.js:

// pages/_app.js
import "../styles/globals.css";

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;

Local Styles

Local style files are associated with specific components and only affect that component and its children.

Create a local style file page.css:

// styles/page.css
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

Import the local style file in a component:

// app/page.js
import "./styles/page.css";

export default function Page() {
  return (
    <div className="container">
      <h1>Welcome to My App</h1>
      <p>This is a styled component using local CSS.</p>
    </div>
  );
}

Notes

  • When importing CSS files in components, Next.js automatically handles style injection.
  • To share styles across multiple components, create a separate CSS file and import it in the required components.
  • For dynamically generated pages, ensure styles are correctly imported during server-side rendering.

Example Code

Assume a simple page component page.js that needs local styles.

Create Style File

// styles/page.css
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

Import Styles in Component

// app/page.js
import "./styles/page.css";

export default function Page() {
  return (
    <div className="container">
      <h1>Welcome to My App</h1>
      <p>This is a styled component using local CSS.</p>
    </div>
  );
}

CSS Modules

Steps

  1. Create CSS File: Create a .module.css file containing the desired styles.
  2. Import CSS File: Use an import statement in your component to import the .module.css file.
  3. Use Class Names: Apply class names using the imported styles object in your component.

Example Code

Create CSS File (page.module.css)

// styles/page.module.css
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

Import CSS File (app/page.js)

// app/page.js
import styles from "../styles/page.module.css";

export default function Page() {
  return (
    <div className={styles.container}>
      <h1>Welcome to My App</h1>
      <p>This is a styled component using CSS Modules.</p>
    </div>
  );
}

Explanation

  • .module.css File: Class names in this file are transformed into unique class names to prevent style conflicts.
  • import styles: The styles object contains keys corresponding to class names in the CSS file and values as unique class names.
  • className={styles.container}: Use the properties of the styles object as class names in JSX.

Additional Details

  • Class Name Mapping: Inspect the compiled CSS to see how original class names map to generated ones.
  • Dynamic Class Names: Use template literals or conditional expressions to dynamically apply class names.
  • Multiple Imports: If multiple components import the same CSS file, Next.js merges these styles to avoid duplicate loading.
// app/page.js
import styles from "../styles/page.module.css";

export default function Page() {
  const isDarkMode = true; // Assume this is a state or context value

  return (
    <div className={isDarkMode ? styles.darkContainer : styles.container}>
      <h1>Welcome to My App</h1>
      <p>This is a styled component using CSS Modules.</p>
    </div>
  );
}

SCSS/SASS

Using SCSS/SASS

Install Dependencies

Install the required preprocessor compiler for SCSS/SASS using the sass package.

npm install sass

Create SCSS File

Create an SCSS file, e.g., page.scss.

// styles/page.scss
$primary-color: #ff6347;

body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  color: $primary-color;
}

Import SCSS File in Component

Import the SCSS file directly in your component.

// app/page.js
import "../styles/page.scss";

export default function Page() {
  return (
    <div className="container">
      <h1>Welcome to My App</h1>
      <p>This is a styled component using SCSS/SASS.</p>
    </div>
  );
}

SCSS/SASS Example

Install Dependencies

npm install sass

Create SCSS File

// styles/page.scss
$primary-color: #ff6347;

body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  color: $primary-color;
}

Import SCSS File in Component

// app/page.js
import "../styles/page.scss";

export default function Page() {
  return (
    <div className="container">
      <h1>Welcome to My App</h1>
      <p>This is a styled component using SCSS/SASS.</p>
    </div>
  );
}

LESS

Using LESS

Install Dependencies

Install less and less-loader for LESS support.

npm install less less-loader

Create LESS File

Create a LESS file, e.g., page.less.

// styles/page.less
@primary-color: #ff6347;

body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  color: @primary-color;
}

Import LESS File in Component

Import the LESS file directly in your component.

// app/page.js
import "../styles/page.less";

export default function Page() {
  return (
    <div className="container">
      <h1>Welcome to My App</h1>
      <p>This is a styled component using LESS.</p>
    </div>
  );
}

LESS Example

Install Dependencies

npm install less less-loader

Create LESS File

// styles/page.less
@primary-color: #ff6347;

body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  color: @primary-color;
}

Import LESS File in Component

// app/page.js
import "../styles/page.less";

export default function Page() {
  return (
    <div className="container">
      <h1>Welcome to My App</h1>
      <p>This is a styled component using LESS.</p>
    </div>
  );
}

styled-components

styled-components is a popular CSS-in-JS solution that allows defining styles using JavaScript and template literals.

Install Dependencies

Install styled-components.

npm install styled-components

Example Code

// app/page.js
import styled from 'styled-components';

const Container = styled.div`
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  color: #ff6347;
`;

export default function Page() {
  return (
    <Container>
      <h1>Welcome to My App</h1>
      <p>This is a styled component using styled-components.</p>
    </Container>
  );
}

Tailwind CSS

Tailwind CSS is a utility-first CSS framework providing composable class names for rapid custom design.

Install Dependencies

Install Tailwind CSS and PostCSS.

npm install tailwindcss postcss autoprefixer

Initialize Tailwind CSS.

npx tailwindcss init

Configure Tailwind CSS

Create a tailwind.config.js file to configure Tailwind CSS.

// tailwind.config.js
module.exports = {
  content: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
};

Example Code

// app/page.js
export default function Page() {
  return (
    <div className="container mx-auto p-4">
      <h1 className="text-3xl font-bold">Welcome to My App</h1>
      <p className="text-gray-600">This is a styled component using Tailwind CSS.</p>
    </div>
  );
}

Combining styled-components and Tailwind CSS

While styled-components and Tailwind CSS are typically distinct styling approaches, you can combine them. For example, use styled-components for reusable components and Tailwind CSS’s utility classes for quick layout and style adjustments.

// app/page.js
import styled from 'styled-components';
import tw from 'twin.macro'; // Use Twin.macro as a bridge

const Container = styled.div`
  ${tw`max-w-2xl mx-auto p-4`}
  color: #ff6347;
`;

export default function Page() {
  return (
    <Container>
      <h1 className="text-3xl font-bold">Welcome to My App</h1>
      <p className="text-gray-600">This is a styled component using styled-components and Tailwind CSS.</p>
    </Container>
  );
}

Notes

  • Ensure your project configuration supports both styled-components and Tailwind CSS.
  • For Tailwind CSS, verify that PostCSS is correctly configured.
  • If using a custom Webpack configuration, you may need to manually configure loaders for these files.
  • Consider using @emotion/styled as an alternative to styled-components for better integration with Next.js.

CSS-in-JS (using styled-jsx)

In Next.js, styled-jsx is a CSS-in-JS solution that allows defining styles within components. It provides a simple way to add styles that work correctly on both client and server.

Using styled-jsx

// app/page.js
export default function Page() {
  return (
    <div className="container">
      <style jsx>{`
        .container {
          max-width: 800px;
          margin: 0 auto;
          padding: 20px;
          color: #ff6347;
        }
      `}</style>
      <h1>Welcome to My App</h1>
      <p>This is a styled component using styled-jsx.</p>
    </div>
  );
}

Explanation

  • <style jsx>: Use the <style jsx> tag in JSX to define styles. These styles are compiled into scoped class names, affecting only the current component and its children.
  • Style Block: CSS code within the style block should be defined using template literals {“}.

Notes

  • Scoped Styles: Styles generated by styled-jsx are scoped, preventing conflicts with other components.
  • Dynamic Styles: Dynamically modify styles using template literals or conditional expressions.
  • Global Styles: Use the <style global> tag to define global styles.
// app/page.js
export default function Page() {
  const isDarkMode = true; // Assume this is a state or context value

  return (
    <div className="container">
      <style jsx>{`
        .container {
          max-width: 800px;
          margin: 0 auto;
          padding: 20px;
          color: ${isDarkMode ? '#fff' : '#ff6347'};
          background-color: ${isDarkMode ? '#333' : '#fff'};
        }
      `}</style>
      <h1>Welcome to My App</h1>
      <p>This is a styled component using styled-jsx.</p>
    </div>
  );
}

Using styled-jsx for Global Styles

To define global styles, use the <style global> tag.

// app/page.js
export default function Page() {
  return (
    <>
      <style jsx global>{`
        body {
          font-family: Arial, sans-serif;
          background-color: #f4f4f4;
        }
      `}</style>

      <div className="container">
        <style jsx>{`
          .container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            color: #ff6347;
          }
        `}</style>
        <h1>Welcome to My App</h1>
        <p>This is a styled component using styled-jsx.</p>
      </div>
    </>
  );
}

Summary

  • Scoped Styles: styled-jsx provides scoped styles, avoiding global style conflicts.
  • Dynamic Styles: Styles can be dynamically modified based on conditions.
  • Global Styles: Use <style global> to define global styles.
Share your love