Bootstrap equal height column [duplicate] - css

This question already has answers here:
How can I make Bootstrap columns all the same height?
(34 answers)
Closed 7 years ago.
Consider the code below:
<div class="row">
<div class="col-xs-3"><div id="sidebar">sidebar</div></div>
<div class="col-xs-3">content content content content content content content content content content content content content content content</div>
</div>
I want the sidebar always has the height of the right column.
Demo: http://www.bootply.com/FT3DVckZgp

Use table method. It works in all browsers. Give display: table to parent and display: table-cell to children.
.row {
display: table;
}
[class*="col-"] {
float: none;
display: table-cell;
vertical-align: top;
}
Here is the fiddle
Another cool method is with the help of margins.
.row{
overflow: hidden;
}
[class*="col-"]{
margin-bottom: -99999px;
padding-bottom: 99999px;
}
Here is the fiddle

You can use following code to define column of same height by providing display layout as table, table-cell.
Define these CSS classes
.container-sm-height
{
display: table;
padding-left:0px;
padding-right:0px;
}
.row-sm-height
{
display: table;
table-layout: fixed;
height: 100%;
}
.col-sm-height
{
display: table-cell;
float: none;
height: 100%;
}
For Small devices use this media query
#media (min-width: 480px)
{
.row-xs-height {
display: table;
table-layout: fixed;
height: 100%;
width: 100%;
}
.col-xs-height {
display: table-cell;
float: none;
height: 100%;
}
}
Now Apply these classes in your HTML structure as following
<body>
<div class="row container-fluid row-sm-height">
<row class="col-sm-3 col-sm-height" id="sidebar">
<!--your code-->
</row>
<row class="col-sm-9 col-sm-height">
<!--Your code-->
</row>
</div>
</body>

HTML
<div class="row">
<div class="col-xs-3 euqlHeight"><div id="sidebar">sidebar</div></div>
<div class="col-xs-3 euqlHeight">content content content content content content content content content content content content content content content</div>
</div>
JS
var maxHeight = 0;
$(document).ready(function() {
$(".euqlHeight").each(function() {
if ($(this).height() > maxHeight) {
maxHeight = $(this).height();
}
});
$(".euqlHeight").height(maxHeight);
});
$(window).resize(function() {
maxHeight = 0;
$(".euqlHeight").removeAttr("style");
$(".euqlHeight").each(function() {
if ($(this).height() > maxHeight) {
maxHeight = $(this).height();
}
});
$(".euqlHeight").height(maxHeight);
});

Give id to the second right col and on page load use jquery as
$("#sidebar").css("height", $("#IdOfRightDiv").height());

You can Go For the Display:table Property to Get the Output You Desired
Have Tweeted Your Code
Check the above Link
<div class="row" style="display:table">
<div id="sidebar" class="col-xs-3" style="display:table-cell;float:none"><div>sidebar</div></div>
<div class="col-xs-3" style="display:table-cell;float:none">content content content content content content content content content content content content content content content</div>
</div>

Related

CSS Grid - How to implement grid items, which don't "stretch" the grid row and have a scroll-able container

My challenge is:
I want to have a grid with a fixed amount of columns (which can later be adjusted via javascript) and a flexible amount of rows of equal height.
The number of rows are determined by the amount of grid items, which are UI cards.
These cards should fill out the entire height of their respective cell but MUST not increase the height of the row. So basically max-height = row-height assigned by grid
Then inside these cards we have the typical three parts: Header, Body and Footer. The body MUST be scroll-able, if more list items exists than the row-height allows.
I've tried to implement this on stackblitz
https://stackblitz.com/edit/angular-3gkmtm
What i don't understand is
Why the cards "stretches" the row when more items appear
How to achieve the scroll-able card body section without manually using a fixed height (like in the example i use max-height)
Why when there are more then 3 rows, it overflows
Please help!
<article>
<section>
<h2>Fixed Gird with scrollable cards</h2>
</section>
<section>
<button (click)="onAdd()">Add</button>
<button (click)="onRemove()">Remove</button>
</section>
<section class="remaining-height">
<div class="grid-container">
<div class="grid-item" *ngFor="let card of cards">
<div class="card">
<div class="card-header">Card #{{card}}</div>
<div class="card-body card-flexible-scroll">
<div class="list-item" *ngFor="let item of list">{{item}}</div>
</div>
<div class="card-footer">
Some Footer
</div>
</div>
</div>
</div>
</section>
</article>
article{
display: flex;
flex-direction: column;
height: 100%;
}
.remaining-height{
flex:1
}
.grid-container {
display: grid;
grid-gap: 0.5rem;
height: 100%;
grid-auto-rows: auto;
grid-template-columns: repeat(5, auto);
}
.grid-item{
display: flex;
padding:24px;
}
.card{
display: flex;
flex-direction: column;
width: 100%;
height:100%;
background:#ccc;
}
.card-body{
.list-item{
padding: 6px;
background:#fcd3d3;
}
.list-item:nth-child(even){
background:#efefef;
}
}
.card-flexible-scroll{
flex:1;
overflow-y:auto;
max-height: 300px; // <= no max height
}
Angular Controller to generate cards and list items
```js
export class AppComponent {
name = "Angular";
cards = new Array(8).fill(0).map((_,idx)=>idx+1);
list = new Array(30).fill(0).map((_,idx)=>idx+1);
onAdd() {
this.cards.push(this.cards.length + 1);
}
onRemove() {
this.cards.pop();
}
}
global style
html , body{
height: 100vh;
overflow: hidden;
}
If I understand correctly what you are trying to do you want that the card body takes all the available row space between the header and footer and not force the card to be bigger than the row if it contains items.
It is possible to achieve that with adding another div with absolute positioning inside the card body div that is sized to the full body height then the items inside will overflow correctly.
Here is the changed template:
<article>
<section>
<h2>Fixed Gird with scrollable cards</h2>
</section>
<section>
<button (click)="onAdd()">Add</button>
<button (click)="onRemove()">Remove</button>
</section>
<section class="remaining-height">
<div class="grid-container">
<div class="grid-item" *ngFor="let card of cards">
<div class="card">
<div class="card-header">Card #{{card}}</div>
<div class="card-body">
<div class="card-flexible-scroll">
<div class="list-item" *ngFor="let item of list">{{item}}</div>
</div>
</div>
<div class="card-footer">
Some Footer
</div>
</div>
</div>
</div>
</section>
</article>
And the updated CSS:
.card-body{
.list-item{
padding: 6px;
background:#fcd3d3;
}
.list-item:nth-child(even){
background:#efefef;
}
position: relative;
flex:1;
}
.card-flexible-scroll{
position: absolute;
width: 100%;
height: 100%;
max-height: 100%;
overflow-y: auto;
}
I created a fork of your StackBlitz where you can see how it works. If this is not what you look for please explain more.

Expand parent DIV to overflowing content width

I've read quite a few similar questions to mine but none is quite the same or has an answer which works for me.
I'm using Twitter Bootstrap 3. I have two rows, and each row contains a col-sm-12 div, so they're the same width. The content in the first row is wider than its container but I have overflow:auto set on the element containing the two rows so a horizontal scrollbar is displayed and the content can be seen using that, so that's fine.
In the second row I have a div to which I'm applying a jQuery plugin (jqxGrid, for what it's worth). I've set the width option of the plugin to be "100%". The resultant grid's content is also too wide for its container but because of the way the jQuery plugin creates the grid it constricts the grid's width to 100% of its parent's width rather than overflowing.
So what I really need is for the .row elements to all be as wide as the widest overflowing content so that when the jQuery plugin evaluates the width of its parent so as to set its own width, the resultant grid ends up being as wide as the overflowing content in the first row.
I've made a fiddle which I hope will illustrate the problem. I feel that at its heart this is a CSS problem so a pure CSS solution would be excellent, but I doubt that that's possible.
.wrapper {
color: #fff;
padding: 10px;
}
.container-fluid {
background-color: #333;
overflow: auto;
}
.row1 {
background-color: yellow;
}
.row2 {
background-color: orange;
}
.short-content {
background-color: red;
width: 100%;
}
.long-content {
width: 2000px;
background-color: blue;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="wrapper">
<div class="container-fluid">
<div class="row row1">
<div class="col-sm-12">
<div class="long-content">
Long content
</div>
</div>
</div>
<div class="row row2">
<div class="col-sm-12">
<div class="short-content">
THe jQuery plugin here is too wide to fit but won't overflow because its width is set to match its parent.
</div>
</div>
</div>
</div>
</div>
To my understanding, wrapping each .col-sm-12 into their own parent .row is a verbose way of having all .col-sm-12 in a single .row container, as .col-sm-12s are always wrapping into a new line.
So, in case your setup allows for removing the intermediate .row tags, the only additional line of css you have to write is float: left; on .row. (In the example below I used the id #custom on .container-fluid to isolate this modification from the rest of your page).
body {
color: #fff;
padding: 10px;
}
.container-fluid {
background-color: #333;
overflow: auto;
}
.row1 {
background-color: yellow;
}
/*.row2 {
background-color: orange;
}*/
.short-content {
background-color: red;
width: 100%;
}
.long-content {
width:2000px;
background-color: blue;
}
#custom .row {
float: left;
}
<div id="custom" class="container-fluid">
<div class="row row1">
<div class="col-sm-12">
<div class="long-content">
Long content
</div>
</div>
<!-- </div> -->
<!-- <div class="row row2"> -->
<div class="col-sm-12">
<div class="short-content">
THe jQuery plugin here is too wide to fit but won't overflow because its width is set to match its parent.
</div>
</div>
</div>
</div>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>

How to equalise sibling div heights?

<div class="wrapper">
<div class="sidebar-wrapper"></div>
<div class="content-wrapper"></div>
</div>
The height of content-wrapper is dynamic (auto). Is there any way to get the height of it and use it for the sidebar-wrapper so that it looks nice?
Displaying them like table cells would do it. Table cells can adjust their height automatically to the content, and all cells on the same row get the same height. If you give the side bar a fixed width (which is likely), you can easily get the content wrapper to fill the remaining space.
Whichever has the longest content will determine the height.
.wrapper {
width: 100%;
display: table;
}
.sidebar-wrapper,
.content-wrapper {
display: table-cell
}
.sidebar-wrapper {
width: 200px;
background-color: silver;
}
.content-wrapper {
background-color: yellow;
}
<div class="wrapper">
<div class="sidebar-wrapper">Here is <br>content<br>that is .....<br><br><br><br><br><br>Quite long</div>
<div class="content-wrapper">Smaller content</div>
</div>
Flexbox is an alternative to #GolezTrol's CSS tables.
.wrapper {
display: flex;
}
.sidebar-wrapper {
width: 200px;
background-color: silver;
}
.content-wrapper {
background-color: yellow;
flex: 1;
}
<div class="wrapper">
<div class="sidebar-wrapper">Here is
<br>content
<br>that is .....
<br>
<br>
<br>
<br>
<br>
<br>Quite long</div>
<div class="content-wrapper">Smaller content</div>
</div>

Dojo Dgrid - Use remaining space in block

I have a block like this:
<div class="container">
<div class="someStuff">Some stuff of unknown height</div>
<div class="myDGrid" data-dojo-attach-point="dgrid"></div>
</div>
The DGrid is started like this:
new (declare([OnDemandGrid, DijitRegistry]))({
store: ...,
columns: ...
}, this.dgrid);
Requirements:
The container block has some height.
The someStuff block has some height that is dynamically set.
The myDGrid block contains a Dojo DGrid. It should use the remainder of the space in container. For example:
If container is 400px and someStuff is 200px then myDGrid should be 200px.
If container is 300px and someStuff is someStuff is 10px then myDGrid should be 290px.
The dgrid should have scrollbars if all rows cannot be shown.
What is the best way to do this?
One solution is to change the html to this:
<div class="container">
<div class="someStuff">Some stuff of unknown height</div>
<div class="containsDGrid">
<div class="myDGrid" data-dojo-attach-point="dgrid"></div>
</div>
</div>
And then use CSS like this:
.container {
display: table;
}
.someStuff {
display: table-row;
}
.containsDGrid {
display: table-row;
height: 100%;
}
.dgrid {
width: 100%;
height: 100%;
}
.dgrid .dgrid-scroller {
overflow-y: auto;
overflow-x: hidden;
}

2-col to 1-col responsive design layout

I am trying to go from a 2-col layout on Desktop like so:
To a 1-col layout on Mobile like so:
I am having trouble getting container #5 to the correct position on Desktop. My markup (modified for brievity) is like so (this can be changed to whatever):
<div id="container-1></div>
<div id="container-2></div>
<div id="container-3></div>
<div id="container-4></div>
<div id="container-5></div>
On desktop: #1 and #5 are floated left, the rest are floated right. But this causes #5 to be position right next to #4 (#5 top-aligned with #4) instead of right below #1. I thought it should've worked. Am I missing something here?
PS: All the containers' height are fluid
Try wrapping the middle 3 in an extra container and wrapping that.
<div id="container">
<div id="container-1">content content content content content content </div>
<div id="containerwrapper">
<div id="container-2">content content content content content content </div>
<div id="container-3">content content content content content content content content content content content content </div>
<div id="container-4">content content content content content content content content content content content content </div>
</div>
<div id="container-5">content content content content content content </div>
</div>​
and the CSS:
#container { background: none; float: left; width: 340px; }
div { margin: 10px; margin-bottom: 0; background: #0f0; }
#container-1 { float: left; width: 60px; }
#containerwrapper { background: none; float: right; margin: 0; }
#container-2 { width: 240px; }
#container-3 { width: 240px; }
#container-4 { width: 240px; }
#container-5 { float: left; width: 60px; }​
You can see it here: http://jsfiddle.net/GcYuh/

Resources