How to make div fill full height of parent in tailwind - tailwind-css

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:

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 overscroll y not working properly

I'm building a laravel/tailwind dashboard but I'm now facing an issue with the overflow of an element.
The design I want to achieve is the follwing :
And what i achieved until now is the following:
With this code structure :
<body>
<div id="app" class="max-h-screen flex flex-col">
<nav class="bg-white border-gray-200 flex flex-wrap h-fit justify-between shadow items-center p-0 m-0">
</nav>
<div class="flex max-h-full grid grid-cols-8">
<aside class="h-full flex col-span-1" aria-label="Sidebar" id="sidebar">
</aside>
<div class="w-full bg-gray-100 p-5 col-span-7 flex-1 m-0">
</div>
</div>
</div>
</body>
The issue
I would like to have only the body as scrollable ans keep the sidebar and the navbar in the same fixed position they are at any time.
Unfortunately, when i add the overflow-y-auto class to the div where the body is, the overflow is applied to the whole window breaking the design.
Do you have any suggestion on how i can make only the body scrollable with the above code base?
Thank you
Method 1: using fixed classes
Idea : make the nav and aside elements fixed
<body>
<div id="app" class="h-screen flex flex-col">
<nav class="bg-white border-gray-200 flex flex-wrap h-fit justify-between shadow items-center p-0 m-0 w-full fixed top-0 left-0 z-10">
</nav>
<aside class="h-screen fixed top-0 left-0 w-60 flex col-span-1" aria-label="Sidebar" id="sidebar">
</aside>
<div class="w-4/5 ml-auto bg-gray-100 p-5 col-span-7 flex-1 overflow-y">
</div>
</div>
</body>
Method 2: using sticky class
<body>
<div id="app" class="max-h-screen flex flex-col">
<nav class="bg-white border-gray-200 flex flex-wrap h-fit justify-between shadow items-center p-0 m-0 w-full fixed top-0 left-0 z-10">
</nav>
<div class="flex max-h-full grid grid-cols-8 relative h-screen overflow-hidden">
<aside class="h-screen flex col-span-1 sticky top-0" aria-label="Sidebar" id="sidebar">
</aside>
<div class="w-full overflow-auto bg-gray-100 p-5 col-span-7 flex-1 m-0">
</div>
</div>
</div>
</body>
You might have to experiment with the div widths as I am just roughly eyeballing the values with w-4/5 and w-60 classes.

TailwindCSS - how to center content on a flex-grow item

I have a basic page layout as follows. I would like to center the four items in the middle of the page, not only horizontally, but vertically. Centering horizontally works but vertically doesn't. According to the tailwind doc, entering can be acheived using the place-content-center class. However, this doesn't seem to work here. Any ideas about how to do this?
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.2/tailwind.min.css" rel="stylesheet"/>
<div class="flex flex-col h-screen">
<header class="h-10 bg-red-500">Header</header>
<div class="flex-grow place-content-center bg-green-500">
<h1>Content</h1>
<div class="grid place-items-center justify-center">
<div class = "grid gap-6 md:grid-cols-2 content-center">
<div class="h-[200px] w-[300px] bg-yellow-500 flex flex-col items-center">
Item 1
</div>
<div class="h-[200px] w-[300px] bg-yellow-500 flex flex-col items-center">
Item 2
</div>
<div class="h-[200px] w-[300px] bg-yellow-500 flex flex-col items-center">
Item 3
</div>
<div class="h-[200px] w-[300px] bg-yellow-500 flex flex-col items-center">
Item 4
</div>
</div>
</div>
</div>
<footer class=" w-full h-10 bg-blue-500">Footer</footer>
</div>
It appears that you just need to add the h-full class to your content wrapper:
<div class="grid h-full place-items-center justify-center">
You can see a working example here: https://play.tailwindcss.com/U5NB6t6heB

Div on top of another with Tailwind CSS

How do I get the second inner div to be on top of the first inner div (map)? I can't figure this out, despite using relative & absolute positioning. I'm using React & Tailwind CSS. Instead, the second inner div currently follows the flow of the image and is positioned below the first children div.
<div className="relative w-full h-screen">
<div className="bg-green-400 w-full h-full z-0">
<p className="italic text-bold bd-red-100 font-serif">Map</p>
</div>
<div className="absolute z-50">
<p className="text-2xl font-bold">This should be on top of the map</p>
</div>
</div>
Here's a Tailwind Play Code I created based on your query. I have tweaked height and width for proper visual.
<div class="w-full h-screen bg-gray-200 flex justify-center items-center">
<div class="bg-gray-400 w-96 h-96 relative z-0">
<p class="italic text-bold bd-red-100 font-serif">Map</p>
<div class="absolute inset-0 flex justify-center items-center z-10">
<p class="text-2xl font-bold">This should be on top of the map</p>
</div>
</div>
</div>
I would like to extend #Digvijay's answer further more to provide extended explanation, which consists
1. Logic
2. Responsive Sidebar
3. Responsive Sidebar with hamburger menu
You'll have to work with relative absolute and z-index to make this work.
1. Logic:
Have parent relative having z-index value less than the child absolute div which will be used for navbar.
Code:
<div class="h-screen relative z-0 flex bg-gray-500">
<div class="text-4xl">
The main content of the file and it has it's content all over the page
and i want to build a navbar on top of this
</div>
<div class="absolute inset-y-0 left-0 z-10 bg-green-400 w-1/3">
<div class="flex h-full items-center justify-center text-4xl">
Mobile Navbar
</div>
</div>
</div>
Output:
Code Link: tailwind play
2. Responsive Sidebar
If you are aiming to build responsive sidebar which overlaps only on the mobile screen but would be normal div in the large screen then follow the below code.
Code:
<div class="md:bg-yellow-400 h-screen relative z-0 flex bg-gray-500">
<div class="invisible md:visible bg-blue-400 w-1/3">
<div class="flex h-full items-center justify-center text-4xl">
Desktop Navbar
</div>
</div>
<div class="text-4xl">
The main content of the file and it has it's content all over the page
and i want to build a navbar on top of this
</div>
<div
class="absolute inset-y-0 left-0 z-10 bg-green-400 w-1/3 md:invisible"
>
<div class="flex h-full items-center justify-center text-4xl">
Mobile Navbar
</div>
</div>
</div>
Code link : tailwind play
Output in large device:
Output in smaller device:
3. Toggle mobile navbar using hamburger menu
Output on large devices
Output in small device with hamburger menu
When clicked on hamburger menu
Code:
<body>
<div class="bg-yellow-400 h-screen relative z-0 flex">
<div class="hidden md:block bg-blue-400 w-1/3">
<div class="flex h-full items-center justify-center text-4xl">
Desktop Navbar
</div>
</div>
<div class="text-4xl pl-24 md:p-0 main_content">
The main content of the file and it has it's content all over the page
and i want to build a navbar on top of this
</div>
<div
class="mobile_navbar absolute inset-y-0 left-0 z-10 bg-green-400 w-1/3 hidden md:hidden"
>
<div class="flex h-full items-center justify-center text-4xl">
Mobile Navbar
</div>
</div>
<div
class="md:hidden space-y-2 absolute hamburger_menu inset-y-0 left-0 p-4"
>
<span class="block w-8 h-1 bg-white"></span>
<span class="block w-8 h-1 bg-white"></span>
<span class="block w-8 h-1 bg-white"></span>
</div>
</div>
<script type="text/javascript">
document
.querySelector(".hamburger_menu")
.addEventListener("click", () => {
console.log("Hello");
document.querySelector(".mobile_navbar").classList.toggle("hidden");
});
document.querySelector(".main_content").addEventListener("click", () => {
console.log("Touch me");
console.log(
document
.querySelector(".mobile_navbar")
.classList.contains("hidden") == false &&
document.querySelector(".mobile_navbar").classList.toggle("hidden")
);
});
</script>
</body>

Applying scroll to specific section of flex container

<div class="flex flex-grow h-full w-100">
<div class="flex flex-col bg-white w-1/5">
<div class="dates px-4">
<p>Today</p>
<p>Tomorrow</p>
<p>Upcoming</p>
</div>
<hr />
<div class="projects flex-grow px-4">
<p>Project 1</p>
<p>Project 2</p>
</div>
<div class="footer">
<hr />
<button class="outline-none py-2 border-gray-400 text-red-400 w-full">
Add project
</button>
</div>
</div>
<div class="main bg-gray-100 flex-grow">Hello</div>
<div class="bg-white w-1/5">Hello</div>
</div>
In the above code, I want only the div with class projects to be scrollable while holding the dates and footer fixed on their places. how to do that using tailwind.css ?! I also want the div with class main to be scrollable vertically while holding the other two divs fixed on their places without scrolling.
It sounds a bit like a common usage of overflow-y.
For example, you could add this CSS rule to your project's class:
.projects {
overflow-y: scroll;
}
You can add this rule to whichever container you want to be scrollable - in this case vertically.
On the other, there is overflow-x: scroll for horizontal scrolling, or overflow: scroll for both (shorthand).
According to tailwind overflow guide, you can use .overflow-y-auto for vertical scrolling.
e.g.
<div class="projects flex-grow overflow-y-auto px-4">
It's good that you have used .flex-grow otherwise you would have to give a max-height to the div.
<div class="flex flex-grow h-full w-100">
<div class="flex flex-col bg-white w-1/5">
<div class="dates px-4">
<p>Today</p>
<p>Tomorrow</p>
<p>Upcoming</p>
</div>
<hr/>
<div class="projects h-auto overflow-x-auto flex-grow px-4">
<p>Project 1</p>
<p>Project 2</p>
</div>
<div class="footer">
<hr/>
<button class="outline-none py-2 border-gray-400 text-red-400 w-full">
Add project
</button>
</div>
</div>
<div class="main bg-gray-100 flex-grow">Hello</div>
<div class="bg-white w-1/5">Hello</div>
</div>

Resources