Is it possible to customize the mounting element of NextJS or apply additional classes to the __next div?

In a nutshell, I'm currently working on a project where my aim is to make the content "fill" the vertical space below the static header. Previously, in React with tailwind, I achieved this like so:

<body class="flex flex-col h-screen text-gray-600 work-sans leading-normal text-base tracking-normal">
    <header class="flex h-18 bg-white shadow-md">
        {/* header menu options */}
    </header>
    <div class="flex flex-1 h-full bg-gray-200 p-6">
        {/* page content */}
    </div>

However, with NextJS, it seems that the mounting div (i.e.

<div id="__next">
) is placed between the body and the rest of the content. If I adjust the CSS to apply #__next { height: 100% }, the filling does not function correctly and causes overflow. The structure ends up looking like this:

<body class="flex flex-col h-screen text-gray-600 work-sans leading-normal text-base tracking-normal">
    <div id="__next">
        <header class="flex h-18 bg-white shadow-md">
            {/* header menu options */}
        </header>
        <div class="flex flex-1 h-full bg-gray-200 p-6">
            {/* page content */}
        </div>
    </div>

I have included screenshots for a visual representation of why the additional div is causing issues: https://i.sstatic.net/xZloH.jpg

Two possible solutions to resolve this issue theoretically are to add classes to the #__next div or to mount to the body instead of the #__next div. Does anyone know how to implement either of these?

Edit: It might be possible for me to change the layout to a fixed header with padding on top of the content element, which could bypass the problem. However, I am still curious about the feasibility of the solutions I mentioned, as if they are not viable, it would signify a technical limitation of NextJS that is not widely discussed.

Answer №1

To fix the issue, I removed classes from the body and applied them to the #__next container div:

I followed a similar approach outlined in this example for using Tailwind with Next.js.

Then, I made changes to the styles/index.css

@tailwind base;

/* Your custom base styles here */
/* #__next {
  height: 100%;
} */

/* Start purging... */
@tailwind components;
/* Stop purging. */

html,
body {
  @apply bg-gray-50 dark:bg-gray-900;
}

#__next {
  @apply flex flex-col h-screen text-gray-600 leading-normal text-base tracking-normal;
}

/* Your custom component styles here */
.btn-blue {
  @apply px-4 py-2 font-bold text-white bg-blue-500 rounded;
}

/* Start purging... */
@tailwind utilities;
/* Stop purging. */

/* Your custom utilities */

As previously mentioned, it's crucial to add the classes to #__next rather than the body.

The key directives to note are:

#__next {
  @apply flex flex-col h-screen text-gray-600 leading-normal text-base tracking-normal;
}

In response to your query title, this method demonstrates one way to incorporate Tailwind styles into the #__next container div.

Another option involves adding the classes after the component or page has loaded using either the componentDidMount() lifecycle hook or the useEffect hook like so:

useEffect(() => {
    document.querySelector("#__next").className =
      "flex flex-col h-screen text-gray-600 leading-normal text-base tracking-normal";
  }, []);

Referencing the Next.js documentation on Custom document, you'll find that the Main component and NextScript are integral to Next.js functioning correctly and cannot be altered. Therefore, I believe the solutions provided above are the optimal means of applying classes to the #__next container div.

Answer №2

One simple way to ensure your NextJS application fills the entire screen height is to adjust the parent elements' heights using the 100vh unit (which represents 1% of the viewport height).

html, body, #__next, #app {
  min-height: 100vh;
}

Your HTML structure can be structured like this:

<html>
<head><!-- head content --></head>
<body>
  <div id="__next">
    <div id="app"><!-- this is the main element of your app --></div>
  </div>
</body>
</html>

Answer №3

If you want to customize the html or body tags, you can do so by creating a custom document in ./pages/_document.js

import Document, { Html, Head, Main, NextScript } from 'next/document'

class CustomDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body className="custom-class-name">
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default CustomDocument

Keep in mind that you must include these tags in your file: <Html>, <Head />, <Main />, and <NextScript />.

For more information, check out the full documentation

In this context, the element with the __next id is essential for rendering the main app and cannot be removed or altered. You can apply CSS targeting #__next in _document.js using the @apply directive from tailwind instead of modifying the HTML of the element (as it may not be possible)

Answer №4

The simplest method I discovered to accomplish this was by updating the styles/globals.css.

/*
  Make sure that the topmost enclosing elements stretch to cover the entire height of the screen
  in order for the background image to fill the whole screen
*/
html,
body,
#__next {
  height: 100%;
}

It is important to remember that the global.css needs to be imported into _app.tsx

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Clear the modal form in Codeigniter and AJAX upon closing the edit modal

Having an issue with my modal form - when I open the edit modal, the data is fetched and that part works well. However, when I close the modal and try to add a new user, the data is automatically fetched again. Why is this happening? Shouldn't the for ...

The content within Contentful is presented in a JSON object format, but accessing specific values is proving to be

I have successfully added two records in the contentful database and now I am attempting to fetch the content from Contentful into my React-hooks website. However, I am facing difficulties retrieving the values for title, description, image, and shortDescr ...

Creating a custom component results in an extended duration to 'eliminate' its children

1I am currently facing an issue with a time-table component created using vue.js. It contains approximately 200 nested child timeline components, making it quite complex (I wanted to share an image but lacked the reputation to do so). The main problem lie ...

Guidelines for Implementing Stylesheets from a Referenced Node Module

I am currently developing a VS Code module that incorporates highlight.js to produce HTML for syntax highlighting of source code. Within the highlight.js npm package, there is a directory named styles containing various CSS files that I intend to utilize. ...

How can I embed input tag with the data-plugin attribute into a DOM element?

Can anyone help me with adding a data-plugin attribute to the "el" element using JavaScript? HTML <input type="text" data-plugin="datepicker" class="form-control" > JavaScript // Creating an input element var cellRight = row.insertCell(1); var ...

Having difficulty in making the left sidebar stay fixed

In my web layout, I have a left-sided sideNav div and a right-sided main div set up as follows: #sideNav { background-color: #012d20; position: fixed; z-index: 1; top: 0; left: 0; overflow: hidden; border-right-style: groove; height: 100 ...

Background PHP/JS authentication through HTTP

Recently, I developed a PHP website that includes embedded web-cam snapshots which refresh every 2 seconds using JavaScript. For the first camera, I can easily log in using URL parameters like this: cam1-url?usr=usr&pwd=pwd. However, the second camer ...

Extracting object properties and tallying their occurrences

How can I extract a single property from an array of objects like the following: [{"name":"Bryan","id":016, "counter":0}, {"name":"John","id":04, "counter":2}, {"name":"Alicia","id":07, "counter":6}, {"name":"Jenny","id":015, "counter":9}, {"name":"Bryan" ...

Line up with miniature stature

How can I prevent the image in this row from getting a margin at the bottom when I resize the window? <div class="row-fluid"> <div class="span2"> <img src="https://s3.amazonaws.com/media.jetstrap.com/SLgRUEHSyGwQVfG4x6ed_curso_a ...

What is the best way to display database information on my webpage according to the selected item in the combo box?

Whenever I visit my sample.php page, the only thing that appears is my combo box. However, when I start selecting a value from the combo box, that's when the data from my database, which is fetched from getyear.php, is displayed. What I want to achie ...

Having trouble populating a Material-UI collapsible table with data in React. Any tips on what may be causing this issue?

When I execute the code, the table is generated but I am facing an issue where some database data is not appearing in the collapsible table. Despite confirming that the query successfully retrieves data with console.logs, the data is still missing from t ...

Resizable icon next to inline element caused width adjustment

I have a group of individuals listed, each with two elements side by side: a "contact me" button (an 'a' element with a fontawesome icon) and a tag displaying the user type (span element). Some users do not have a tag, and when there is one prese ...

Display the final row by hovering over the line

<table> <thead> <tr> <th>First</th> <th>Second</th> <th></th> </tr> </thead> <tbody> <tr> <td>Data1</td> <td>Dat ...

The CSS styles are failing to load properly for the antd Menu option

I am working with React using the Next.js framework, and I've integrated the antd npm package for components like tables and menus. However, I'm facing an issue where the CSS is not loading for these controls. What could be causing this problem? ...

Leverage jQuery to organize and categorize JSON information received through an Ajax call

I have retrieved the following array from a MySQL database using PDO: [{ "tbl":"1", "orid":"915", "date":"2021-12-30 12:46:48", "flag":0 }, { "tbl":"2", "orid":"914", "date":"2021-12-30 12:46:21", "flag ...

Tips for showing data associated with the chosen option from a dropdown list in Angular.js fetched from an API

My goal is to automatically display the coordinator's name based on the selection in a dropdown list populated with data from an API. The dropdown options are the email addresses from the JSON data below, and upon selecting a login ID, the correspondi ...

Is it possible to customize the close icons on the autocomplete feature in Material UI?

Is there a solution to change the icon while keeping its function when clicked? I am looking to replace this Icon <Autocomplete multiple id="checkboxes-tags-demo" options={top100Films} disableCloseOnSelect getOpt ...

Exploring the Applications of Directives in Multiple Modules within Angular 2

When I declare the directive in two modules, I get an error that says Type PermissionDirective is part of the declarations of 2 modules. However, when I declare it in only one module, I receive an error stating Can't bind to 'isPermission' s ...

The 'wrapper' property is not present in the 'ClassNameMap<never>' type in Typescript

Hey there, I've been encountering a puzzling issue in my .tsx file where it's claiming that the wrapper doesn't exist. My project involves Material UI and Typescript, and I'm relatively new to working with Typescript as well as transiti ...

Dispense CSS using a React element

My React component index.js contains styling in style.css. I am looking to share this component on npm, but I am unsure of how to simplify the process for other developers to use the styling. After exploring different options, I have come across three ap ...