CSS Columns Table like - html

Back in the day, when tables were used to layout content setting up a column type of layout was easy.I.e <table><tr><td>column 1</td><td>Column2</td></table>
I'm trying to do the same thing using CSS (with Divs etc..), however, I'm having difficulties trying to keep the two columns with the same size. Here's an example of what I'm talking about: http://www.jsfiddle.net/ybYJ9/
What I'm trying to do is have the column on the left (marked in blue) have the same size as the column on the right. The height of the column of the right will grow depending on content size, so I can't fix the size. I've tried to set the column height to be 100% and it isn't working if you can help with this it would be great.
Thanks

The best way is to use something like this.
Use jQuery (or similar scripting language) to detect the height of your main div and transfer the value to your other div :)

Most commonly used method is "Faux Columns".
You can apply a background image/color of a shorter column to an overall container. Container will strech to higher column, so it'll look like they're having same height.
Second way is background that'll look like both columns, and you'll repeat it vertically. It'll work great if u dont know which column will be higher.

At the moment there isn't a clear and safe way of doing this in CSS.
You might:
Use faux columns – if the design permits you
Use display: table, display: table-row and display: table-cell, effectively renderings semantic markup as a table. Here's some details about this, but be wary, it doesn't work in
Use JS to set equal heights to the columns. You can do this manually (comparing the height of each column, and setting each column's height to be that of the tallest), or simpler via a jquery plugin.
If you rely on JS, be careful of dynamic height changes, as you will have to update the previously set height declarations.

There are lots of ways to do it, and none of them are 100% satisfactory to me. Rebelek's answer is a good one, but my favourite method is with a jQuery plugin.
(function ($) {
$.fn.equalColumnHeights = function () {
equalise = function (element) {
var maxHeight = 0;
$(element).children().each(function() {
if ($(this).height() > maxHeight) {
maxHeight = $(this).height();
}
});
$(element).children().height(maxHeight);
};
return this.each(function () {
equalise(this);
var element = this;
$(window).resize(function () {
$(element).children().height('');
equalise(element);
});
});
};
}(jQuery));
Then in your example:
jQuery(function ($) {
$('#mainBody').equalColumnHeights();
});
Example here: http://www.jsfiddle.net/nathan/ybYJ9/9/ I haven't changed anything except for adding the above JavaScript. That's why I like this method: completely non-intrusive.

You can't set the two different div elements the same non-fixed height without using the JS.
However, you can try to emulate the table behavior with the CSS display property.
Look over these 3 properties:
display: table;
display: table-row;
display: table-cell;
Set the display: table for your outer div (which will act like HTML <table> tag)
For your rows use display: table-row and for table cells use display: table-cell
You will have something like this:
<div style="display: table;">
<div style="display: table-row;">
<div style="display: table-cell;">
1 cell
</div>
<div style="display: table-cell;">
2 cell
</div>
</div>
</div>
But please be careful since not all browsers handle these properties correctly.
Hope it helps.

Related

CSS Property (body's width) = HTML Tag Attribute (table's width)

How can I make this code of CSS work?
body {
width: $table.width();
}
I can't find a easy/simple way of doing this.
The reason is that I have a table and the width of that table is huge, but I don't wanna manually type xxxxx px, I want it to automatically change the width of the body to the same as that table. If I don't change the width, the headers of the table get more rows/height to decrease the columns/width so that the headers I'm constantly adding, fit on the body.
I know about other CSS Preprocesors but I would really love to know a way to do this whit "CSS", nothing more, nothing less.
P.S.: I currently use http://codepen.io/pen.
EDIT: Said to be impossible, I didn't found a solution myself. No more posts needed (mostly questions) unless with the actual solution as I don't think it will be posted, but, as long as it isn't posted, anyone can post it (I will just not answer but will check).
I would personally place the table inside a div.
That way, you can style the div's width to be page width, or any specified amount of pixels/percentage of page width, and then set the width of the table to 100%. This is assuming you have your view port statement set to device width.
HTML:
<div class = 'container'>
<table class = 'tab'>
</div>
CSS:
.container{
width = 1200px
}
.tab{
width = 100%
}
I want it to automatically change the width of the body to the same as that table
Here is my solution, Pure CSS
body {
width: auto;
height: auto;
border: 2px solid red;
display: inline-block;
}
table {
width: 100px;
height: 100px;
}
<body>
<table>
</table>
</body>
You will need to use javascript to extract out the current width of the table
var width = document.getElementById('table').style.offsethwidth;
then calling the function with AJAX and then including the value in the style. However, you will need to use <table width="$width"</table>
To be able to extract out the width, you will need to use a GET to call the variable. Thus what you want to do is technically not possible, this is the only way i can see it being done.

Calculate width from auto to pixel then add by pixel in LESS CSS

I want to use auto width and add x pixels to it.
How can this be acheived Less file?
span
{
width:calc(auto + 100px);
}
I want to use auto, since I don't know the length of the text. But I know a fixed size text gets append to it at some point. I don't want the span to grow larger when this happen. Therefore, adding 100px to auto would handle it perfectly.
You should do this with JQuery.
window.onload = function(){
$('span').width($('span').width()+100px);
};
And the CSS code remains
span{
width: auto;
}
EDIT: If the span content changes after the onload function is being executed, then you should execute that line whenever the content changes.
Here you can find how to do this. Credits to #Emile
1- The jQuery change event is used only on user input fields because if anything else is manipulated (e.g., a div), that manipulation is coming from code. So, find where the manipulation occurs, and then add whatever you need to there.
2- But if that's not possible for any reason (you're using a complicated plugin or can't find any "callback" possibilities) then the jQuery approach I'd suggest is:
a. For simple DOM manipulation, use jQuery chaining and traversing, $("#content").html('something').end().find(whatever)....
b. If you'd like to do something else, employ jQuery's bind with custom event and triggerHandler
$("#content").html('something').triggerHandler('customAction');
$('#content').unbind().bind('customAction', function(event, data) {
//Custom-action
});
Here's a link to jQuery trigger handler: http://api.jquery.com/triggerHandler/
As stated by #Paulie_D, this wasn't possible.
Proposed solution to handle this with Javascript would probably work, but I prefer to avoid this solution as I don't like handling the layout with Javascript instead of HTML/CSS.
The solution I used :
Use a DIV instead of a SPAN. This allowed to add another div inside it with a fixed width of 100px. This way, the parent div size to content including this 100px child div. Thus making the +100 needed.
When extra content is added, child div is used to display the extra content instead.
<div class="ParentDiv">
TextWithVariableLength
<div class = "ChildDiv"></div>
</div>
LESS
.ParentDiv
{
width: auto;
}
.ChildDiv
{
height:100%;
width: 100px;
}

How to achieve float: top in CSS/HTML

If you can read the Headings ... one's called JWT, the other Alela Diane.. how do I get "Alela Diane" to fill up the space between them ( no puns intended )
The CSS property for these div's is set to display: inline-block.
The HTML - >
<div id="shastra_display">
<div class="shastra_post">
There are multiple div's like this containing the Alela Diane's and JWT's etc.
</div>
</div>
The CSS - >
#shastra_display
{
width: 880px;
}
#shastra_display div
{
display: inline-block;
vertical-align: text-top;
}
.shastra_post
{
width: 270px;
background-color: light-grey;
}
Is it always going to be just two
columns? – thirtydot
It's two columns because the width of
the parent box allows only two to fit.
– Zach
So, the number of columns changes depending on the browser width.
That means you can't "cheat" and do it like this (as suggested by #Stefy):
http://jsbin.com/atimu4
Other than a fixed number of columns, CSS can't do it. See this answer for a comparision of the ideas:
CSS Floating Divs At Variable Heights
You will have to use JavaScript. There's already a convienient jQuery plugin: jQuery Masonry
Some interesting demos:
http://masonry.desandro.com/demos/animating-jquery.html
http://masonry.desandro.com/demos/adding-items.html
You should probably use a 2-column template in order to display the items properly.

How can I hide an HTML table row <tr> so that it takes up no space?

How can I hide an HTML table row <tr> so that it takes up no space? I have several <tr>'s set to style="display:none;", but they still affect the size of the table and the table's border reflects the hidden rows.
Can you include some code? I add style="display:none;" to my table rows all the time and it effectively hides the entire row.
You can set <tr id="result_tr" style="display: none;"> and then show it back with JavaScript:
var result_style = document.getElementById('result_tr').style;
result_style.display = 'table-row';
I would really like to see your TABLE's styling. E.g. "border-collapse"
Just a guess, but it might affect how 'hidden' rows are being rendered.
Thought I'd add to this a potential other solution:
<tr style='visibility:collapse'><td>stuff</td></tr>
I've only tested it on Chrome but putting this on the <tr> hides the row PLUS all the cells inside the row still contribute to the widths of the columns. I will sometimes make an extra row at the bottom of a table with just some spacers that make it so certain columns can't be less than a certain width, then hide the row using this method. (I know you're supposed to be able to do this with other css but I've never gotten that to work)
Again, I'm in a purely chrome environment so I have no idea how this functions in other browsers.
If display: none; doesn't work, how about setting height: 0; instead? In conjunction with a negative margin (equal to, or greater than, the height of the top and bottom borders, if any) to further remove the element? I don't imagine that position: absolute; top: 0; left: -4000px; would work, but it might be worth a try.
For my part, using display: none works fine.
You can use style display:none with tr to hide and it will work with all browsers.
var result_style = document.getElementById('result_tr').style;
result_style.display = '';
is working perfectly for me..
Add some of the following line-height:0px;font-size:0px;height:0px;margin:0;padding:0;
I forget which one does it. I think it's line-height for IE6.
I was having the same issue, I even added style="display: none" to each cell.
In the end I used HTML comments
<!-- [HTML] -->
This happened to me and I was baffled as to why. Then I noticed that if i removed any nbsp; i had within the rows, then the rows didn't take up any space.
I was having the exact same problem; I'm making a leaderboard thing that can display different difficulty highscores by pressing buttons.
But after screwing around for the better part of 2 hours, I found out some stuffs:
You can use this code to hide with a button press (JavaScript):
document.getElementById('mytr').style='display:none;';
Show with a button press:
document.getElementById('mytr').style='display:table-row;';
Start off hidden (To later bring back with button press):
<tr id='mytr'style='display:none;'>
Hope this helped!
P.S.
You can also show & hide headers in a similar way, only to show the header instead of writing 'display:table-row;' you write 'display:table-header;'.
This can also be used to change row into headers & headers into rows.
You need to put the change the input type to hidden, all the functions of it work but it is not visible on the page
<input type="hidden" name="" id="" value="">
as long as the input type is set to that you can change the rest.
Good Luck!!
I was having same problem and I resolved the issue.
Earlier css was overflow:hidden; z-index:999999;
I change it to overflow:visible;
HTML:
<input type="checkbox" id="attraction" checked="checked" onchange="updateMap()">poi.attraction</input>
JavaScript:
function updateMap() {
map.setOptions({'styles': getStyles() });
}
function getStyles() {
var styles = [];
for (var i=0; i < types.length; i++) {
var style = {};
var type = types[i];
var enabled = document.getElementById(type).checked;
style['featureType'] = 'poi.' + type;
style['elementType'] = 'labels';
style['stylers'] = [{'visibility' : (enabled ? 'on' : 'off') }];
styles.push(style);
}
return styles;
}
position: absolute will remove it from the layout flow and should solve your problem - the element will remain in the DOM but won't affect others.
You can set
<table>
<tr style="visibility: hidden"></tr>
</table>

Frozen table header inside scrollable div

I've three divs. Header, central and footer. There is a table in central div (gridview) which is almost always longer than outer div. So I've made this div scrollable vertically. The question is: how can I make table header that it would be visible after div is scrolled down? I could have done this header with separate div or table and make it fixed but widths of columns in the table are not always the same - so I don't know how to maintain widths of columns in header then. Any clue?
I've just put together a jQuery plugin that does exactly what you want. Its very small in size and really easy to implement.
All that is required is a table that has a thead and tbody.
You can wrap that table in a DIV with a classname and the table will always resize to fit in that div. so for example if your div scales with the browser window so will the table. The header will be fixed when scrolling. The footer will be fixed (if you enable a footer). You also have the option to clone the header in the footer and have it fixed. Also if you make your browser window too small and all columns can't fit...it will also scroll horizontally (header too).
you just pass the DIV's classname to the plugin like so: $('.myDiv').fixedHeaderTable({footer: true, footerId: 'myFooterId'});
and the plugin will do the rest. FooterID is a element on the page that contains the mark-up for your footer. this is used if you want to have pagination as your footer.
If you have multiple tables on the page it will also work for each table you want to have a fixed header.
check it out here: http://fixedheadertable.mmalek.com/
Keep in mind its still 'beta' so I am adding new features and bug fixes daily.
Supported browsers: IE6, IE7, IE8, FireFox, Safari, and Chrome
Solution is really simple. You need 3 DIVs: a general container (in my case of class "outer"), a table container (in my case of class "inner") and a DIV in which you make a clone of an existing table using jQuery or javaScript (in my case of class "header").
Solution uses CSS and a few lines of jQuery code, which clones HTML of "inner" into "header" and sets its width and height. Supports fixed and variable columns width. Tested with IE8, Firefox 9, Safari and Google Chrome.
Here is a sample code:
$(document).ready(function() {
$('.header').html( $('.inner').html() );
$('.header').css('width', $('.inner table').outerWidth() );
$('.header').css('height', $('.inner table thead').outerHeight() );
});
table {
width:100%;
}
th {
border-top:1px solid #999;
text-align:left;
}
td, th {
border-bottom:1px solid #999;
background-color:#EEE;
}
.outer {
position:relative;
width:500px;
}
.inner {
height:150px;
overflow:auto;
}
.header {
position:absolute;
top:0;
left:0;
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="outer">
<div class="inner">
<table cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>2</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>3</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>4</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>5</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>6</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>7</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>8</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>9</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>10</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>11</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>12</td><td>b</td><td>c</td><td>d</td></tr>
</tbody>
</table>
</div>
<div class="header">
</div>
</div>
</body>
Here is a basic solution using javascript:
function position(table) {
table.rows[0].style.position="absolute";
table.rows[0].style.top="0px";
table.style.marginTop = table.rows[0].clientHeight/1.2;
var widths = Array();
for(var i = 0; i < table.rows[0].cells.length; i++) {
widths[i] = max(table.rows[0].cells[i].clientWidth, table.rows[1].cells[i].clientWidth);
}
for(var row = 0; row < table.rows.length; row++) {
for(var col = 0; col < widths.length; col ++) {
table.rows[row].cells[col].style.width = widths[col] + "px";
}
}
}
function max(num1, num2) { return (num1 > num2) ? num1 : num2; }
You would have to put the header outside the scrollable div. Everything within the div will scroll.
EDIT
Regarding the width if you go for a separate header, I can see a few solutions:
Assuming this is dynamic content, generate "fixed" widths based on the length of the string. Obviously specify in terms of EMs and leave some margin for error.
Use javascript.
Use fixed width columns.
I haven't actually tried the first, and it might be overcomplicating things a bit. It's something to try if you're desperate for the effect though.
I should also mention that there are probably javascript libraries with table widgets that do this already. Have a look at them to see how they do it.
You need to put a table with the headers about your table of data. You can maintain the column width with table-layout:fixed. JavaScript can be used to match the column widths.
Here's a nice solution (mostly CSS) which uses fixed width columns: http://www.imaputz.com/cssStuff/bulletVersion.html
And here's a bit of jQuery code to fix cell-widths when cell contents take more width than the fixed width:
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"
type="text/javascript"></script>
<script>
$(function() {
$('div.tableContainer').each(function() { // for each table
var div = $(this);
var widths = [];
var changed = false;
$('table>*>tr', div).each(function(tr_i) {
$(this).children().each(function(i) {
var w = $(this).width();
if (w > widths[i]) {
widths[i] = w;
changed = true;
}
});
}).each(function(tr_i) {
if (changed)
$(this).children().each(function(i) {
var width = widths[i];
// add some width for scrollbar
if (tr_i == 0 && changed && i == widths.length-1) width += 16;
// insert a div to ensure width
$(this).append('<div style="width:'+width+'px; height:0px"> </div>');
});
});
div.width(div.children('table').width()).css('overflow-x', 'hidden');
});
});
</script>
The output is a bit off in IE when using a non-strict DTD. Tweak the widths in the CSS if you can't use standards mode.
Note that the jQuery code increases the table width at the end, and disables the horizontal scrollbar. You may or may not want that.
You may try the jQuery plugin Stupid Fixed Header. The technique is basically the same: clone a header and put it on top of the table layer.
What you actually want to be doing is making the <tbody> of the data table scrollable, so the <thead> and <tfoot> will remain naturally fixed.
Whilst this is trivial for FF et al:
tbody
{
height: 100px; /* or whatever */
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
}
IE has severe and complex issues with tbody in general. It can be solved with expressions but it's non-trivial, and specific to the design.
I haven't tested this, but perhaps you could generate the table twice, once in the header and once in the scrolling div. Then in the header, make all the rows except the heading row invisible. Perhaps with 'display: none' or set their height to zero.
This solution works using CSS in Firefox and the other Gecko browsers, and CSS expressions in IE.
http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html
The header and footer do not stay fixed in Opera or Safari/Chrome, but the whole table is scrollable so it is usable. Note that the columns are given percentage widths in the author's example, but they can be removed.
If you want to experiment with Opera/Safari/Chrome support, look at giving the tbody display:block and go from there.
Take a look at YUI Data Table if you are looking for a comprehensive cross-browser implementation. I believe this is done by creating another table with matching column widths.
There appears to be tricks required to fix column widths. If I recall correctly, Firefox requires <col/> tags to be present.
In any case, there were many tricks employed in YUI DataTable (50k lines). You'd be well advised to look at it and decide how far you'd like to go on your own with this.