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

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

<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, чтобы дать #__next { height: %100 }, но из-за этого заливка не будет работать правильно, она переполнится. Так это выглядит так:

<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 или смонтировать в тело вместо #__next div. Кто-нибудь знает, как достичь любого из них?

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

установите __next height 100% и box-sizing: border-box; отступы и поля на 0

Robert 19.12.2020 23:11

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

Robert 19.12.2020 23:14

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

Dillan Wilding 20.12.2020 01:30

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

Robert 20.12.2020 02:16

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

Robert 20.12.2020 02:32

Я никогда не видел calc(100% - 18px). Я должен попробовать. Это хороший момент, я мог бы изменить способ размещения заголовка навигации вверху, но тогда мне пришлось бы компенсировать это, добавив верхнее дополнение к пространству содержимого. Спасибо за ваши предложения! Я отчитаюсь.

Dillan Wilding 20.12.2020 02:48
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
13
6
12 768
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

Dillan Wilding 27.12.2020 05:08

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

Jair Reina 27.12.2020 23:11

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

Dillan Wilding 28.12.2020 03:31
Ответ принят как подходящий

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

Я использовал подход из этого примера для использования попутного ветра с 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;
}

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

Другое решение — установить классы после загрузки компонента или страницы с помощью хука жизненного цикла 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 и необходимы для правильного отображения страницы, и вы не можете изменить Далее. .js, поэтому я думаю, что упомянутые выше решения — лучший способ добавить классы в контейнер div #__next.

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

Dillan Wilding 28.12.2020 03:32

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

Abbas Hosseini 28.12.2020 11:15

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

Dillan Wilding 30.12.2020 15:25

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

Abbas Hosseini 30.12.2020 15:46

Нет необходимости вставлять элементы между техническими корневыми элементами 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>

Я обнаружил, что обновление 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

Другие вопросы по теме