Overflowing layout with flexbox and bootstrap3 columns causing undesired page width increase - html

I have a layout making use of twitter-bootstrap-3 columns and flexbox.
At a highlevel, the layout I am trying to achieve is like this:
The toolbar and the rest of the content are flexed next to each other (dashed boxes are the children of the flex):
The non-toolbar sections (the green, blue and yellow boxes) are one bootstrap3 row, with three columns (columns are dashed boxes). On large screens the layout should be like the image (meta + main content is col-md-7, secondary #1 is col-md-5, secondary #2 is col-md-12), but defaulting to separate rows on small screens (all col-sm-12):
Finally, the meta and main content (the green and blue boxes) are flexed next to each other (dashed boxes are the children of the flex):
The tricky part is that the main content (the blue section) can get quite wide and must scroll horizontally. The issue I am running into is that as the overflowing content section gets larger, it seems to push the screen artificially wide and escape the boundaries of the bootstrap column.
Here is a simplified example showcasing the issue. (You might have to click "Full page" link to see the overflow issue.)
Is there any way to get around this issue?
.flex {
display: flex;
}
.flex-variable {
flex: 1 1 auto;
/*flex:1;*/
}
.w-100 {
width: 100%;
}
.overflowable-h {
overflow-x: auto;
}
div {
border: 1px gray solid;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container-fluid">
<h1>overflowing content</h1>
<div class="flex">
<div>toolbar</div>
<div class="flex-variable">
<div class="row">
<div class="col-md-7">
<div class="flex">
<div class="text-nowrap">
<table>
<tr>
<td>metadata</td>
<td>metadata</td>
</tr>
<tr>
<td>metadata</td>
<td>metadata</td>
</tr>
</table>
</div>
<div class="flex-variable w-100 text-nowrap overflowable-h">
<table>
<tr>
<td>content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content-content</td>
</tr>
<tr>
<td>content-content-content-content-content-content-content-content-content</td>
</tr>
</table>
</div>
</div>
</div>
<div class="col-md-5">
<div>secondary-secondary-secondary-secondary-secondary-secondary</div>
</div>
<div class="col-md-12">secondary-secondary-secondary-secondary-secondary-secondary-secondary-secondary-secondary</div>
</div>
</div>
</div>
<h1>no overflowing content</h1>
<div class="flex">
<div>toolbar</div>
<div class="flex-variable">
<div class="row">
<div class="col-md-7">
<div class="flex">
<div class="text-nowrap">
<table>
<tr>
<td>metadata</td>
<td>metadata</td>
</tr>
<tr>
<td>metadata</td>
<td>metadata</td>
</tr>
</table>
</div>
<div class="flex-variable w-100 text-nowrap overflowable-h">
<table>
<tr>
<td>content-content</td>
</tr>
<tr>
<td>content-content-content</td>
</tr>
</table>
</div>
</div>
</div>
<div class="col-md-5">
<div>secondary-secondary-secondary-secondary-secondary-secondary</div>
</div>
<div class="col-md-12">secondary-secondary-secondary-secondary-secondary-secondary-secondary-secondary-secondary</div>
</div>
</div>
</div>
</div>
</body>
</html>

if i understand correct, try this:
add and modify your css like below: (toolbar can have any fixed width px/rem/vw/percent and Your flex-variable should calc available width based on toolbar width)
#toolbar{width:200px;}
.flex-variable {
flex: 1 1 auto;
width: calc(100% - 200px);
}
and add id to toolbard div
<div id="toolbar">toolbar</div>
You can achive this in many ways, but your container should have some width to not overflow.

Related

Equal distribution of height across multiple Flex Columns [duplicate]

This question already has answers here:
Align child elements of different blocks
(3 answers)
Closed 10 months ago.
We have the following problem:
It is about accommodating three boxes in a row, which should have the same height. In addition, the boxes each contain two parts: an introductory block and a detailed description.
If we now build the whole thing with Bootstrap 4, this is the structure:
/**
* CSS just for visualization
**/
.block-wrap {
background: lightgrey;
height: 50px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
</div>
We want the blocks (cols) to always have the same height - this means that the tallest block (based on the content) dictates the height of the others. We achieve this by setting the height of all blocks to 100 percent. It will look somewhat like this:
Now it gets tricky. While the blocks should always have the same height among themselves, the detail blocks should always start at the same height, like this:
Any idea how we can achieve this - it is important that the responsive behavior is retained and the blocks also make sense on mobile.
Edit:
I found a simple solution while stumbling across another problem - in hindsight I wonder why I didn't think of that right away, after all I've already worked with it. Thats how it works:
Bootstrap comes with a function to sort the columns. So in the end I just created a row with 6 columns. I then gave them a sorting on the different devices during the break.
I have recreated it again for you to illustrate:
Codepen fullscreen
we can use table to do that. not sure if we can do that flex box or grid without using javascript
.container {
border: 1px solid black;
border-collapse: collapse;
}
.intro {
background:lightblue;
}
.intro div{
background:orange;
}
.details div{
background:lightgreen;
}
.details {
height:100px;
background:lightblue;
}
table td {
width: 1%;
border: 1px solid black;
padding:10px;
vertical-align:top;
}
table td.details{
vertical-align:bottom;
}
.ch-50 {
height: 5em;
}
.ch-75 {
height: 7.5rem;
}
.ch-100 {
height: 10rem;
}
.ch-20 {
height: 2rem;
}
table{width:100%;}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<table class="container">
<tr>
<td class="intro ch-50">
<div class="h-75"></div>
</td>
<td class="intro ch-75">
<div class="h-100"></div>
</td>
<td class="intro ch-100">
<div class="h-50"></div>
</td>
</tr>
<td class="details">
<div class="h-50"></div>
</td>
<td class="details">
<div class="h-75"></div>
</td>
<td class="details">
<div class="h-100"></div>
</td>
<tr>
</tr>
</table>
/**
* CSS just for visualization
**/
.row {
display: flex;
}
.block-wrap {
background: lightgrey;
flex: 1;
border: 1px solid;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-4 block-wrap">
<div>
Intro text
Intro text
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
Intro text
Intro text
Intro text
</div>
<div>
<p>Detais text</p>
<p>Detais text</p>
<p>Detais text</p>
<p>Detais text</p>
</div>
</div>
</div>
Please check the properties of flex that I have given to block-wrap. You have to give class to Intro Text as well if you want the height of that column to be same as well

Stretch one div and display another one below to use entire parent div area but make the top div scrollable if too large

I need to have a div (divParent) which needs to have 2 other divs (divContainer, divButtons) where the divButton will display at the very bottom of the DivParent and the divContainer will use the entire remaining space of the divParent up to the divButton, but it cannot overlap the divButtons and if the content of the divContainer is too big, I need the vertical scrollbar to be displayed.
I've got the following more or less working but the divContainer seems to be overlapping the divButtons and it does not display the vertical scrollbar if the content is too big, even when I specify overflow: auto or overflow-y: auto.
<div id="divParent" style="width: 100%; height: 100%; background-color: red; position: relative">
<div id="divContainer" style="overflow-y:auto;">
<table id="fields">
<large content goes here>
</table>
</div>
<div id="divButtons" style="width: 100%; background-color: blue; position: absolute; bottom: 0">
<div style="float:right;">
<table>
<tr>
<td style="padding: 2px">
<div id="submitbutton">test1</div>
</td>
<td style="padding: 2px">
<div id="cancelbutton">test2</div>
</td>
</tr>
</table>
</div>
</div>
</div>
If I specify "max-height:100px" on the divContainer to test, it does exactly what I need where the vertical scrollbar is displayed but it's clearly no longer stretched all the way to the divButton.
Note that the divParent is then used in a third-party popup window.
Any suggestions?
Thanks.
I eventually figured it out, but credit to #Brad for his answer in:
from How do I make a div stretch in a flexbox of dynamic height?
I had to rejig a few things but eventually got there and my divs are defined as follows now:
<div id='divParent' style='display: flex;
flex-direction: column; height: 100%; width: 100%;'>
<div id='divContainer' style='width: 100%; flex-grow:1;
overflow: auto'>
<div id='divButtons' style='width: 100%; height: 40px;
margin-top: 5px'>
That'it!
Install bootstrap and you will have great control of div placements. Bootstrap creates 12 columns for each row:
<div class="row">
<div class="col-md-7" align="right">
<div class="row">
</div>
<div class="row">
</div>
</div>
<div class="col-md-3" align="left">
</div>
<div class="col-md-2" style="padding-right:2%;">
</div>
</div>

how to replace a div with other div only for screen sizes less than 567 px without any click event [duplicate]

This question already has answers here:
Div show/hide media query
(3 answers)
Closed 4 years ago.
//Here i have 2 divs i want div1 to be displayed on the screen before 567px but after 567px screen size i want div2 to get displayed instaed of div1
//this my div1 which should be displayed above 567px screen size
<table style="width:100%">
<thead>
<tr class="header">
<th>PARAMETERS </th>
<th>Scio </th>
<th>Path Lab</th>
<th>Fitness Apps</th>
<th>Insurance Co’s</th>
<th>Teleconsultant App</th>
</tr>
</thead>
<tbody>
<tr>
<td>Annual Blood Test </td>
<td><img src="/static/success.png"></td>
<td><img src="/static/success.png"></td>
<td></td>
<td><img src="/static/success.png"></td>
<td></td>
</tr>
<tr>
//this is my div2 which i want to get displlayed instead of div but only for the screen sizes less and equal to 567px
<div class="card-container">
<div class="table-cards">
<div class= "card1">
<div class="rows head-row">
<div>Annual Blood Test </div>
</div>
<div class="rows">
<div>Scio</div>
<div><img src="/static/success.png"></div>
</div>
<div class="rows">
<div>Path Labs</div>
<div><img src="/static/success.png"></div>
</div>
<div class="rows">
<div>Fitness Apps</div>
<div></div>
</div>
<div class="rows">
<div>Insurance Co's</div>
<div><img src="/static/success.png"></div>
</div>
<div class="rows">
<div>Teleconsultant App</div>
<div></div>
</div>
</div>
</div>
please help me with this and let me know the most easier way of doing it
With css you can do a media query and hide the div you want, your css will be something like this:
div2{ display: none }
div1{ display: block}
#media (max-width: 567px){
div2{ display: block }
div1{ display: none }
}

Bootstrap stretch contents on entire screen

I am using bootstrap for responsive design.
I want contents to auto-fill depend on the screen size (Which bootstrap allows in-built). Although it is not working when I am connecting to the big monitor (22 inch)
See as below:
Picture 1 (on my Laptop); Covers the entire screen
Picture 2 on Big Monitor (Notice the empty area in the bottom)
(Between Header 6 and End of Browser window)
I expect Headers and contents will be displayed big to cover the entire screen
HTML as below:
<div class="container-fluid">
<div class="row" >
<table class="table">
<tr>
<td><img alt="Bootstrap Image Preview" src="Images/Logo.png"></td>
<td align="right"><img alt="Bootstrap Image Preview" src="Images/Header_RequestExpress.png"></td>
</tr>
</table>
</div>
<div class="row" style="border:1px solid; color:Red;">
<div class="col-md-4" style="border:1px solid; color:green;">
<h2>Categories</h2>
<!--Images Carousel Here-->
</div>
<div class="col-md-8">
<div class="row" style="border:1px solid; color:blue;">
<div class="col-md-12">
<h2>Locations</h2>
<!--Images Carousel Here-->
</div>
</div>
<div class="row" style="border:1px solid; color:Maroon;">
<div class="col-md-12">
<h2>Location Current Requests</h2>
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
<h4>Header 4</h4>
<h5>Header 5</h5>
<h6>Header 6</h6>
</div>
</div>
</div>
</div>
Apply height:100vh;to the container div.
In your example, on your laptop it was just lucky to appear that way, with the content you filled as you didn't put any rule for the page to be full-height.
You either have to proportion .table and .row vertically.
Example:
.table {
height: 30vh;
}
.row {
height: 70vw;
}
Or let's say the table height is 100px and you want the other part to be filled for the rest of the screen, you can apply:
.table {
height: 200px;
}
.row {
height: calc(100vh - 200px);
}
NOTE I'd suggest you add another class as well to the div .row as that class can be used other places as well, as the Bootstrap provides it.

Is it possible to layout span/div in this way?

Im generating a table in php, and would like it in the top left of the screen.
The table varies slightly in width so directly to the right of it should go two blocks of text (text1, text2) and a third text (text3) which floats in the topmost right of the screen.
Below the three texts should be text4.
Requirements:
Text1 needs to always be to the right of the table.
text4 always needs to be below the top 3 texts.
I uploaded an image with the span/div/table/text and have literally been trying to arrange these for about 1.5 hours now. it seems like it should be really simple but im struggling with my requirements and one of them always seems to misalign. (all the 'texts' are just pieces of html text (not <input type=text or <textarea>)
Edit: Thankyou, is it possible without using libraries or bootstrap?
If you don't like using <table> tags for layouts, and don't like an extra large dependency to your project (like bootstrap), one could go for the following option:
<div class="table">
Table
</div>
<div class="text-container">
<div class="text1">
Text1
</div>
<div class="text2">
Text2
</div>
<div class="text3">
Text3
</div>
<div class="text4">
Text4
</div>
</div>
It is crucial that the display type of .table, .text-container and .text{1,2,3} are all display: inline-block;. This will make them inline. However, to force wrapping of .text4, this will still have to be display: block;.
https://jsfiddle.net/nnLofpL1/
Like hjardine uses in his example: it may also be a good idea to look to the clear property.
However it is not the nicest solution, the classic "table in table" does the job:
<table>
<tr>
<td>
<table>
<tr>
<td>PHP generated data</td>
</tr>
</table>
</td>
<td>
<table>
<tr style="height: 60px;">
<td>Text 1</td>
<td style="padding-left: 100px;">Text 2</td>
<td style="width: 200px; text-align: right;">Text 3</td>
</tr>
<tr style="height: 60px;">
<td colspan="3">Text 4</td>
</tr>
</table>
</td>
</tr>
</table>
https://jsfiddle.net/jrrfbqfk/
I can see you don't want to use bootstrap so i have updated an answer so that you don't have to use a table either, exact same output but without the problems of using a table for output.
.div1{float:left;width:40%;border:1px solid #000;min-height:200px;}
.div2{float:right;width:58%;border:1px solid #000;min-height:200px;}
.row1{min-height:100px;}
.sp1{float:left;width:30%;padding:4px;border:1px solid #000;min-height:60px;}
.sp2{float:left;width:30%;padding:4px;border:1px solid #000;min-height:60px;}
.sp3{float:right;width:30%;text-align:right;padding:4px;border:1px solid #000;min-height:60px;}
.divRow{width:100%;border: 1px solid #000;}
<div>
<div class="div1">
<div class="divRow">1</div>
<div class="divRow">2</div>
<div class="divRow">3</div>
<div class="divRow">4</div>
<div class="divRow">5</div>
<div class="divRow">6</div>
</div>
<div class="div2">
<div>
<div class="row1">
<div class="sp1">1</div>
<div class="sp2">2</div>
<div class="sp3">3</div>
<div style="clear:both;"></div>
</div>
<div class="row2" style="border:1px solid #000;min-height:40px;">
sadsadsad
</div>
</div>
</div>
<div style="clear:both;">
</div>
</div>
An easy solution to laying out a page so that things are where you want them is using bootstrap, because of the grid layout in bootstrap you can keep things in the same relative positions no matter what the size of the page is.
For what you want to do i think it would benefit you greatly.
EXAMPLE
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<div class="Container">
<div class="row">
<div class="col-xs-2">
Top left
</div>
<div class="col-xs-2 col-xs-offset-8">
Top right
</div>
</div>
</div>
This is a link to Bootstrap which is well worth learning IMHO!