How to make div rows fill available height - html

I have a simple web page that contains multiple rows. I want to be able to have those rows fill the available space equally (with a minimum height as well). The number of rows is also dynamic.
Here is the code:
.outer {
display: block;
overflow: auto;
height: 100%;
}
.row {
border: 1px solid blue;
background-color: red;
min-height: 120px;
}
<div class="outer">
<div class="row">
test 1
</div>
<div class="row">
test 2
</div>
<div class="row">
test 3
</div>
<div class="row">
test 4
</div>
<div class="row">
test 5
</div>
</div>
The colouring is just there so we can see what is happening.
Any help would be appreciated. The other questions on SO are not helping my specific case. Or at least I can't find one that does :)

.outer {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.row {
flex: 1;
}

Related

Flex-Wrap: Equal (Max-)Width for elements wrapped by column

I've got this Layout https://jsfiddle.net/0f791rwd/1/ with either 2-3 columns (depending on variable data in the real thing). The text inside the elements should break to new lines, instead of overflowing. But as i don't know if there will be 2 or 3 columns i can't set a max-width to each manually.
Is there a way to equally distribute the width of the parent to the wrapped elements?
The real thing is a VueJS Component, just if there's a benefit out of it, which could be useful here.
My Code:
<div id="main">
<div style="background-color:coral;">Very very long Text</div>
<div style="background-color:lightblue;">Long Text</div>
<div style="background-color:khaki;">C</div>
<div style="background-color:pink;">D</div>
<div style="background-color:lightgrey;">Also a very, very long Text</div>
<div style="background-color:lightgreen;">F</div>
</div>
<style>
#main {
width: 200px;
height: 200px;
border: 1px solid #c3c3c3;
display: flex;
flex-direction: column;
flex-wrap: wrap;
div {
height: 50px;
}
}
</style>
Thanks!
You can follow the below code for equal width of column and text wrapping inside the column.
#main {
width: 200px;
border: 1px solid #c3c3c3;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#main div {
height: 50px;
width:50%;
}
<div id="main">
<div style="background-color:coral;">Very very long Text</div>
<div style="background-color:lightblue;">Long Text</div>
<div style="background-color:khaki;">C</div>
<div style="background-color:pink;">D</div>
<div style="background-color:lightgrey;">Also a very, very long Text</div>
<div style="background-color:lightgreen;">F</div>
</div>

Create rows in html which will share height?

<div class="container-fluid">
<div calss="row" style="height:20%; display: block;">
<h1>20 percent height</h1>
</div>
<div calss="row">
<h1>height should be 80 percent</h1>
</div>
</div>
I tried some example which is shown here but it's not working.
My requirement is if i keep first height as 10% or 20% second row should occupy height automatically without setting the height explicitly.
Use flexbox for this type of stuff. Also instead of 80 and 20 you could use 4 and 1, it's just the ratio that matters
.parent {
display: flex;
width: 100vw;
height: 100vh;
flex-direction:column;
}
.top {
flex: 80;
background: red;
}
.bottom {
flex: 20;
background: blue;
}
<div class="parent">
<div class="top"></div>
<div class="bottom"></div>
</div>
Use flex display. Add display: flex and flex-direction: column for the parent and for the second content provide flex-grow: 1 which will fit that div in rest of the space.
.container-fluid {
display: flex;
flex-direction: column;
height: 500px;
}
.container-fluid div {
margin: 5px;
border: 1px solid black;
}
.row-two {
flex-grow: 1;
}
<div class="container-fluid">
<div class="row" style="height:20%; display: block;">
<h1>20 percent height</h1>
</div>
<div class="row row-two">
<h1>height should be 80 percent</h1>
</div>
</div>

Layout a flex box similar to a table?

I'm working with a framework developed in-house which depends on a certain structure to our HTML. And one of the tricky things is that each row needs its own container with its own classes and data attributes.
So here's the problem. Without drastically changing the DOM, how can I make the flex box below render essentially like an HTML table would? Or is a table the only way? The solution will have to work in both IE11 and Chrome.
I'm trying to make it look like this...
Column A | Column B | Column C
1 | 2 | 3
section {
display: flex;
flex-wrap: wrap;
}
section .col {
flex: 1 1 auto;
}
section .line-break {
flex-basis: 100%;
width: 0px;
height: 0px;
overflow: hidden;
}
<html>
<head>
</head>
<body>
<section>
<header>
<div class="col">Column A</div>
<div class="col">Column B</div>
<div class="col">Column C</div>
</header>
<div class="line-break"></div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
</section>
</body>
</html>
header, .row {
display: flex; /* aligns all child elements (flex items) in a row */
}
.col {
flex: 1; /* distributes space on the line equally among items */
}
<section>
<header>
<div class="col">Column A</div>
<div class="col">Column B</div>
<div class="col">Column C</div>
</header>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
</section>
If the content you are going to present is of type tabular data, then a table is the proper way.
HTML 5.1 W3C Recommendation, 1 November 2016, 4.9 Tabular data
Given that you can't, or don't want to, alter the markup, this can be done using CSS Table, and with that easily swap between any display type such as flex, block, etc., or even float, using media query etc.
I also removed the <div class="line-break"></div> element, since you don't need, though if it is rendered by a component or similar, leaving it as is won't cause any problem.
Using CSS Table
section {
display: table;
width: 100%;
}
section > * {
display: table-row;
}
section .col {
display: table-cell;
}
<html>
<head>
</head>
<body>
<section>
<header>
<div class="col">Column A</div>
<div class="col">Column B</div>
<div class="col">Column C</div>
</header>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
</section>
</body>
</html>
If you still need, or have to, use Flexbox, this answer of mine mention the difference between CSS Table and Flexbox on two important features:
Can flexbox handle varying sizes of columns but consistent row height?
Updated, a sample showing some useful Flexbox stuff, with varying width's and span columns.
Using Flexbox
.tbl {
display: flex;
flex-direction: column;
}
.row {
display: flex;
min-height: 50px;
}
.cell {
flex: 4;
border: 1px solid red;
}
.cell:nth-child(1) {
flex: 1;
}
.cell:nth-child(2) {
flex: 2;
}
.cell.span4-5 {
flex: 8 24px; /* col 4,5 flex-grow/border/padding */
}
.cell.span3-4 {
flex: 8 24px; /* col 3,4 flex-grow/border/padding */
}
.cell.span3-5 {
flex: 12 36px; /* col 3,4,5 flex-grow/border/padding */
}
.row:first-child .cell {
display: flex;
justify-content: center; /* center horiz. */
align-items: center; /* center vert. */
}
.row .cell {
padding: 5px;
box-sizing: border-box;
}
<div class="tbl">
<div class="row">
<div class="cell">ID </div>
<div class="cell">Nr </div>
<div class="cell">Header 1 </div>
<div class="cell span4-5"> Header 2 </div>
</div>
<div class="row">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
</div>
<div class="row">
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell span3-5">Content</div>
</div>
<div class="row">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell span3-4">Content</div>
<div class="cell">Content</div>
</div>
</div>
This code works for me:
* {
box-sizing: border-box;
}
body, html {
height: 100%;
margin: 0;
}
#container {
width: 400px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
background-color: lightgrey;
padding: 10px;
}
.shelf {
flex: 1 1 auto;
width: 100%;
margin-bottom: 10px;
border: 1px solid black;
background-color: lightgreen;
display: flex;
flex-direction: row;
}
.shelf:last-child {
margin-bottom: 0;
}
.labelbox {
flex: 0 0 35%;
}
.valuebox {
flex: 0 0 65%;
}
<div id="container">
<div class="shelf">
<div class="labelbox">Name: </div> <div class="valuebox">Barry Carter</div>
</div>
<div class="shelf">
<div class="labelbox">DOB:</div><div class="valuebox">10/12/1980</div>
</div>
<div class="shelf">
<div class="labelbox">
Description:
</div>
<div class="valuebox">
This content goes on and on and will force the height to expand. And the label box to the left will
"move" with it. There need not be much of a relation other than that their parent div/flex-container is
getting taller as well.
</div>
</div>
<div class="shelf">
<div class="labelbox">Group:</div><div class="valuebox">Advanced</div>
</div>
<div class="shelf">
<div class="labelbox">End Date:</div><div class="valuebox">2020-09-20</div>
</div>
</div>
Use CSS Grid. You can style any table the way you like.
Keep in mind If your table is more than 700 rows, the fram rate will start to drop, no matter what js framework you use. react, angular, vue or vanila JS. the scrolling will get real laggy.
And the maximum you row can use is 1000. More than that the extra row will create bad graphic. But you wont reach 1000 anyway, because at 700th row, the scrolling speed, starts to get bad.
If somehow you need to display more than 1000 rows, you will visualized lib. Every js framework has a lib to do so. Basically, it will render the rows in the view port. The rows that not in the view port will not be rendered. They will only be rendered when user scrolls.
This is year 2021, chances you read this answer in the future, the browsers vendor might probably fix the performance of 1000 rows, they might even extend that limit. So try it out.

How can I get even heights of unknown elements inside a column? [duplicate]

This question already has answers here:
Equal height flex items in flex columns
(3 answers)
Closed 5 years ago.
I'm using flex to create even columns and vh to make them the same height. That's working fine but inside the columns I can have an x number of items in them. I'd like for elements in each column to be even height depending on how many items are present (using css).
1 = 100%
2 = 50%
3 = 33.33%
etc.
I know I can do this through JS but I'd like to automate this through css via flex, grid, or something elese.
I've tried replicating your problem. Use flex: 1 on .items so that each and every item take equal space (according to the problem statement).
Have a look at the snippet below:
body {
margin: 0;
}
.parent {
width: 80%;
padding: 20px;
display: flex;
border: 1px solid red;
}
.child {
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-end;
padding: 20px;
border: 1px solid blue;
height: 60vh;
}
.item {
flex: 1;
background: lightGreen;
border: 1px solid green;
}
<div class="parent">
<div class="child">
<div class="item">33.33%</div>
<div class="item">33.33%</div>
<div class="item">33.33%</div>
</div>
<div class="child">
<div class="item">50%</div>
<div class="item">50%</div>
</div>
<div class="child">
<div class="item">100%</div>
</div>
</div>
Hope this is what you are trying to achieve.
This is all you need to make it work with the Flexbox:
.flex-container {
display: flex;
}
.flex-item {
display: flex;
flex-direction: column;
flex: 1;
}
.item {
flex: 1;
border: 1px solid;
}
<div class="flex-container">
<div class="flex-item">
<div class="item">1/1</div>
</div>
<div class="flex-item">
<div class="item">1/2</div>
<div class="item">1/2</div>
</div>
<div class="flex-item">
<div class="item">1/3</div>
<div class="item">1/3</div>
<div class="item">1/3</div>
</div>
<div class="flex-item">
<div class="item">1/4</div>
<div class="item">1/4</div>
<div class="item">1/4</div>
<div class="item">1/4</div>
</div>
</div>

How to make a Bootstrap row background color fill the rest of the page?

When we make a webpage with Bootstrap, we use rows that we put in a container, so if do this with 2 rows, how to make the 2nde one to fill the entire page ?
I.e if I have those 2 rows:
here
How do I make the 2nde one (the blue one) to fill the rest of the page ?
Thank you
The HTML code is:
<body>
<div class="container-fluid">
<div class="row row1">
<br>
</div>
<div class="row row2">
<br>
</div>
</div>
</body>
And the css is:
.row1{
background-color: orange;
}
.row2{
background-color: blue;
}
p.s: I just want to transform the rows properties, not use one row and color the rest of the page with the backgroud color of the body.
You can use flex layout to implement what you want. Here is an example:
* {
margin: 0;
}
html, body {
height: 100%;
}
.row1{
background-color: orange;
}
.row2{
background-color: blue;
}
.container-fluid {
display: flex;
flex-direction: column;
height: 100%;
}
.row:last-child {
flex: 1;
}
<div class="container-fluid">
<div class="row row1">
<br>
</div>
<div class="row row2">
<br>
</div>
</div>
A jsfiddle is also made for reference.
Some explanation for the key code:
display: flex;: use flex layout for items inside of display: flex.
flex-direction: column;: arrange .rows vertically.
flex: 1;: make the last child of .container-fluid (.row2 in your case) grow/shrink automatically.