Div height and overflow in nested layout to achieve scrollable child elements - css

I'm having immense trouble understanding the concept of div height and overflow. Been searching for two days but I think I'm missing a key concept here...
My layout looks like this (Tailwind Playground):
The blue div does not scroll all the way to the end of the content. For some reason the div thinks that its height is larger than it really is (by exactly the height of the second navbar (red) on top of it). As a result, I can't scroll all the way to the bottom.
Also, having to repeat h-full for each child div until I reach the div that I want to be scrollable seems off to me but otherwise it assumes h-auto which is not good.
<div class="h-screen overflow-hidden">
<div class="flex h-full flex-col overflow-hidden">
<div class="w-full bg-slate-500 text-center text-white h-12 ">NAVBAR</div>
<div class="flex h-full overflow-hidden">
<div class="flex h-full basis-1/6">
<div class="w-full bg-gray-300 text-center text-black">Sidebar</div>
</div>
<div class="flex h-full grow flex-col bg-slate-500">
<div class="h-12 w-full shrink-0 bg-red-400 text-center">Second Navbar</div>
<div class="h-full w-full grow bg-green-400">
<div class="flex h-full">
<div class="w-1/3 bg-blue-400 text-center">
<div class="flex h-full flex-col overflow-y-scroll">
<div>
Lorem....
</div>
</div>
</div>
<div class="h-full w-2/3 overflow-y-scroll bg-orange-400 text-center">Main content</div>
</div>
</div>
</div>
</div>
</div>
</div>

Lets look at the container(blue parent) under the second navbar. Its parent (the parent of the second navbar as well) have a height of about 831px. The navbar height is 3rem - which is about 48px.
But the blue parent has a height of 100% (of its parent) ~ 831px. So its basically overflowing (because 831+48 != 831).
If you put the overflow:hidden on the blue parent it'll hide the overflowing and blue container will scroll normally.
https://play.tailwindcss.com/SOO2rwiGsw

Related

Correct way to hide parent scrollbar and only show child scrollbars

Why am I not getting a vertical scrollbar in each div? If I use max-h-screen instead of max-h-full I'm getting the scrollbar but the problem is that - because of the navbar - the content at the bottom of the screen is clipped by exactly the height of the navbar.
Playground
<div class="h-screen overflow-hidden">
<div class="flex flex-col">
<div class="h-12">Navbar </div>
<main class="flex flex-row">
<div class=" w-1/5 flex h-full max-h-full overflow-y-auto flex-col flex-grow bg-purple-50">Lorem... </div>
<div class=" w-4/5 bg-gray-50 h-full max-h-full overflow-y-auto">Lorem... </div>
</main>
</div>
You need to carry the height: 100% onto the second nested div, and your main. Otherwise the height becomes auto and grows to accommodate your content, so on tailwind that looks like it's h-full you'll need to put on both of those:
<div class="h-screen overflow-hidden">
<div class="flex flex-col h-full">
<div class="h-12">Navbar </div>
<main class="flex flex-row h-full">
<div class=" w-1/5 flex h-full max-h-full overflow-y-auto flex-col flex-grow bg-purple-50">Lorem... </div>
<div class=" w-4/5 bg-gray-50 h-full max-h-full overflow-y-auto">Lorem... </div>
</main>
</div>

Tailwind: how to set autofill of grid?

I have 2 divs under 1 div.
first div should be w-64.
second div's width want to be the rest except for 64.
How to make it?
and if I use grid then how to make that?
<div className="w-screen h-screen">
<div className="fixed top-0 left-0 w-64 h-screen" >
</div>
<div className="flex bg-blue-100 justify-center items-center">
{children}
</div>
</div>
You can add to the second div two Tailwind properties:
w-[calc(100vw-16rem)], where 100vw is a fullscreen and w-64 = width: 16rem; /* 256px */), then we calculate the width of the div.
After that we offset the second div with ml-auto.
<div className="w-screen h-screen">
<div className="fixed top-0 left-0 w-64 h-screen"></div>
<div className="grid w-[calc(100vw-16rem)] ml-auto bg-blue-100 justify-center items-center">
{children}
</div>
</div>
Grid solution
For the grid, we need to add a grid property to the parent element and set two columns grid-cols-[16rem_calc(100vw-16rem)]. The first column is static, and the second is responsive. We also need to remove all properties from the first child element.
<div className="grid grid-cols-[16rem_calc(100vw-16rem)] w-screen h-screen ">
<div className="flex"></div>
<div className="flex bg-blue-100 justify-center items-center">
{children}
</div>
</div>

Vertically fill a parent flex-box container with 3 items each at 33% of height

What I currently have using Tailwind (see this playground)
<div class="h-screen flex flex-col items-center space-y-6">
<div class="h-1/3">X</div>
<div class="h-1/3">X</div>
<div class="h-1/3">X</div>
</div>
What I like is that each of the 3 items take 33% (minus the y-spacing) of the h-screen container.
What happens there is that the h-screen container is larger than the height of the screen so there's a scroll, you can see that in the playground I've added.
There is a parent around that container with py-6. I initially thought that was the problem, but if I do this:
<div class="h-screen flex flex-col items-center space-y-6">
<div class="">X</div>
</div>
With that same py-6 parent around it, it works as expected and there's no scroll.
You can use other classes like flex-1 to expand your flex-child and mind margins, also flex-col on the parent holding a single child is not necessary., h-screen on the child is also not necessary, the parent is already a sized flexbox and will fill it up:
possible example :
<div class="min-h-screen bg-gray-100 py-6 flex justify-center">
<div class=" flex flex-col items-center space-y-6">
<div class="flex-1 bg-red-500">X</div>
<div class="flex-1 bg-green-500">X</div>
<div class="flex-1 bg-yellow-500">X</div>
</div>
</div>
https://play.tailwindcss.com/VCTmCjUAQA
make it 2 children, it will be 50% minus margins, four : 25% minus margins and so on. flex do the math itself ;)

Tailwind CSS flex item overflows outside of parent

I have a flexbox with 3 children items that looks something like this:
<section className="px-5 flex flex-col md:flex-row md:space-x-10 justify-around">
<div className="flex flex-col py-3 md:flex-grow"><input ... /></>
<div className="flex flex-col py-3 md:flex-grow"><input ... /></>
<div className="flex flex-col py-3 md:flex-grow"><input ... /></>
</section>
This works fine in full screen, however flex items start to break out of parent after shrinking the window width (near 1000px).
How can I make it so the items stay inside their parent?
Fullscreen
After shrinking window width
What I would like to achieve
By adding flex-wrap class in the parent(section tag in your case) will fix the issue.
Read more about flex-wrap https://tailwindcss.com/docs/flex-wrap
If you use flexbox, you can use flex wrap property to solve your proble.,
But i try to get the same result with grid
<div class="container py-10">
<section class="grid grid-cols-3 gap-4 p-5 border border-gray-400 rounded-lg">
<div class="w-full h-20 bg-orange-200 border border-orange-400 rounded-md"></div>
<div class="w-full h-20 bg-orange-200 border border-orange-400 rounded-md"></div>
<div class="w-full h-20 bg-orange-200 border border-orange-400 rounded-md"></div>
</section>
</div>
This is better i think :)

How to make div fill full height of parent in tailwind

I am using tailwind in my Vuejs app. I have this simple template
<template>
<div class="bg-gray-500 h-screen">
<Header /><!-- //height 32 -->
<div class="w-2/3 mx-auto p-4 text-lg bg-white h-full shadow-lg">
<router-view />
</div>
</div>
</template>
The div with h-screen is the root or my app. The component<header> has a tailwind height of h-32
The problem is that the second div causes the page to scroll at the bottom, the height of the <header> (h-32).
What I want to do
If there is no content, I want the second div to fill the remaining height of the screen but no more.
If there is content, I want it grow as necessary.
You can leverage .flex, .flex-col and .flex-1 for this. Check out docs.
<div class="bg-gray-500 flex flex-col h-screen">
<div class="flex h-32 bg-gray-200"></div>
<div class="flex-1 w-2/3 mx-auto p-4 text-lg bg-white h-full shadow-lg bg-gray-300">
<router-view />
</div>
</div>
Usage of flex-1 is optimal for your solution to expand a certain component in the parent:
Use flex-1 to allow a flex item to grow and shrink as needed, ignoring its initial size:
Vertically
<div class="flex h-screen flex-col">
<div class="h-50 bg-cyan-400 text-center text-4xl">Header</div>
<div class="flex-1 bg-yellow-400 text-center text-4xl">I am the body</div>
</div>
Output:
Horizontally
<div class="flex w-screen ">
<div class="h-50 bg-cyan-400 text-center text-4xl">NavBar</div>
<div class="flex-1 bg-yellow-400 text-center text-4xl">I am the body</div>
</div>
Output:

Resources