Можете ли вы изменить элемент монтирования NextJS или добавить классы в __next div?

#javascript #css #next.js #jsx #tailwind-css

#javascript #css #next.js #jsx #tailwind-css

Вопрос:

Короче говоря, я работаю над проектом, в котором я хочу, чтобы содержимое «заполняло» вертикальное пространство под статическим заголовком. Я сделал это в React с tailwind следующим образом:

 <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>
 

Но с NextJS, похоже, монтируемый div (т. Е. <div id="__next"> ) помещается между телом и частью содержимого. Если я изменяю CSS на give #__next { height: 0 } , но это приводит к неправильной работе заливки, она переполняется. Итак, это выглядит так:

 <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>
 

Вот скриншоты, чтобы наглядно увидеть, почему дополнительный div вызывает проблемы: https://imgur.com/a/dHRsDkY

Два возможных варианта решения этой проблемы, которые теоретически могут сработать, — это добавление классов в #__next div или монтирование в body вместо #__next div. Кто-нибудь знает, как достичь любого из них?

Редактировать: Да, я думаю, что я мог бы изменить макет на фиксированный заголовок и заполнение поверх элемента содержимого, и это обошло бы проблему, и это может оказаться обходным путем, который мне нужен, но мне все еще интересно узнать, возможно ли какое-либо из упомянутых мной решений, потому что, если они неэто техническое ограничение NextJS, которому не уделяется много внимания.

Комментарии:

1. установите __next height 100% и размер поля: border-box; отступы и поля на 0

2. и тело, высота html 100%

3. @Robert Результат совпадает с изображением переполнения, которое я опубликовал в imgur

4. ваш заголовок имеет фиксированную высоту. h-18, поэтому просто calc(100% — 18 пикселей) должен быть в порядке, или поместите этот слой как абсолютный верхний 0, а минимальная высота 100% также должна работать. (но во втором случае вам нужно изменить zindex заголовка)

5. или лучше. если заголовок всегда находится сверху, просто сделайте его фиксированным, среднее положение: фиксированное и top: 0. это удалит его из __nav, а высота 100% будет рассматриваться как 100% страницы, а не плюс высота заголовка

Ответ №1:

Я решил проблему, удалив классы из тела и применив их к #__next контейнерному div:

Я использовал подход в этом примере для использования tailwind с Next.js .

Затем я отредактировал styles/index.css

 @tailwind base;

/* Write your own 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;
}

/* Write your own 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 own custom utilities */

 

Как вы сказали, смысл в том, чтобы добавить классы #__next вместо body .

Как вы можете видеть в комментариях, важно, куда добавить @apply инструкцию.

Важные строки:

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

Как вы задали в заголовке своего вопроса, это один из способов добавить стили tailwind #__next в div контейнера.

Другим решением является установка классов после загрузки компонента или страницы с использованием componentDidMount() крючка жизненного useEffect цикла или крючка, подобного этому:

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

Если вы посмотрите на Next.js документация о пользовательском документе вы можете видеть, что Main компонент и NextScript являются внутренними компонентами Next.js и необходимы для правильного отображения страницы, и вы не можете изменить Next.js внутренние компоненты, поэтому я думаю, что решения, упомянутые выше, являются лучшими способами добавления классов в #__ следующий контейнер div.

Комментарии:

1. Я думаю, что это может быть ближе всего к фактическому решению проблемы, но не совсем то, что я искал. Я новичок в Nextjs, и кажется, что он произвольно добавляет #__next div для монтирования Nextjs, и, похоже, он вообще не настраивается. Я надеялся получить некоторое представление о внутренней работе Nextjs или, возможно, о возможных улучшениях, которые можно было бы внести.

2. Как вы упомянули в заголовке вашего вопроса: » или добавить классы в __next div? » это способы, которыми вы можете достичь своей цели.

3. Хотя это не решает мой творческий / интеллектуальный запрос о Nextjs, это решило мою проблему, поэтому я собираюсь вознаградить вас.

4. Я рад, что смог помочь!

Ответ №2:

вы можете изменить свои html body теги or, создав пользовательский документ в ./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
 

Примите во внимание, что эти теги должны быть включены в ваш файл: <Html> , <Head /> , <Main /> и <NextScript /> .

Вот полная документация

В вашем случае этот элемент с идентификатором __next — это именно то, что отображает элемент, и он необходим для монтирования основного приложения. Таким образом, вы не можете удалить его или отредактировать. Я думаю, вы можете добавить немного css в _document.js который нацелен на #__next, использование директивы @apply из tailwind может быть способом вместо редактирования HTML элемента (поскольку это кажется невозможным)

Комментарии:

1. У меня есть пользовательский документ, подобный описанному здесь и в документации, но Nextjs по-прежнему вставляет div с идентификатором __next между телом и содержимым страницы.

2. Я понимаю. Этот элемент с идентификатором __next — это именно то, что отображает элемент <Main /> , и он необходим для монтирования основного приложения. Таким образом, вы не можете удалить его или отредактировать. Я думаю, вы можете добавить немного css в _document.js который нацелен на #__next , использование директивы @apply из tailwind может быть способом вместо редактирования HTML элемента <Main /> (поскольку это кажется невозможным)

3. Это прискорбно. Я почти думаю, что было бы лучше либо настроить точку монтирования, либо подключить к телу, а не вставлять произвольный div.

Ответ №3:

Нет необходимости вставлять элементы между техническим корневым элементом NextJS или заменять #__next его (). Просто растяните все родительские элементы корневого элемента вашего приложения, чтобы занять всю высоту экрана 100vh (vh — это «вертикальная высота», единица измерения, равная 1% от высоты окна просмотра).

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

Ваш HTML-код может выглядеть следующим образом:

 <html>
<head><!-- head content --></head>
<body>
  <div id="__next">
    <div id="app"><!-- this is your app's top element --></div>
  </div>
</body>
</html>
 

Ответ №4:

Я обнаружил, что обновление styles/globals.css является самым простым способом достижения этой цели.

 /*
  Extend the top most enclosing elements to entire height of the screen 
  to allow for the background image to fill the entire screen
*/
html,
body,
#__next {
  height: 100%;
}
 

Обратите внимание, что это global.css должно быть импортировано в _app.tsx