Lesson 12-Next.js Page Routing-Styling

CSS

Global Styles

Global style files are typically placed in the project root or imported 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 typically 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 the 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 where needed.
  • 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 the 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 the Style in the 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 a CSS File: Create a .module.css file containing the styles you want to use.
  2. Import the CSS File: Use an import statement in your component to import the .module.css file.
  3. Use Class Names: Apply class names using the object imported from the .module.css file.

Example Code

Create the 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 the 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, with values being the 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 file to see how original class names map to generated ones.
  • Dynamic Class Names: Use template literals or conditional expressions to dynamically change class names.
  • Multiple Imports: If a CSS file is imported by multiple components, Next.js automatically 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 necessary preprocessor compiler. For SCSS/SASS, use the sass package.

npm install sass

Create an 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 the SCSS File in a 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 an SCSS File

$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 the SCSS File in a 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

For LESS, install less and less-loader.

npm install less less-loader

Create a 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 the LESS File in a 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 a 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 the LESS File in a 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 you to define 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 that provides a set of composable class names for rapidly building custom designs.

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 considered distinct styling approaches, you may combine them in some cases. For example, use styled-components to create reusable components and leverage Tailwind CSS 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 in your project.
  • If using a custom Webpack configuration, you may need to manually configure loaders to handle these files.
  • When using styled-components, consider @emotion/styled as an alternative, as it integrates better with Next.js.

CSS-in-JS (Using styled-jsx)

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

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 and only affect the current component and its children.
  • Style Block: Define CSS code within template literals {``}.

Notes

  • Scoped Styles: Styles generated by styled-jsx are scoped locally, preventing conflicts with other components.
  • Dynamic Styles: Dynamically change styles based on conditions 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 Global Styles with styled-jsx

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 locally scoped styles to avoid global style conflicts.
  • Dynamic Styles: Dynamically change styles based on conditions.
  • Global Styles: Use the <style global> tag to define global styles.

Share your love