Stretch <canvas> to fill flex item without any scrollbars - html

I am using Bootstrap 5 and trying to set up a nested flex layout that fills the window, with one flex item filled by a "stretchy" <canvas> (so no scrollbars anywhere).
For some reason, creating the canvas with w-100 and h-100 utilities (equivalent to setting CSS width and height to 100%) is creating a vertical scrollbar on the page. I've seen numerous similar questions around the interwebs, but they almost all deal with flex-direction: row and don't seem to work for my column scenario. I can't tell if this is a bug in Bootstrap, or if I'm just misunderstanding nested flex containers and/or canvases.
Here is a Codepen that reproduces the issue: https://codepen.io/Rabadash8820/pen/eYWwXxx
And here is the HTML body:
<body class="d-flex flex-column vh-100">
<div class="alert alert-warning alert-dismissible fade show" role="alert">
Alert alert!
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Warning"></button>
</div>
<header>
Header content
</header>
<div class="flex-grow-1 d-flex">
<div class="flex-grow-1 d-flex flex-column">
<main class="flex-grow-1 bg-dark">
<canvas class="d-block w-100 h-100"></canvas>
</main>
<footer>Footer content</footer>
</div>
<div class="w-25"><h2>Options</h2></div>
</div>
</body>

Switch from the default min-height: auto to min-height: 0 for your flex items to suppress the minimum content size of your canvas.
You’re seeing the scrollbars because when you set width: 100% on canvas, it tries to maintain its 2:1 aspect ratio, which affects its height. That height is communicated to the parents of canvas, which are flex items inside flex containers. By default, flex items don’t shrink below their min-content size, which is affected by the aspect ratio.
To prevent this from happening, you can set min-height: 0 on your <div class="flex-grow-1 d-flex"> and <main class="flex-grow-1 bg-dark"> elements, like this:
<div class="flex-grow-1 d-flex" style="min-height: 0;">
<div class="flex-grow-1 d-flex flex-column">
<main class="flex-grow-1 bg-dark" style="min-height: 0;">
<canvas class="d-block w-100 h-100"></canvas>
</main>
<footer>Footer content</footer>
</div>
<div class="w-25"><h2>Options</h2></div>
</div>
Then, they will let their flex containers shrink them, and then your canvas settings of 100% width and height will refer to that shrunk size.
If you don’t want to write custom CSS, I guess the solution would be to find Bootstrap classes that correspond to setting min-height: 0.

Related

How can I achieve this two-column layout with Tailwind?

I need to create three divs positioned like below:
Green div should be 75% width and red divs should have 25% width and 50% of height, placed in column. And everything should be responsive.
Right now I have something like here:
<div className="w-full">
<div className="w-3/4 float-left">
</div>
<div className="w-1/4 float-right">
<div id="red-one"></div>
<div id="red-two"></div>
</div>
</div>
but it not this same as i expected :/
can someone tell me how to do this?
thanks for any help!
Oldish option (see nowdays below that one) :you can use and mix the table-layout display and regular block display via tailwind class
Possible example
/* your scrennshot's borders */
div div {border:solid red;}
div.table-cell{border-color:green}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet"/>
<div class="table w-full p-2">
<div class="table-cell w-3/4 p-2">hello</div>
<div class="p-2 ml-2"> the</div>
<div class="p-2 mt-2 ml-2">world</div>
</div>
any draw back ?
yes, if both content of the rights side div are shorter than the content of the left one, it wont fill the column
nowdays option: grid
Advised example:
div div {border:solid red;}
div div:first-child{border-color:green}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet"/>
<div class="grid grid-cols-4 p-2 grid-cols-2 gap-2">
<div class="col-1 col-span-3 row-span-2 p-2">hello</div>
<div class="col-2 p-2"> the</div>
<div class="col-2 p-2">world</div>
</div>
drawbacks ? none, but you will have to create your own class to set the grid-template-colums property to match your columns's widths as commented by #bqardi
Container: grid grid-cols-4 and green div: col-span-3 row-span-2? No need to create own class

Using flexbox grow but allow the content to overflow

I'm a bit new to using flexbox and I've ran into one problem I can't seem to fix.
What I want:
I want to have a container taking the available height, but whenever the content inside it takes up more space than the containers height, apply overflow:scroll
Context:
Ref image:
container image
As you see on the image, everything inside of the red brackets are covered inside of a div with flex-grow:1, I want this because the images might be different sizes so therefore I need the div to take the reamining space.
As for the white container, that is also using flex-grow:1 so that the button can be on the bottom of the div.
Now, what I would like is for the content inside of the blue brackets to be taking the available height, but if there is more content than the available height, then I want it to be scrollable.
The thing that happens now if I add a lot more content to the container inside of the blue brackets, it pushes everything below it further down, meaning the overflow isn't working.
E.g Like so
As you see in the image, everything is just pushed further down and the div is being stretched.
Here is the code I have so far:
<div class="flex flex-col grow overflow-y-auto w-3/4 my-2 mx-auto bg-white max-h-full">
<!-- img -->
<div>
<img [src]="currentUser.photoURL" class="w-full mx-auto">
</div>
<!-- information -->
<div class="flex flex-col text-black grow">
<!-- Info -->
<div class="flex flex-col p-2 divide-y grow overflow-y-auto">
<div class="flex flex-col">
<p class="font-bold">{{currentUser.displayName}}</p>
<p class="font-thin">{{currentUser.email}}</p>
</div>
<div class="p-2 overflow-y-auto max-h-[90%]">
<div class="h-full grow-0 overflow-y-auto">
<p>
some information about {{currentUser.displayName}}
</p>
<ul>
<li>
Some values are
</li>
<li>
Some experience are...
</li>
<li>
Why im helping people...
</li>
</ul>
</div>
</div>
</div>
<!-- Message -->
<div class="shrink-0 p-2 text-center w-full bg-blue-500">
<button>Send melding</button>
</div>
</div>
</div>
I'm using tailwindCSS for this project, but will happily take suggestions in normal css as well.
I think the simplest solution for this would be to set the div you want to be a scrollable as "display: block" (or at least some version of block) with a fixed height. Once you apply that fixed height, your overflow content ought to be scrollable.

How to fit word length and height to fit container

I am trying to fit some text while designing on html and css, and I can't seem to find a way to do it.
I currently have this
and the objective is to have as it is here
what seems the best way to do this?
<div class="container h-100">
<div class="row h-100 align-items-center justify-content-center text-center">
<div class="col-lg-10 align-self-end">
<h1 class="text-uppercase text-white font-weight-bold adjust">Ignition<br>Dimension</h1>
</div>
</div>
</div>
This is not possible with just CSS. You need JavaScript to adjust the text size depending on its parent container. See https://css-tricks.com/fitting-text-to-a-container/
There is a proposal for CSS Container Queries but this has only been implemented in Chrome behind a flag
Except your parent container has the same width and height as your viewport. In that case, you could use vh/ vw to adjust the size based on the viewport

Overflow causing entire page to scroll

I am trying to create a page that doesn't scroll. Certain child elements on the page can scroll, but I'm trying to prevent the page as a whole from scrolling. I have a very nested child element that, when overflowed, receives a scroll bar, but also causes the main document to grow and receive a scroll bar as well.
This is the heart of the issue, but there are a few more nested levels that may be a factor.
<div class="h-100 d-flex flex-column">
<div class="d-flex align-items-center justify-content-center bg-red" style="height: 7%">
</div>
<div class="d-flex align-items-center justify-content-center bg-red" style="height: 3%">
</div>
<div class="bg-green" style="max-height: 75%; height: 75%; overflow-y: auto;">
<div class="bg-gray m-4" style="height: 2000px;">
The height of this content causes BOTH scroll bars to appear. I only want a bar on the
'green section'
</div>
</div>
<div class="bg-red flex-grow-1">
</div>
</div>
This code pen demonstrates how my app is set up. The overflowing element is nested deep within many flex displays (coming from bootstrap 4 utility classes).
https://codepen.io/averyferrante/pen/YMdNpO
I want only the green section from the code pen to scroll, not the entire document to grow/scroll as well.
The problem is that a couple of your containers are missing height definitions. As a result, the children of those containers ignore the percentage heights applied to them.
Add this to your code:
<div class="flex-grow-1" style="height: calc(100% - 48px);">
This height rule gives the container a defined height while compensating for the height of its sibling.
Another height rule was missing three levels down:
<div class="d-flex flex-column w-100" style="height: 100%;">
revised codepen
More detailed explanations:
Working with the CSS height property and percentage values
Chrome / Safari not filling 100% height of flex parent
Did you try playing with position: absolute? You can then set width and height as needed and the red box will see its scrollbar disappear!

Bootstrap 4: Text on image displaced on difference screen size

I want the text to look like this on my image:
which is slightly away from the "Center" point of the image(as i want to avoid the phone in the image), so text-center wouldnt work. I currently set the division of the row to "relative" and the text to "Absolute" in order to even get the text on top of the image. But when i resize the image, it will be displaced.
Code:
<section>
<div class="col-lg-12 text-center"style="margin: 0;padding: 0;position: relative;">
<img class="img-fluid" style="width:100%;" src="img/phone-transparent.png" alt=""></img>
<h2 style="color:red;position: absolute; top: 120px; width: 100%;">This is also</br>available on your mobile.</h2>
</div>
</section>
On original screensize:
On a different screensize:
This can be done using only Bootstrap 4 classes. Read the documentation on using the grid, and the utility classes for positioning and flexbox. You don't need all the inline CSS styles.
<div class="container-fluid">
<section class="row no-gutter align-items-center">
<div class="col-lg-12 text-center p-0 d-flex align-items-center">
<img class="img-fluid position-relative mx-auto" src="//placehold.it/1900x400" alt="">
<h3 class="w-100 position-absolute text-danger my-auto">This is also<br>available on your mobile.</h3>
</div>
</section>
</div>
Demo
Remember that .col-* must be placed in the .row, and the .row
should be inside a container.
You can use the spacing utils and CSS object-fit on the image to get the position and size: Demo 2 (you will need to tweak this as desired).