TailwindCss layout with full screen height and scrolling content panel - html

I'm trying to create a typical html layout using TailwindCss - a fixed header and footer, with left-hand and right-hand sidebars.
The center content has a search function which is fixed - the content below should scroll.
I've tried utilising patterns from TailwindCss and TailwindUI, but can't get overflowing content (shown in light blue in the demo below) to scroll rather than pushing the page down.
<link href="https://unpkg.com/tailwindcss#^1.0/dist/tailwind.min.css" rel="stylesheet"/>
<div>
<div class="h-screen flex flex-col bg-gray-300">
<!-- header -->
<div class="bg-blue-700 p-4">
Nav
</div>
<div class="flex-grow flex flex-row justify-center">
<!-- lhs -->
<div class="flex-shrink-0 w-1/4 p-4">
Left menu
</div>
<!-- center -->
<div class="flex-1 flex flex-col bg-white">
<div class="border-b-2 m-4 pb-2 border-gray-200">Search</div>
<main class="flex-1 overflow-y-scroll p-4 bg-indigo-200">
<div class="relative">
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
</div>
</div>
</main>
<!-- rhs -->
<div class="flex-shrink-0 w-1/4 p-4">
Right sidebar
</div>
</div>
<!-- footer -->
<div class="bg-blue-700 p-4">
Footer
</div>
</div>
</div>

What's happening is the the middle div (which contains that center column we want to be scrollable) is being clamped to the height of its contents. Unless instructed otherwise, it'd rather do that, than overflow (at least on Chrome and Firefox). So our central column never even gets the opportunity to apply its own scroll behaviour.
The minimum solution is to put overflow-hidden on the middle div, to let it know it's okay for its contents to overrun:
<link href="https://unpkg.com/tailwindcss#^1.0/dist/tailwind.min.css" rel="stylesheet"/>
<div>
<div class="h-screen flex flex-col bg-gray-300">
<!-- header -->
<div class="bg-blue-700 p-4">
Nav
</div>
<div class="flex-grow flex flex-row overflow-hidden justify-center">
<!-- lhs -->
<div class="flex-shrink-0 w-1/4 p-4">
Left menu
</div>
<!-- center -->
<div class="flex-1 flex flex-col bg-white">
<div class="border-b-2 m-4 pb-2 border-gray-200">Search</div>
<main class="flex-1 overflow-y-auto p-4 bg-indigo-200">
<div class="relative">
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
</div>
</div>
</main>
<!-- rhs -->
<div class="flex-shrink-0 w-1/4 p-4">
Right sidebar
</div>
</div>
<!-- footer -->
<div class="bg-blue-700 p-4">
Footer
</div>
</div>
</div>
... as a result of which, the center column's overflow scroll behaviour becomes operational.
I've also suggested overflow-y-auto on the center column, so that the scrollbars are only when necessary.

This may not be the ideal solution, but it helps. Add this rule to your css:
main.flex-1.overflow-y-scroll.p-4.bg-indigo-200 {
flex-basis: 0;
}
main.flex-1.overflow-y-scroll.p-4.bg-indigo-200 {
flex-basis: 0;
}
<link href="https://unpkg.com/tailwindcss#^1.0/dist/tailwind.min.css" rel="stylesheet"/>
<div>
<div class="h-screen flex flex-col bg-gray-300">
<!-- header -->
<div class="bg-blue-700 p-4">
Nav
</div>
<div class="flex-grow flex flex-row justify-center">
<!-- lhs -->
<div class="flex-shrink-0 w-1/4 p-4">
Left menu
</div>
<!-- center -->
<div class="flex-1 flex flex-col bg-white">
<div class="border-b-2 m-4 pb-2 border-gray-200">Search</div>
<main class="flex-1 overflow-y-scroll p-4 bg-indigo-200">
<div class="relative">
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
<div class="mb-64">Overflowing content</div>
</div>
</div>
</main>
<!-- rhs -->
<div class="flex-shrink-0 w-1/4 p-4">
Right sidebar
</div>
</div>
<!-- footer -->
<div class="bg-blue-700 p-4">
Footer
</div>
</div>
</div>

Related

How to set the height of two Bootstrap 4 columns to content height when the columns wrap?

I have 2 scrollable columns in Bootstrap 4 and they work ok:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row flex-grow-1 overflow-hidden">
<div class="col-6 mh-100 overflow-auto">
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
</div>
<div class='col-6 mh-100 overflow-auto'>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
For mobile, I use #media to change mh-100 and overflow and wrap the 2 columns into 1 column like this:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
</div>
<div class='col-12 overflow-visible'>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
This is OK, when scrollbar is visible.
But when there is no scrollbar, both columns have 50% height:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello
</div>
<div class='col-12 overflow-visible'>
World
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
How can I set the height of the first column to fit the content when there is no scrollbar?
I don't want to loose the existing functionality.
I know that the columns will fit the content if I remove flex-grow-1 from the row.
The answer is to use #media to add display: block!important to the row on mobile:
Now it works with the scrollbar:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row d-block flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
</div>
<div class='col-12 overflow-visible'>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
And it works when there is no scrollbar:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row d-block flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello
</div>
<div class='col-12 overflow-visible'>
World
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>

CSS (Tailwind) Grid height 100vh not working

currently im trying to create a Layout which fills the whole screen.
Thought its very easy but found out it doesn't work as expected.
Here is a Fiddle https://jsfiddle.net/s5ocg3v8/36/
<div class="h-screen grid grid-rows-[auto_1fr] p-5">
<div class="bg-slate-200 mb-1 p-2">Header</div>
<div class="grid grid-cols-[auto_1fr]">
<div class="bg-slate-200 mr-1 p-2">Navigation</div>
<div class="bg-slate-200 p-2 overflow-y-auto">
Container
<div class="border-2 border-black" style="height: 1000px;">
Content
</div>
</div>
</div>
</div>
if the content gets bigger than the container, the defined height is ignored.
i want the layout to always fill the whole screen but not more, if the content is bigger then it should show a scrollbar for the container.
i could set the header to a fixed height and then use calc(100%-headerHeight) but thats not really what i want
Just add min-h-0 to the second grid container.
<script src="https://cdn.tailwindcss.com"></script>
<div class="h-screen grid grid-rows-[auto_1fr] p-5">
<div class="bg-slate-200 mb-1 p-2">Header</div>
<div class="grid grid-cols-[auto_1fr] min-h-0">
<div class="bg-slate-200 mr-1 p-2">Navigation</div>
<div class="bg-slate-200 p-2 overflow-y-auto">
Container
<div class="border-2 border-black" style="height: 1000px;">
Content
</div>
</div>
</div>
</div>
Or always prefer minmax(0,1fr) instead of 1fr
<script src="https://cdn.tailwindcss.com"></script>
<div class="h-screen grid grid-rows-[auto_minmax(0,1fr)] p-5">
<div class="bg-slate-200 mb-1 p-2">Header</div>
<div class="grid grid-cols-[auto_1fr]">
<div class="bg-slate-200 mr-1 p-2">Navigation</div>
<div class="bg-slate-200 p-2 overflow-y-auto">
Container
<div class="border-2 border-black" style="height: 1000px;">
Content
</div>
</div>
</div>
</div>

How to center a text vertically in a Bootstrap footer?

what is the best way to create a footer in Bootstrap where in the middle (horizontally) of the screen is a text with two lines and at the end of the screen (horizontally) is a text with one line, but centered vertically?
I try to create the footer with columns and offset columns - but is it the best way? Additional I don't figured out how to center the one line.
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<footer class="bg-secondary py-0 mt-auto">
<div class="container-fluid px-5">
<div class="row">
<div class="col-6 offset-3 text-center">
<div class="m-0">First Line</div>
<div class="m-0">Second Line</div>
</div>
<div class="col-3 text-end">
<div class="m-0">One Line Centered</div>
</div>
</div>
</div>
</footer>
Edit:
The correct way to do this in modern browsers is to use Flexbox.
See this for details.
I'm updating my code:- [I'm adding a border in each div to clear your expectation]
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<style> div{ border: 1px solid green;} </style>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<footer class="bg-secondary py-0 mt-auto">
<div class="container-fluid px-5">
<div class="row">
<div class="col-6 offset-3 text-center">
<div class="m-0">First Line</div>
<div class="m-0">Second Line</div>
</div>
<div class="col-3 text-end" style="display: table; overflow: hidden;">
<div class="m-0 text-center" style="display: table-cell; vertical-align: middle;">One Line Centered</div>
</div>
</div>
</div>
</footer>

Bootstrap flex containers equal height for children

I am trying to rewrite html table to bootstrap flex divs.
Stack on how to keep the same height of logical child elements of containers?
https://jsfiddle.net/48qdk3r5/1/
It looks some buggy behaviour then I try set up .content height to 100%, the next row of elements overflows first row.
<div class="container">
<div class="row">
<div class="col">
<div class="header">
<h2>Header</h2>
</div>
<div class="content d-flex">
<div class="text-center w-50">
<h3>Sub1</h3>
<p>Iam sub 1.</p>
</div>
<div class="text-center w-50">
<h3>Sub2</h3>
<p>Iam sub 2.</p>
<p>Iam sub 2.</p>
</div>
</div>
</div>
<div class="col">
<div class="header">
<h2>Header3</h2>
</div>
<div class="text-center content">
<h3>Sub3</h3>
<p>Iam sub 3.</p>
</div>
</div>
</div>
<!--end first row -->
<div class="row">
<div class="col">
<div class="header">
<h2>Header</h2>
</div>
<div class="content d-flex">
<div class="text-center w-50">
<h3>Sub1</h3>
<p>Iam sub 1.</p>
</div>
<div class="text-center w-50">
<h3>Sub2</h3>
<p>Iam sub 2.</p>
</div>
</div>
</div>
<div class="col">
<div class="header">
<h2>Header3</h2>
</div>
<div class="text-center content">
<h3>Sub3</h3>
<p>Iam sub 3.</p>
<p>Iam sub 3.</p>
</div>
</div>
</div>
</div>```
I expect all elements of row to be the same height.
You can achieve equal heights by making your .col divs flexboxes, too, and using flex-grow for the .content boxes:
.col{
display: flex;
flex-flow: column;
}
.col .content{
flex-grow: 1;
}
See this updated jsFiddle: https://jsfiddle.net/t29ph10d/

How can I align both boxes, one in top of the other having same size

I am trying to align both of the boxes shown in the code below, using bootstrap flex and grid classes, but somehow both of them have different width.
I tried setting the width of both to width=200px; to see what happened, and flex items lose position.
<!-- total income -->
<div class="container">
<div class="budget__income d-flex justify-content-center mb-2">
<div class="row d-flex justify-content-center col-xs-1">
<div class="budget__income--text py-3">
<strong>Ingresos</strong>
</div>
<div class="budget__income--value py-3">
+ 4,300 </div>
<div class="buget__income--percentage py-3 pl-2 align-self-center ">
34%
</div>
</div>
</div>
<!-- total expense -->
<div class="budget__expense d-flex justify-content-center">
<div class="row d-flex justify-content-center col-xs-1">
<div class="budget__expense--text py-3">
<strong>Gastos</strong>
</div>
<div class="budget__expense--value py-3">
+ 4,300 </div>
<div class="buget__expense--percentage py-3 pl-2 align-self-center ">
22%
</div>
</div>
</div>
</div>
I expect to have both of the specified boxes aligned horizontally, and both having the same width.
Thank you so much,
try with table, table-row and table-cell display. Like:
<div style="display: table">
<div style="display: table-row">
<div style="display: table-cell">
content1
</div>
</div>
<div style="display: table-row">
<div style="display: table-cell">
content2
</div>
</div>
</div>