Feature blog image

Next.js app directory and 100% height

3 min read

info

This article describes the behavior of Next.js between version 13.0.0 and version 13.0.7. Version 13.0.7 removes the extra div, see section the fix for details.

The new app directory of Next.js 13 introduces the great concepts of layouts. But they come with a price ... a div wrapper. Each layout wraps its children in a div. This could break designs which are using a height of 100%.

As Tim Neutkens (one of the Next.js maintainers) says, the problem is temporary but it has to be fixed in react:

First off: We totally understand your struggle because of the added elements.

It's indeed added for now to handle keeping the right section of the page in view when navigating between pages. Unlike in pages the new router has improved scroll and focus handling. It ensures only the changed part is scrolled into view and put focus on.

Right now this is a trade-off as React doesn't allow finding the DOM node from a component and it has to interplay with server components which can't just get a ref passed as they render outside the browser.

We're planning to create a RFC for React to solve the "selecting a underlying DOM node of a component" for this case.

The original post can be found in the answers of this github discussion.

The workaround

The good news Next.js 13.0.1 add a data attribute (data-nextjs-scroll-focus-boundary) to those div wrappers. With this attribute, we are now able to apply styles to the wrapper. For example, we can specify display: contents as suggested by bmcmahen on the same discussion:


[data-nextjs-scroll-focus-boundary] {
display: contents;
}

Using display: contents prevent the wrapper from affecting the layout at all.

developer.mozilla.org describes display: content as follows:

These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes. Please note that the CSS Display Level 3 spec defines how the contents value should affect "unusual elements" — elements that aren't rendered purely by CSS box concepts such as replaced elements.

It sound perfect for our use case, but they mention also accessibility issues:

Due to a bug in browsers, this will currently remove the element from the accessibility tree — screen readers will not look at what's inside.

Here is blog post from Adrian Roselli, which describes the problem in more detail: Display: Contents Is Not a CSS Reset

I'm not really sure, if the accessibility bugs still exists, accordingly to caniuse.com there are still issues with it.

So if our only problem is the 100% height, perhaps we should just use:


[data-nextjs-scroll-focus-boundary] {
height: 100%;
}

The Fix

A few weeks after this article was published Tim Neutkens, tweets the following:

A few days later Next.js 13.0.7 was released, which contains the following fix:

So if you run Next.js 13.0.7 or newer you do not need the workaround anymore.

Posted in: nextjs, css