next.js-tutorial

Next.js CSS Support

We can utilise the built-in CSS-in-js library styled-jsx in Next.js. Within a react component, CSS can be written, and these styles are scoped to the component. We’ll create a container object in this example, which will be used to encapsulate and style other components.

To showcase this notion, we’ll create a components directory at the root level and add a container.module.css file using the following code:

.container {
   max-width: 36rem;
   padding: 0 1rem;
   margin: 3rem auto 6rem;
   border: 1px solid red;  
}

Now we will create a container.JS file in the components directory with the following code:

import styles from './container.module.css'

function Container({ children }) {
   return <div className={styles.container}>{children}</div>
}

export default Container

Now we will use the container component as the code below in the first.js file.

import Link from 'next/link'
import Head from 'next/head'
import Container from '../../components/container'

export default function FirstPost() {
   return (
      <>
         <Container>
            <Head>
               <title>My First Post</title>
            </Head>
            <h1>My First Post</h1>
            <h2>
            <Link href="/">
               <a>Home</a>
            </Link>
            </h2>
         </Container>
      </>	  
   )
}

Starting the Next.JS Server

We will use the following code to start the next.js server.

npm run dev

Built-In CSS Support

Next.js allows you to import CSS files from a JavaScript file. This is possible because Next.js extends the concept of import beyond JavaScript.

Adding a Global CSS Stylesheet

To add a stylesheet to your application, import the CSS file within pages/_app.js.

For example, consider the following stylesheet named styles.css:

body {
  font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
    'Arial', sans-serif;
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

Create a pages/_app.js file if not already present. Then, import the styles.css file.

import '../styles.css'

// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}


These styles (styles.css) will be applied to all of the pages and components in your application. Because of their global nature and to avoid conflicts, stylesheets can only be imported inside pages/ app.js.

In development, this method of expressing stylesheets allows you to keep the application state by having your styles hot reloaded as you make changes. In production, all CSS files will be concatenated into a single minified.css file.

Import styles from “node_modules”

For global stylesheets, like bootstrap or nprogress, you should import the file inside pages/_app.js. For example:

// pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'

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

For importing CSS required by a third party component, you can do so in your component. For example:

// components/ExampleDialog.js
import { useState } from 'react'
import { Dialog } from '@reach/dialog'
import VisuallyHidden from '@reach/visually-hidden'
import '@reach/dialog/styles.css'

function ExampleDialog(props) {
  const [showDialog, setShowDialog] = useState(false)
  const open = () => setShowDialog(true)
  const close = () => setShowDialog(false)

  return (
    <div>
      <button onClick={open}>Open Dialog</button>
      <Dialog isOpen={showDialog} onDismiss={close}>
        <button className="close-button" onClick={close}>
          <VisuallyHidden>Close</VisuallyHidden>
          <span aria-hidden>×</span>
        </button>
        <p>Hello there. I am a dialog</p>
      </Dialog>
    </div>
  )
}

Next.js Global CSS Support

At the root level, we’ll establish a styles directory. We’ll also create a styles.css file with the following code:

Let’s use Next.js to build global styles that will be applied to all pages.

In this example, we’ll create a styles.css file that will be applied to all of the _app.js component’s components.

html,
body {
   padding: 0;
   margin: 0;
   line-height: 1.6;
   font-size: 18px;
   background-color: lime;
}

* {
   box-sizing: border-box;
}

a {
   color: #0070f3;
   text-decoration: none;
}

a:hover {
   text-decoration: underline;
}

img {
   max-width: 100%;
   display: block;
}

Using the code below, we will create _app.js file in the pages directory.

import '../styles/styles.css'

export default function App({ Component, pageProps }) {
   return <Component {...pageProps} />
}

Starting the Next.JS Server

Using the given code, we will start the server in the terminal.

npm run dev

Global Styles

We’ll delete all the boilerplate and add something like:

export default function Home() {
  return <main>
    <h1>Soothing Teas</h1>

    <p>Welcome to our wonderful tea shop.</p>

    <p>We have been open since 1987 and serve customers with hand-picked oolong teas.</p>
  </main>
}

Unfortunately, it will appear rather plain, so let’s apply some global styles to the most basic elements, such the h1> tags. (I refer to these styles as “acceptable global defaults.”) In certain cases, we can overrule them, but if we don’t, they’re an excellent predictor of what we’ll want.

This will go in the styles/globals.css file (which comes with Next.js by default):

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  color: var(--off-white);
  background-color: var(--dark);
}

h1 {
  color: var(--green);
  font-size: var(--font-size-lg);
}

p {
  font-size: var(--font-size-md);
}

p, article, section {
  line-height: 1.5;
}

:focus {
  outline: 0.15rem dashed var(--off-white);
  outline-offset: 0.25rem;
}
main:focus {
  outline: none;
}

img {
  max-width: 100%;
}

This is, of course, a very simple version, but it includes my globals. A CSS file does not need to be particularly huge in most circumstances. This section styles basic HTML components (headings, body, links, and so on). To give these parts some basic styling, there’s no need to wrap them in React components or add classes all the time.

Component Styles

Let’s begin by creating a new page in the pages/shop.jsx directory:

export default function Shop() {
  return <main>
    <div className="lockup">
      <h1>Shop Our Teas</h1>
    </div>

  </main>
}

Then, we’ll need some teas to display. We’ll include a name, description, and image (in the public/ directory) for each tea:

const teas = [
  { name: "Oolong", description: "A partially fermented tea.", image: "/oolong.jpg" },
  // ...
]

Now, let’s add our components/TeaList/TeaList.jsx file:

import TeaListItem from './TeaListItem'

const TeaList = (props) => {
  const { teas } = props

  return <ul role="list">
    {teas.map(tea =>
      <TeaListItem tea={tea} key={tea.name} />)}
  </ul>
}
export default TeaList

Let’s get started with the components/TeaList/TeaListItem.jsx component, which will loop over our teas and display a list item for each one:

import Image from 'next/image'

const TeaListItem = (props) => {
  const { tea } = props

  return <li>
    <div>
      <Image src={tea.image} alt="" objectFit="cover" objectPosition="center" layout="fill" />
    </div>

  <div>
      <h2>{tea.name}</h2>
      <p>{tea.description}</p>
    </div>
  </li>
}

export default TeaListItem

We’re employing the built-in image component in Next.js. I set the alt attribute to an empty string in this example because the photos are only for aesthetic purposes. With elaborate graphic explanations, we don’t want to bother screen reader users.

Finally, let’s create a components/TeaList/index.js file so that we can easily import our components from other places:

import TeaList from './TeaList'
import TeaListItem from './TeaListItem'

export { TeaListItem }

export default TeaList

RECOMMENDED ARTICLES





Leave a Reply

Your email address will not be published. Required fields are marked *