Browsers render multiple tbody height differently - html

Here is an example, containing a table element with multiple tbody elements
https://jsfiddle.net/aoLbuafx/
HTML
<table>
<tbody class="tbody1">
<tr>
<td>Eka</td>
<td>Toka</td>
<td>Kolmas</td>
</tr>
</tbody>
<tbody class="tbody2">
<tr>
<td>Sisältö</td>
<td>Sisältö</td>
<td>Sisältö</td>
</tr>
<tr>
<td>Sisältö</td>
<td>Sisältö</td>
<td>Sisältö</td>
</tr>
<tr>
<td>Sisältö</td>
<td>Sisältö</td>
<td>Sisältö</td>
</tr>
</tbody>
<tbody class="tbody3">
<tr>
<td>Eka</td>
<td>Toka</td>
<td>Kolmas</td>
</tr>
</tbody>
</table>
CSS
table {
height: 500px;
}
.tbody1 {
background-color: red;
}
.tbody2 {
background-color: blue;
}
.tbody3 {
background-color: green;
}
The end results is that browsers render this table very differently. Firefox shares the total height between tbody elements equally, while Chrome prefers to use the first tbody to fill the available space.
Is is possible to help Chrome render the table as Firefox does, sharing the height between tbody elements, while keeping the table height fixed?
Sidenote: Changing the first tbody to thead and the last tbody to tfoot helps a bit, since in this case Chrome prefers the one and only tbody element to fill the available space. Still, it is not what I want.

That's interesting behavior. Without using Javascript to count children and set height accordingly, this can be done with a flexboxes (as can many things).
Here's the HTML:
<div class="table">
<div class="wrap tbody1">
<div class="cell">Eka</div>
<div class="cell">Toka</div>
<div class="cell">Kolmas</div>
</div>
<div class="wrap tbody2">
<div class="cell">Sisältö</div>
<div class="cell">Sisältö</div>
<div class="cell">Sisältö</div>
</div>
<div class="wrap tbody2">
<div class="cell">Sisältö</div>
<div class="cell">Sisältö</div>
<div class="cell">Sisältö</div>
</div>
<div class="wrap tbody2">
<div class="cell">Sisältö</div>
<div class="cell">Sisältö</div>
<div class="cell">Sisältö</div>
</div>
<div class="wrap tbody3">
<div class="cell">Eka</div>
<div class="cell">Toka</div>
<div class="cell">Kolmas</div>
</div>
</div>
And the CSS:
.wrap {
display: flex;
flex: 1;
justify-content: space-between;
}
.cell {
display: flex;
width: 100%;
padding: 5px;
}
.table {
height: 500px;
display: flex;
flex-direction: column;
}
Here's a JSFiddle with some added styles. The property in the flexbox that allows heights to be evening out is the flex:1 on .wrap.

Related

Turn a table row in a css grid layout independent from other rows

I've to rearrange a table like this one using only CSS.
<head>
<style>
table, th, td {border: 1px solid black; border-collapse: collapse; }
th, td {padding: 5px;}
th {text-align: left;}
</style>
</head>
<body>
<table>
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
<th>H4</th>
<th>H5</th>
<th>H6</th>
<th>H7</th>
<th>H8</th>
<th>H9</th>
<th>H10</th>
</tr>
<tr>
<td class="col-A1">A1</td>
<td class="col-A2">A2</td>
<td class="col-A3">A3</td>
<td class="col-A4">A4</td>
<td class="col-A5">A5</td>
<td class="col-A6">A6</td>
<td class="col-A7">A7</td>
<td class="col-A8">A8</td>
<td class="col-A9">A9</td>
<td class="col-A10">A10</td>
</tr>
<tr>
<td class="col-B1">B1</td>
<td class="col-B2">B2</td>
<td class="col-B3">B3</td>
<td class="col-B4">B4</td>
<td class="col-B5">B5</td>
<td class="col-B6">B6</td>
<td class="col-B7">B7</td>
<td class="col-B8">B8</td>
<td class="col-B9">B9</td>
<td class="col-B10">B10</td>
</tr>
</table>
</body>
How can I get a layout like this?
My initial idea would have been using CSS flexbox but I didn't know how to rearrange the row into this layout, especially the A2 to A7 part in which there are two columns.
So as suggested by comments to original post, I would opt for a CSS grid layout.
This is not possible with tables even if you rearrange the rows because col-A9 and col-A10 occupy 2.5 columns each. And with flexbox you would find difficulty spanning the rows (eg col-A2) and can be solved only if you nest more containers.
But with css grids this is actually easy - you can use a 20-column layout here. See demo with explanations inline:
.wrapper {
display: grid; /* establish a grid container */
grid-template-columns: repeat(20, 1fr); /* 20 columns */
grid-auto-rows: 50px; /* row height for illustration */
}
.wrapper div {
border: 1px solid;
grid-column: span 2; /* span two columns */
/* flexbox to center content*/
display: flex;
justify-content: center;
align-items: center;
}
.wrapper .a {
grid-column: span 10; /* span ten columns */
}
.wrapper .a1 {
grid-column: span 20; /* span all 20 columns */
}
.wrapper .a2 {
grid-row: span 5; /* span five rows */
}
.wrapper .a9,.wrapper .a10{
grid-column: span 5; /* span five columns */
}
<div class="wrapper">
<div class="h">H1</div>
<div class="h">H2</div>
<div class="h">H3</div>
<div class="h">H4</div>
<div class="h">H5</div>
<div class="h">H6</div>
<div class="h">H7</div>
<div class="h">H8</div>
<div class="h">H9</div>
<div class="h">H10</div>
<div class="a a1">A1</div>
<div class="a a2">A2</div>
<div class="a a3">A3</div>
<div class="a a4">A4</div>
<div class="a a5">A5</div>
<div class="a a6">A6</div>
<div class="a a7">A7</div>
<div class="a a8">A8</div>
<div class="a a9">A9</div>
<div class="a a10">A10</div>
<div class="b">B1</div>
<div class="b">B2</div>
<div class="b">B3</div>
<div class="b">B4</div>
<div class="b">B5</div>
<div class="b">B6</div>
<div class="b">B7</div>
<div class="b">B8</div>
<div class="b">B9</div>
<div class="b">B10</div>
</div>

css pdf page - header overlapping with content

As we can see from the image my content overlaps with the header image and this is the code I have:
<style type="text/css" media="print">
#page {
/*size:landscape;*/
#top-center {
content: element(header);
}
#bottom-left {
content: element(footer);
}
}
div.header {
padding: 10px;
position: running(header);
}
div.footer {
display: block;
padding: 5px;
position: running(footer);
}
.pagenumber:before {
content: counter(page);
}
.pagecount:before {
content: counter(pages);
}
</style>
</head>
<div class="header">
<img src="logo.png" title="logo" width="200px"/>
</div>
<div class="content">
</div>
P.S.: Please don't close this question as duplicate as I have already searched all the questions related to the same but mine looks different as PDF is involved.
Headers and footers are established within the page margins.
So the solution is to increase the page top margin, for example:
#page {
margin-top: 50mm;
}
Method to implement header footer properly in PDF
After finding a lot on internet on different solutions and workaround, I'm finally sharing a way that works for me.
Please add these style to report container (the div in which report is rendered).
<div #scrollingContainer class="col-xxs-9 content-container" style="overflow-x: hidden;width:100%;">
</div>
// Div properties may differ
Wrap the Doc component into the table structure with thead and tfoot according to the size of your header and footer(table is wrapped inside a div).
<div style="width: 100%;">
<table style="table-layout: fixed; width: 100%;"> // Add this css to make main table fixed, child tables will still scroll
<thead class="page-break-before">
<tr>
<td>
<div style="height: 80px;"></div> // space for the respective header
</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<div> Your Data Goes Here........</div>
</td>
</tr>
</tbody>
<tfoot class="show-in-print page-break-after">
<tr>
<td>
<div style="height: 130px;"></div> // space for the respective footer
</td>
</tr>
</tfoot>
</table>
</div>
Sample Header and footer
<div class="page-break-before">
<div>A long header content...</div>
</div>
<div class=" page-break-after">
<p> A long footer content...</p>
</div>

How to position a div to the bottom of the container?

I need to set <div id="group-of-tables"> to the bottom of the <div class="item-content">, and without using absolute position.
HTML:
<div class="item-content">
<div id="group-of-tables">
<table class="item" id="first-table">
<tr>
<td><div class="" id="">1</div></td>
<td><div class="" id="">2</div></td>
<td><div class="" id="">3</div></td>
<td><div class="" id="">4</div></td>
</tr>
</table>
<table class="item" id="second-table" border="1">
<tr>
<td><div class="" id="">Next</div></td>
</tr>
</table>
</div>
</div>
CSS:
.item-content{
height:100%;
}
Something like this:
You could do it with CSS flex, and don't forget to prefix all the flex related rules to make it to work more browsers, visit this link to see more support details, visit this link to learn more.
JsFiddle Demo
html, body {
height: 100%;
margin: 0;
}
.wrap {
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.top {
flex: 1;
}
<div class="wrap">
<div class="top">Top</div>
<div class="bottom">Bottom</div>
</div>

Nested divs with 'display: table-row-group' not laying out properly

I'm building out a hierarchical (recursive) table using Angular. Unfortunately angular's directives are part of the HTML DOM and combined with recursion I end up with nested table elements. I am trying to use CSS table layout rather than the classic <table> elements.
Using table elements everything lays out okay:
<table>
<tr>
<td class="cell">one</div>
<td class="cell">two</div>
<td class="cell">three</div>
</tr>
<tbody>
<tr>
<td>one</td>
<td>two</td>
<td>three</td>
</tr>
<tbody>
<tr>
<td>one</td>
<td>two</td>
<td>three</td>
</tr>
</tbody>
</tbody>
</table>
But if I try to do the same things using CSS the layout gets screwed up:
<style>
.table {
display: table;
width: 100%;
table-layout: fixed;
}
.row {
display: table-row;
}
.cell {
display: table-cell
}
.nolayout {
display: table-row-group
}
</style>
<div class="table">
<div class="row">
<div class="cell">one</div>
<div class="cell">two</div>
<div class="cell">three</div>
</div>
<div class="nolayout">
<div class="row">
<div class="cell">one</div>
<div class="cell">two</div>
<div class="cell">three</div>
</div>
<div class="nolayout">
<div class="row">
<div class="cell">one</div>
<div class="cell">two</div>
<div class="cell">three</div>
</div>
</div>
</div>
</div>
Here's a jsfiddle showing the problem:
http://jsfiddle.net/LjyLz2Le/7/
please change
.nolayout {
display: table-row-group
}
to
.nolayout div {
display: table-row-group
}
Because the nolayout class assign only for the main div, does not sub div. you need assign table-row-group for your cell div
Working Demo

Convert table to div in angularjs using css

In my view form I have this code for table:
<table class ="table table-bordered">
<colgroup span="7"></colgroup>
<tbody>
<tr ng-repeat="tr in rows">
<td ng-repeat="td in tr track by $index">
<span ng-bind-html="td"></span>
</td>
</tr>
</tbody>
Now I want to change from table to div and below is my code:
<div ng-repeat = "tr in rows">
<div ng-repeat="td in tr track by $index">
<div><span ng-bind-html="td"></span></div>
</div>
</div>
But it's not work I try to add some css like this:
<style type="text/css">
div.inline { float:left; }
.clearBoth { clear:both; }
</style>
It doesn't work at all. . Any suggestions?
Indeed <div> tags alone won't do anything and you need CSS.
Here are two different ways to achieve this (see code below):
use display: table, table-row, table-cell for your div to behave like an actual <table>
use display: flex to use the advantages of Flexboxes introduced by CSS3 (not compatible with older browsers)
Live example:
angular.module('test', []).controller('ctrl', function($scope) {
$scope.rows = [['0.0','0.1','0.2'], ['1.0','1.1','1.2']];
});
.cell { padding: 10px; border: 1px solid #999; }
.table { display: table }
.table .row { display: table-row; }
.table .cell { display: table-cell; }
.flexbox { display: flex; flex-direction: column; }
.flexbox .row { display: flex; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="ctrl">
Example using table CSS
<div class="table">
<div class="row" ng-repeat="tr in rows">
<div class="cell" ng-repeat="td in tr track by $index">
{{td}}
</div>
</div>
</div>
<br><br>
Example using flexbox
<div class="flexbox">
<div class="row" ng-repeat="tr in rows">
<div class="cell" ng-repeat="td in tr track by $index">
{{td}}
</div>
</div>
</div>
</div>