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

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

Related

Browsers render multiple tbody height differently

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.

Bulma overlapping items

I'm using bulma.css for a layout, but when I give a border to something I've found its overlapping.
Here is the overlap:
The .shop div seems 'as expected'
But the .basket div seems to be creeping up a bit.
Here is a link to a demo
And Html:
<div id="app">
<div class="container">
<div class="shop">
<div class="columns">
<div class="column is-one-quarter product">
<h3 class="title is-4">Cat</h3>
<p>
£<span>2.99</span></p>
<div><button class="button">Add to basket</button></div>
</div>
<div class="column is-one-quarter product">
<h3 class="title is-4">Dog</h3>
<p>
£<span>4.00</span></p>
<div><button class="button">Add to basket</button></div>
</div>
</div>
</div>
<div class="basket">
<h1>Basket</h1>
<table class="table">
<thead>
<tr>
<td>Item</td>
<td>Quantity</td>
<td>Price</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3">No items in the basket</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
CSS:
// All of bulma.css
html,body{
height:100%;
padding:20px;
}
.product{
box-sizing:border-box;
border:2px solid #eaeaea;
padding:20px;
}
I think its something to do with ... flexbox? I'm not sure!
In it's latest version try is-gapless along with columns class
The bottom container is creeping up over the top container because of this rule in the Bulma code:
.columns:last-child {
margin-bottom: -.75rem;
}
Just override it. Add this to your code:
.columns:last-child {
margin-bottom: 0 !important;
}
!important may not be necessary. I just added it to ensure that your rule prevails.

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>

center table within div

I have a table within a div using the span12 class from twitter bootstrap which is contained within a row class div all surrounded by a footer tag as follows:
<footer class="footer">
<div class="row">
<div class="span12">
<table>
<tr>
<td> <!-- Contact Us -->
<table>
<tr>
<td><b>Contact Us</b></td>
</tr>
<tr>
<td>Tel: 01234 567897</td>
</tr>
<tr>
<td>E-mail: info#email.com</td>
</tr>
</table>
</td>
<td> <!-- Useful Links -->
<table>
<tr>
<td><b>Useful Links</b></td>
</tr>
<tr>
<td>Contact Us</td>
</tr>
<tr>
<td>About Us</td>
</tr>
<tr>
<td>Copyright Information</td>
</tr>
<tr>
<td>Terms & Conditions</td>
</tr>
</table>
</td>
<td> <!-- Social -->
<table>
<tr>
<td><b>Connect With Us</b></td>
</tr>
<tr>
<td>Facebook</td>
</tr>
<tr>
<td>Twitter</td>
</tr>
<tr>
<td>Google Plus</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</footer>
I have the following CSS applied:
/* Table Style */
.footer table {
table-layout:fixed;
margin-right: auto;
margin-left: auto;
width: 100%
}
.footer td b {
vertical-align:top;
color: #ccc2a0;
}
.footer td {
vertical-align:top;
color: #a8a8a8;
}
I have tried to get the space between the left side of the footer and the first table data to be the same as the space between the right side of the footer and the last table data however it always has a bigger gap on the right side.
Can anyone see a problem with the CSS I am using?
Thanks
EDIT:
Here is the code for trying to achieve this using divs:
<footer class="footer">
<div class="row" style="background-color:red;">
<div class="span12" style="background-color:orange;">
<div class="span4" id="leftFooter">
</div>
<div class="span4" id="middleFooter">
</div>
<div class="span4" id="rightFooter">
</div>
</div>
</div>
</footer>
The CSS simply colours the boxes so I can see what is going on and adds some height to the divs.
The grey box is the footer div, the red box is the row and the orange box is the span12. The rest are the 3 content divs of span4. Not sure why they don't stay on the same row.
I changed some of it and stripped all styling out (sorry), but your spacing should be fixed horizontally. You can apply whatever else you want styling wise. Also, I got rid of all the embedded tables because it was so cumbersome...I can adjust the vertical spacing if you want, but I just threw this together to give you an idea for horizontal spacing.
http://jsfiddle.net/YYZwY/1/
HTML:
<footer class="footer">
<table>
<td>
<div id="ContactUS" class="information">Contact Us</div>
<div id="Telephone" class="information">Tel: 01234 567897 </div>
<div id="email" class="information">Email: info#email.com</div>
</td>
<td>
<div class="links">Useful Links</div>
<div class="links">Contact Us</div>
<div class="links">About Us</div>
<div class="links">Copyright Information</div>
<div class="links">Terms & Conditions</div>
</td>
<td>
<div class="connect"><b>Connect With Us</b></div>
<div class="connect">Facebook</div>
<div class="connect">Twitter</div>
<div class="connect">Google Plus</div>
</td>
</footer>
CSS:
.links {
padding-left: 10px;
padding-right: 10px;
position: relative;
}
.connect {
padding-left: 10px;
padding-right: 10px;
position: relative;
}
.information {
padding-right: 10px;
}
CSS:
.span12 {
text-align: center;
}
This solution works if we don't mind the text alignment.
Result [CodePen] : http://codepen.io/loxaxs/pen/kilLG
A different solution:
CSS:
.span12 {
padding-left: 15%;
}
Result [CodePen] : http://codepen.io/loxaxs/pen/izIHq

How to horizontally align columns in a table

I read that each column of a table can be styled using <colgroup> and <col>. I tried the following, but the style speficication is not seeming to work. How can I fix it?
When I do this with width property, it works. Is there anything wrong with text-align property?
<html><body><table>
<colgroup>
<col style="text-align:right" />
<col style="text-align:center" />
<col style="text-align:left" />
</colgroup>
<tr>
<td>aaaaaaaaaaa</td>
<td>bbbbbbbbbbb</td>
<td>ccccccccccc</td>
</tr>
<tr>
<td>aaa</td>
<td>bbb</td>
<td>ccc</td>
</tr>
</table></body></html>
The result is that each colum is left aligned by default, ignoring the specification made in colgroup.
I am using Chrome 17.
While support for colgroup and col seems to be spotty, I don't think one should throw out the baby with the bathwater. I think tables have their place, to display tabular data. Using divs to display tabular data borders on table-phobia in my opinion.
<html><body>
<style>
.left {text-align:left;}
.center {text-align:center;}
.right {text-align:right;}
</style>
<table>
<tr>
<td class="left">aaaaaaaaaaa</td>
<td class="center">bbbbbbbbbbb</td>
<td class="right">ccccccccccc</td>
</tr>
<tr>
<td class="left">aaa</td>
<td class="center">bbb</td>
<td class="right">ccc</td>
</tr>
</table>
</body></html>
If not in need of tables, here´s how I´d do it tableless, just in case:
HTML:
<div id="container">
<div class="left">left aligned text</div>
<div class="center">center aligned text</div>
<div class="right">right aligned text</div>
</div>
CSS:
.container {}
.left {
width:100px;
float:left;
text-align:left;
}
.center {
width:100px;
float:left;
text-align:center;
}
.right {
width:100px;
float:left;
text-align:right;
}
(and you could just unify all the common styles with commas and just separate the text-alignment)
Don't use tables, use divs. Obviously the following should be seperated out into classes and such, but it works.
<html><body>
<div style="display: table">
<div style="display: table-row">
<div style="display: table-cell;">aaaaaaaaaaa</div>
<div style="display: table-cell;">bbbbbbbbbbb</div>
<div style="display: table-cell;">ccccccccccc</div>
</div>
<div style="display: table-row">
<div style="display: table-cell; text-align:right;">aaa</div>
<div style="display: table-cell; text-align:center;">bbb</div>
<div style="display: table-cell; text-align:left;">ccc</div>
</div>
</div>
</body></html>