ARTICLE AD BOX
I am currently building a website using Nuxt 4 + Tailwind CSS and I am having a problem with viewport units (dvh, vh) and percentage heights (h-full) inside a Nuxt layout.
My layout structure is basically:
A global default.vue layout
A Header and a main inside it
Multiple sections rendered inside index the page (Hero, OurTechnologies, etc.), where it uses the default layout
The layout currently looks like this:
<template> <div class="min-h-dvh grid grid-rows-[auto_1fr]"> <LayoutHeader /> <main> <slot /> </main> </div> </template>The index.vue:
<template> <LayoutSectionsHomeHero /> <LayoutSectionsSeparator /> <LayoutSectionsHomeOurTechnologies /> </template>The HeroSection.vue:
<template> <section class="homeHero__main-section h-full flex flex-col items-center justify-center" > <h1 class="homeHero__main-title title__default text-center"> Welcome to <br /> <span class="gradient__text bg-linear-green-1"> <span class="mt-5 inline-block">AutoAI</span> <span class="hidden sm:inline"> - </span> <br class="sm:hidden" /> <span>Pandemics</span> </span> </h1> <p class="homeHero__welcome-paragraph text__default mt-5 text-center"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p> <div class="homeHero__buttons-container mt-10 flex w-full flex-col gap-5"> <UiButtonsPrimary class="font-header-text"> Explore our technologies </UiButtonsPrimary> <UiButtonsSecondary class="font-header-text"> About us </UiButtonsSecondary> </div> </section> </template>And finally, the OurTechnologiesSection.vue
<template> <section class="homeOurTechnologies__main-section flex flex-col items-center"> <UiCardsTool v-for="item in tools" :toolName="item.toolName" :toolDescription="item.toolDescription" :toolLink="item.toolLink" ></UiCardsTool> </section> </template> <script setup lang="ts"> const tools = [ { toolName: "Test", toolDescription: "This is test", toolLink: "/" }, { toolName: "Test", toolDescription: "This is test", toolLink: "/" }, { toolName: "Test", toolDescription: "This is test", toolLink: "/" }, { toolName: "Test", toolDescription: "This is test", toolLink: "/" }, ]; </script>The problem is:
If the page only contains the Hero section, everything works perfectly. Check the image belowLayout without OurTechnologies Section working perfectly
The Hero fills the remaining viewport space below the header exactly as expected.
But as soon as I add another section below it (OurTechnologies), the Hero suddenly becomes much taller than the viewport, like the image below:
Layout broken with OurTechnologies Section
Because of this:
justify-center starts centering based on the entire page height instead of only the visible screen.
The Hero content gets pushed down vertically.
The selected element in DevTools becomes much taller than the viewport.
What I want is a hero section that always fills exactly the visible viewport area remaining below the header(like you can see in the first image above) using best practices for responsive layout.
Oh, and I also tried:
h-full
min-h-full
h-dvh
min-h-dvh
CSS calc()
Changing Grid/Flex configurations
In the hero section, but the behavior still breaks once the page grows vertically.
*Just a small note: Feel free to give me feedback about Vue, HTML, CSS, and best practices. I’m currently starting my journey in front-end development, and I want to learn as much as I can about this huge area, and sorry for my english :)
