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.vuelayoutA
Headerand amaininside itMultiple sections rendered inside
indexthe 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 below
Layout 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-centerstarts 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-fullmin-h-fullh-dvhmin-h-dvhCSS
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 :)