How to Make 4 cells in each line by only css & html - html

What I want to inquire about him, how to make 4 cells in each line automatically without the use of programming languages ​​such as php .
In other words, I want the line is not likely more than 4 cells and any new cell to be in a new line automatically, without manually to put in the code <tr>

Assuming you have a table markup like so:
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
<td>Cell 6</td>
<td>Cell 7</td>
<td>Cell 8</td>
<td>Cell 9</td>
<td>Cell 10</td>
</tr>
</table>
...You can cause each row to have 4 cells with the following css:
FIDDLE
CSS
td {
float: left;
}
td:nth-child(4n + 5) {
clear:left;
}
Edit:
If you want the each td to take up 25% of the table width, then you'll need you set a width on your table and then set width: 25% on all td elements (also reset defalt margin/paddings to 0)
Like so:
Updated FIDDLE
body, td {
margin: 0;padding:0;
}
table {
width: 100%;
}
td {
float: left;
width: 25%;
}

<table>
<tr>
<td> Cell 1 </td>
<td> Cell 2 </td>
<td> Cell 3 </td>
<td> Cell 4 </td>
</tr>
</table>
This is the HTML

Let's assume you want to create a layout for a page and you use <tr> as a synonym for line/row of blocks, not for creating layout tables made of table, tr and td (that's a bad practice) or worse here for data table (a data table with 4 cells per row also have 4 header cells th in the first row (in general) and do use tr to semantically indicate where the rows are and how much cells they each contain)
That said, you can use sibling elements in your HTML code and float them. Here's a Fiddle
Relevant code:
HTML
<div class="block">Some content 1</div>
<div class="block">Some content 2</div>
<!-- (...) -->
CSS
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
width: 400px;
}
.block {
float: left;
width: 24%;
margin: 0 1% 1% 0;
padding: 4px;
border: 1px solid #aaa;
}
/* Improvements for last "row" http://slides.com/heydon/effortless-style#/45 and next slides */
.block:nth-child(4n+1):last-child {
width: 99%;
}
.block:nth-child(4n+1):nth-last-child(2),
.block:nth-child(4n+2):last-child {
width: 49%;
}
.block:nth-child(4n+1):nth-last-child(3),
.block:nth-child(4n+2):nth-last-child(2),
.block:nth-child(4n+3):last-child {
width: 32%;
}

Related

css: display column as row in mobile view

I want to display table column as row, when someone open page in mobile (less than 480px).
This is my table structure.
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main td {
display: table-row;
}
}
<p>
In desktop View
</p>
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>
I tried to do using css like.
#media(max-width: 480px) {
.main td {
display: table-row;
}
}
But it is not working. In Mobile view I want output like this, Second column should display below first column.
Note: I can't change table to div.
This is my expected output:
You will need to break the table-layout via resets on display.
grid or flex can then allow you to reorder your elements
example
table,
th,
td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main tbody {
display: grid;
}
.main tr {
display: contents;
border:solid red
}
.main td {
display: block;
}
.main tr td + td {
order: 1;
}
}
<p>
In desktop View
</p>
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>
explanation :
the browser will generate a tbody wrapper, you can reset display from than one and keep the table display behavior on the <table>element so it keeps shrinking. Let's make that tbody a grid (defaut of display:grid is to draw a single column).
tr are in the way, display:contents will remove them virtually, so the cells (td) can be (virtually) direct child of tbody and be reorder via .. order. You can give here via tr >:nth-child(x){order:X;} an order to each cells.
ressource:
https://css-tricks.com/snippets/css/complete-guide-grid/
https://developer.mozilla.org/en-US/docs/Web/CSS/display
display contents
These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes. Please note that the CSS Display Level 3 spec defines how the contents value should affect "unusual elements" — elements that aren’t rendered purely by CSS box concepts such as replaced elements.
If you can't change the table structure then it is very difficult achieve the desired result. But if it is fixed row and column then you can use some CSS trick to bring the result.
You can reduce the browser width and see the below snippet.
#media(max-width: 480px) {
.main td{
margin-top:63px
}
.main td:last-child {
position:absolute;
left:8px;
}
}
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main td{
margin-top:63px
}
.main td:last-child {
position:absolute;
left:8px;
}
}
<p>
In desktop View
</p>
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>
JS FIDDLE DEMO
adding display block to td and tr will force them to behave like block level element, try if it works for you
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main tr, .main td {
display: block;
}
}
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>

Removing outer border in html table

I am developing a report in HTML. There I have a table. In each TD I have another table. I want to separate each table within td. So I have enabled the border of the main table. But few of the internal table need to display the cell borders. But I don't want the outer border of that particular internal table to display.
Ex.
<table ID="main" >
<tr>
<td>
<table ID="INTER1">
<tr>
<td>Table1 without internal border</td>
<tr>
</table>
</td>
<td>
<table ID="INTER2">
<tr>
<td>Table with internal border</td>
<tr>
</table>
</td>
</tr>
<table>
I want to do this using CSS class. I have googled for it but I found the solution which will apply for all the tags, but that means it will remove outer border of all the tables.
Can I have have the solution for above problem?
Here is how you can do it, you just need to add the n-bordered class to each table where you don't want the outer borders.
.border-none {
border-collapse: collapse;
border: none;
}
.border-none td {
border: 1px solid black;
}
.border-none tr:first-child td {
border-top: none;
}
.border-none tr:last-child td {
border-bottom: none;
}
.border-none tr td:first-child {
border-left: none;
}
.border-none tr td:last-child {
border-right: none;
}
<table class="border-none">
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 4</td>
<td>Cell 5</td>
<td>Cell 6</td>
</tr>
<tr>
<td>Cell 7</td>
<td>Cell 8</td>
<td>Cell 9</td>
</tr>
<tr>
<td>Cell 10</td>
<td>Cell 11</td>
<td>Cell 12</td>
</tr>
</table>
Not sure what you want, so review this and maybe we can progressively resolve this. According to Mr. Sweeney, you don't want the inner tables' borders but you still want the outer table's border. The dashed black line shows where the 2 inner table borders are. In the code are comments on how to remove them.
table#main { border: 2px dashed blue; border-collapse: collapse; }
td { border: 1px solid red; height: 80px; }
td table { border: 1px dashed black; }
/* Replace the last line with this one */
/* td table { border: none; } */
<table ID="main" >
<tr>
<td>
<table ID="INTER1">
<tr>
<td>Table1 without internal border</td>
<tr>
</table>
</td>
<td>
<table ID="INTER2">
<tr>
<td>Table with internal border</td>
<tr>
</table>
</td>
</tr>
<table>
<ul>
<li>Blue Dashed = Outer Table</li>
<li>Black Dashed = Inner Table</li>
<li>Red Solid = Cell</li>
You can just specify which tables you want to remove the border from. Like so:
td table, td table th, td table td {
border: 0;
}
The above selects every table,th and td within another td. The highest-level table will be unaffected.
To style the each tds of a table differently, use their ids. Then do something like:
#INTER1 td {
border: 0;
}
#INTER2 td {
border: 1px solid black;
}
If you have more td elements and you only want to style one of them, you can do the other approach as per above.
#INTER2 td:nth-of-type(2) {
border: 1px solid black;
}

HTML table with 100% width, with vertical scroll inside tbody

How can I set for <table> 100% width and put only inside <tbody> vertical scroll for some height?
table {
width: 100%;
display:block;
}
thead {
display: inline-block;
width: 100%;
height: 20px;
}
tbody {
height: 200px;
display: inline-block;
width: 100%;
overflow: auto;
}
<table>
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
<th>Head 4</th>
<th>Head 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content 1</td>
<td>Content 2</td>
<td>Content 3</td>
<td>Content 4</td>
<td>Content 5</td>
</tr>
</tbody>
</table>
I want to avoid adding some additional div, all I want is simple table like this and when I trying to change display, table-layout, position and much more things in CSS table not working good with 100% width only with fixed width in px.
In order to make <tbody> element scrollable, we need to change the way it's displayed on the page i.e. using display: block; to display that as a block level element.
Since we change the display property of tbody, we should change that property for thead element as well to prevent from breaking the table layout.
So we have:
thead, tbody { display: block; }
tbody {
height: 100px; /* Just for the demo */
overflow-y: auto; /* Trigger vertical scroll */
overflow-x: hidden; /* Hide the horizontal scroll */
}
Web browsers display the thead and tbody elements as row-group (table-header-group and table-row-group) by default.
Once we change that, the inside tr elements doesn't fill the entire space of their container.
In order to fix that, we have to calculate the width of tbody columns and apply the corresponding value to the thead columns via JavaScript.
Auto Width Columns
Here is the jQuery version of above logic:
// Change the selector if needed
var $table = $('table'),
$bodyCells = $table.find('tbody tr:first').children(),
colWidth;
// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
return $(this).width();
}).get();
// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
$(v).width(colWidth[i]);
});
And here is the output (on Windows 7 Chrome 32):
Working demo.
Full Width Table, Relative Width Columns
As the original poster needed, we could expand the table to 100% of width of its container, and then using a relative (Percentage) width for each columns of the table.
table {
width: 100%; /* Optional */
}
tbody td, thead th {
width: 20%; /* Optional */
}
Since the table has a (sort of) fluid layout, we should adjust the width of thead columns when the container resizes.
Hence we should set the columns' widths once the window is resized:
// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
/* Same as before */
}).resize(); // Trigger the resize handler once the script runs
The output would be:
Working demo.
Browser Support and Alternatives
I've tested the two above methods on Windows 7 via the new versions of major Web Browsers (including IE10+) and it worked.
However, it doesn't work properly on IE9 and below.
That's because in a table layout, all elements should follow the same structural properties.
By using display: block; for the <thead> and <tbody> elements, we've broken the table structure.
Redesign layout via JavaScript
One approach is to redesign the (entire) table layout. Using JavaScript to create a new layout on the fly and handle and/or adjust the widths/heights of the cells dynamically.
For instance, take a look at the following examples:
jQuery .floatThead() plugin (a floating/locked/sticky table header plugin)
jQuery Scrollable Table plugin. (source code on github)
jQuery .FixedHeaderTable() plugin (source code on github)
DataTables vertical scrolling example.
Nesting tables
This approach uses two nested tables with a containing div. The first table has only one cell which has a div, and the second table is placed inside that div element.
Check the Vertical scrolling tables at CSS Play.
This works on most of web browsers. We can also do the above logic dynamically via JavaScript.
Table with fixed header on scroll
Since the purpose of adding vertical scroll bar to the <tbody> is displaying the table header at the top of each row, we could position the thead element to stay fixed at the top of the screen instead.
Here is a Working Demo of this approach performed by Julien.
It has a promising web browser support.
And here a pure CSS implementation by Willem Van Bockstal.
The Pure CSS Solution
Here is the old answer. Of course I've added a new method and refined the CSS declarations.
Table with Fixed Width
In this case, the table should have a fixed width (including the sum of columns' widths and the width of vertical scroll-bar).
Each column should have a specific width and the last column of thead element needs a greater width which equals to the others' width + the width of vertical scroll-bar.
Therefore, the CSS would be:
table {
width: 716px; /* 140px * 5 column + 16px scrollbar width */
border-spacing: 0;
}
tbody, thead tr { display: block; }
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 140px;
}
thead th:last-child {
width: 156px; /* 140px + 16px scrollbar width */
}
Here is the output:
WORKING DEMO.
Table with 100% Width
In this approach, the table has a width of 100% and for each th and td, the value of width property should be less than 100% / number of cols.
Also, we need to reduce the width of thead as value of the width of vertical scroll-bar.
In order to do that, we need to use CSS3 calc() function, as follows:
table {
width: 100%;
border-spacing: 0;
}
thead, tbody, tr, th, td { display: block; }
thead tr {
/* fallback */
width: 97%;
/* minus scroll bar width */
width: -webkit-calc(100% - 16px);
width: -moz-calc(100% - 16px);
width: calc(100% - 16px);
}
tr:after { /* clearing float */
content: ' ';
display: block;
visibility: hidden;
clear: both;
}
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 19%; /* 19% is less than (100% / 5 cols) = 20% */
float: left;
}
Here is the Online Demo.
Note: This approach will fail if the content of each column breaks the line, i.e. the content of each cell should be short enough.
In the following, there are two simple example of pure CSS solution which I created at the time I answered this question.
Here is the jsFiddle Demo v2.
Old version: jsFiddle Demo v1
In following solution, table occupies 100% of the parent container, no absolute sizes required. It's pure CSS, flex layout is used.
Here is how it looks:
Possible disadvantages:
vertical scrollbar is always visible, regardless of whether it's required;
table layout is fixed - columns do not resize according to the content width (you still can set whatever column width you want explicitly);
there is one absolute size - the width of the scrollbar, which is about 0.9em for the browsers I was able to check.
HTML (shortened):
<div class="table-container">
<table>
<thead>
<tr>
<th>head1</th>
<th>head2</th>
<th>head3</th>
<th>head4</th>
</tr>
</thead>
<tbody>
<tr>
<td>content1</td>
<td>content2</td>
<td>content3</td>
<td>content4</td>
</tr>
<tr>
<td>content1</td>
<td>content2</td>
<td>content3</td>
<td>content4</td>
</tr>
...
</tbody>
</table>
</div>
CSS, with some decorations omitted for clarity:
.table-container {
height: 10em;
}
table {
display: flex;
flex-flow: column;
height: 100%;
width: 100%;
}
table thead {
/* head takes the height it requires,
and it's not scaled when table is resized */
flex: 0 0 auto;
width: calc(100% - 0.9em);
}
table tbody {
/* body takes all the remaining available space */
flex: 1 1 auto;
display: block;
overflow-y: scroll;
}
table tbody tr {
width: 100%;
}
table thead, table tbody tr {
display: table;
table-layout: fixed;
}
full code on jsfiddle
Same code in LESS so you can mix it in:
.table-scrollable() {
#scrollbar-width: 0.9em;
display: flex;
flex-flow: column;
thead,
tbody tr {
display: table;
table-layout: fixed;
}
thead {
flex: 0 0 auto;
width: ~"calc(100% - #{scrollbar-width})";
}
tbody {
display: block;
flex: 1 1 auto;
overflow-y: scroll;
tr {
width: 100%;
}
}
}
In modern browsers, you can simply use css:
th {
position: sticky;
top: 0;
z-index: 2;
}
CSS-only
for Chrome, Firefox, Edge (and other evergreen browsers)
Simply position: sticky; top: 0; your th elements:
/* Fix table head */
.tableFixHead { overflow: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }
/* Just common table stuff. */
table { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th { background:#eee; }
<div class="tableFixHead">
<table>
<thead>
<tr><th>TH 1</th><th>TH 2</th></tr>
</thead>
<tbody>
<tr><td>A1</td><td>A2</td></tr>
<tr><td>B1</td><td>B2</td></tr>
<tr><td>C1</td><td>C2</td></tr>
<tr><td>D1</td><td>D2</td></tr>
<tr><td>E1</td><td>E2</td></tr>
</tbody>
</table>
</div>
PS: if you need borders for TH elements th {box-shadow: 1px 1px 0 #000; border-top: 0;} will help (since the default borders are not painted correctly on scroll).
For a variant of the above that uses just a bit of JS in order to accommodate for IE11 see this answer Table fixed header and scrollable body
I'm using display:block for thead and tbody.
Because of that the width of the thead columns is different from the width of the tbody columns.
table {
margin:0 auto;
border-collapse:collapse;
}
thead {
background:#CCCCCC;
display:block
}
tbody {
height:10em;overflow-y:scroll;
display:block
}
To fix this I use small jQuery code but it can be done in JavaScript only.
var colNumber=3 //number of table columns
for (var i=0; i<colNumber; i++) {
var thWidth=$("#myTable").find("th:eq("+i+")").width();
var tdWidth=$("#myTable").find("td:eq("+i+")").width();
if (thWidth<tdWidth)
$("#myTable").find("th:eq("+i+")").width(tdWidth);
else
$("#myTable").find("td:eq("+i+")").width(thWidth);
}
Here is my working demo:
http://jsfiddle.net/gavroche/N7LEF/
Does not work in IE 8
var colNumber=3 //number of table columns
for (var i=0; i<colNumber; i++)
{
var thWidth=$("#myTable").find("th:eq("+i+")").width();
var tdWidth=$("#myTable").find("td:eq("+i+")").width();
if (thWidth<tdWidth)
$("#myTable").find("th:eq("+i+")").width(tdWidth);
else
$("#myTable").find("td:eq("+i+")").width(thWidth);
}
table {margin:0 auto; border-collapse:separate;}
thead {background:#CCCCCC;display:block}
tbody {height:10em;overflow-y:scroll;display:block}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="myTable" border="1">
<thead>
<tr>
<th>A really Very Long Header Text</th>
<th>Normal Header</th>
<th>Short</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
<tr>
<td>
Text shorter than header
</td>
<td>
Text is longer than header
</td>
<td>
Exact
</td>
</tr>
</tbody>
</table>
Create two tables one after other, put second table in a div of fixed height and set the overflow property to auto. Also keep all the td's inside thead in second table empty.
<div>
<table>
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
<th>Head 4</th>
<th>Head 5</th>
</tr>
</thead>
</table>
</div>
<div style="max-height:500px;overflow:auto;">
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Content 1</td>
<td>Content 2</td>
<td>Content 3</td>
<td>Content 4</td>
<td>Content 5</td>
</tr>
</tbody>
</table>
</div>
I got it finally right with pure CSS by following these instructions:
http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/
The first step is to set the <tbody> to display: block so an overflow and height can be applied. From there the rows in the <thead> need to be set to position: relative and display: block so that they’ll sit on top of the now scrollable <tbody>.
tbody, thead { display: block; overflow-y: auto; }
Because the <thead> is relatively positioned each table cell needs an explicit width
td:nth-child(1), th:nth-child(1) { width: 100px; }
td:nth-child(2), th:nth-child(2) { width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }
But unfortunately that is not enough. When a scrollbar is present browsers allocate space for it, therefore, the <tbody> ends up having less space available than the <thead>. Notice the slight misalignment this creates...
The only workaround I could come up with was to set a min-width on all columns except the last one.
td:nth-child(1), th:nth-child(1) { min-width: 100px; }
td:nth-child(2), th:nth-child(2) { min-width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }
Whole codepen example below:
CSS:
.fixed_headers {
width: 750px;
table-layout: fixed;
border-collapse: collapse;
}
.fixed_headers th {
text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
padding: 5px;
text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
min-width: 200px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
min-width: 200px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
width: 350px;
}
.fixed_headers thead {
background-color: #333333;
color: #fdfdfd;
}
.fixed_headers thead tr {
display: block;
position: relative;
}
.fixed_headers tbody {
display: block;
overflow: auto;
width: 100%;
height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
background-color: #dddddd;
}
.old_ie_wrapper {
height: 300px;
width: 750px;
overflow-x: hidden;
overflow-y: auto;
}
.old_ie_wrapper tbody {
height: auto;
}
Html:
<!-- IE < 10 does not like giving a tbody a height. The workaround here applies the scrolling to a wrapped <div>. -->
<!--[if lte IE 9]>
<div class="old_ie_wrapper">
<!--<![endif]-->
<table class="fixed_headers">
<thead>
<tr>
<th>Name</th>
<th>Color</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Red</td>
<td>These are red.</td>
</tr>
<tr>
<td>Pear</td>
<td>Green</td>
<td>These are green.</td>
</tr>
<tr>
<td>Grape</td>
<td>Purple / Green</td>
<td>These are purple and green.</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
<td>These are orange.</td>
</tr>
<tr>
<td>Banana</td>
<td>Yellow</td>
<td>These are yellow.</td>
</tr>
<tr>
<td>Kiwi</td>
<td>Green</td>
<td>These are green.</td>
</tr>
<tr>
<td>Plum</td>
<td>Purple</td>
<td>These are Purple</td>
</tr>
<tr>
<td>Watermelon</td>
<td>Red</td>
<td>These are red.</td>
</tr>
<tr>
<td>Tomato</td>
<td>Red</td>
<td>These are red.</td>
</tr>
<tr>
<td>Cherry</td>
<td>Red</td>
<td>These are red.</td>
</tr>
<tr>
<td>Cantelope</td>
<td>Orange</td>
<td>These are orange inside.</td>
</tr>
<tr>
<td>Honeydew</td>
<td>Green</td>
<td>These are green inside.</td>
</tr>
<tr>
<td>Papaya</td>
<td>Green</td>
<td>These are green.</td>
</tr>
<tr>
<td>Raspberry</td>
<td>Red</td>
<td>These are red.</td>
</tr>
<tr>
<td>Blueberry</td>
<td>Blue</td>
<td>These are blue.</td>
</tr>
<tr>
<td>Mango</td>
<td>Orange</td>
<td>These are orange.</td>
</tr>
<tr>
<td>Passion Fruit</td>
<td>Green</td>
<td>These are green.</td>
</tr>
</tbody>
</table>
<!--[if lte IE 9]>
</div>
<!--<![endif]-->
EDIT: Alternative solution for table width 100% (above actually is for fixed width and didn't answer the question):
HTML:
<table>
<thead>
<tr>
<th>Name</th>
<th>Color</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Red</td>
<td>These are red.</td>
</tr>
<tr>
<td>Pear</td>
<td>Green</td>
<td>These are green.</td>
</tr>
<tr>
<td>Grape</td>
<td>Purple / Green</td>
<td>These are purple and green.</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
<td>These are orange.</td>
</tr>
<tr>
<td>Banana</td>
<td>Yellow</td>
<td>These are yellow.</td>
</tr>
<tr>
<td>Kiwi</td>
<td>Green</td>
<td>These are green.</td>
</tr>
</tbody>
</table>
CSS:
table {
width: 100%;
text-align: left;
min-width: 610px;
}
tr {
height: 30px;
padding-top: 10px
}
tbody {
height: 150px;
overflow-y: auto;
overflow-x: hidden;
}
th,td,tr,thead,tbody { display: block; }
td,th { float: left; }
td:nth-child(1),
th:nth-child(1) {
width: 20%;
}
td:nth-child(2),
th:nth-child(2) {
width: 20%;
float: left;
}
td:nth-child(3),
th:nth-child(3) {
width: 59%;
float: left;
}
/* some colors */
thead {
background-color: #333333;
color: #fdfdfd;
}
table tbody tr:nth-child(even) {
background-color: #dddddd;
}
Demo: http://codepen.io/anon/pen/bNJeLO
Adding a fixed width to td,th after making tbody & thead display block works perfectly and also we can use slimscroll plugin to make the scroll bar beautiful.
<!DOCTYPE html>
<html>
<head>
<title> Scrollable table </title>
<style>
body {
font-family: sans-serif;
font-size: 0.9em;
}
table {
border-collapse: collapse;
border-bottom: 1px solid #ddd;
}
thead {
background-color: #333;
color: #fff;
}
thead,tbody {
display: block;
}
th,td {
padding: 8px 10px;
border: 1px solid #ddd;
width: 117px;
box-sizing: border-box;
}
tbody {
height: 160px;
overflow-y: scroll
}
</style>
</head>
<body>
<table class="example-table">
<thead>
<tr>
<th> Header 1 </th>
<th> Header 2 </th>
<th> Header 3 </th>
<th> Header 4 </th>
</tr>
</thead>
<tbody>
<tr>
<td> Row 1- Col 1 </td>
<td> Row 1- Col 2 </td>
<td> Row 1- Col 3 </td>
<td> Row 1- Col 4 </td>
</tr>
<tr>
<td> Row 2- Col 1 </td>
<td> Row 2- Col 2 </td>
<td> Row 2- Col 3 </td>
<td> Row 2- Col 4 </td>
</tr>
<tr>
<td> Row 3- Col 1 </td>
<td> Row 3- Col 2 </td>
<td> Row 3- Col 3 </td>
<td> Row 3- Col 4 </td>
</tr>
<tr>
<td> Row 4- Col 1 </td>
<td> Row 4- Col 2 </td>
<td> Row 4- Col 3 </td>
<td> Row 4- Col 4 </td>
</tr>
<tr>
<td> Row 5- Col 1 </td>
<td> Row 5- Col 2 </td>
<td> Row 5- Col 3 </td>
<td> Row 5- Col 4 </td>
</tr>
<tr>
<td> Row 6- Col 1 </td>
<td> Row 6- Col 2 </td>
<td> Row 6- Col 3 </td>
<td> Row 6- Col 4 </td>
</tr>
<tr>
<td> Row 7- Col 1 </td>
<td> Row 7- Col 2 </td>
<td> Row 7- Col 3 </td>
<td> Row 7- Col 4 </td>
</tr>
<tr>
<td> Row 8- Col 1 </td>
<td> Row 8- Col 2 </td>
<td> Row 8- Col 3 </td>
<td> Row 8- Col 4 </td>
</tr>
<tr>
<td> Row 9- Col 1 </td>
<td> Row 9- Col 2 </td>
<td> Row 9- Col 3 </td>
<td> Row 9- Col 4 </td>
</tr>
<tr>
<td> Row 10- Col 1 </td>
<td> Row 10- Col 2 </td>
<td> Row 10- Col 3 </td>
<td> Row 10- Col 4 </td>
</tr>
<tr>
<td> Row 11- Col 1 </td>
<td> Row 11- Col 2 </td>
<td> Row 11- Col 3 </td>
<td> Row 11- Col 4 </td>
</tr>
<tr>
<td> Row 12- Col 1 </td>
<td> Row 12- Col 2 </td>
<td> Row 12- Col 3 </td>
<td> Row 12- Col 4 </td>
</tr>
<tr>
<td> Row 13- Col 1 </td>
<td> Row 13- Col 2 </td>
<td> Row 13- Col 3 </td>
<td> Row 13- Col 4 </td>
</tr>
<tr>
<td> Row 14- Col 1 </td>
<td> Row 14- Col 2 </td>
<td> Row 14- Col 3 </td>
<td> Row 14- Col 4 </td>
</tr>
<tr>
<td> Row 15- Col 1 </td>
<td> Row 15- Col 2 </td>
<td> Row 15- Col 3 </td>
<td> Row 15- Col 4 </td>
</tr>
<tr>
<td> Row 16- Col 1 </td>
<td> Row 16- Col 2 </td>
<td> Row 16- Col 3 </td>
<td> Row 16- Col 4 </td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script>
<script>
$('.example-table tbody').slimscroll({
height: '160px',
alwaysVisible: true,
color: '#333'
})
</script>
</body>
</html>
Css workaround for forcing columns to display correctly with a 'block' tbody
This solution still requires the th widths to be calculated and set by jQuery
table.scroll tbody,
table.scroll thead { display: block; }
table.scroll tbody {
overflow-y: auto;
overflow-x: hidden;
max-height: 300px;
}
table.scroll tr {
display: flex;
}
table.scroll tr > td {
flex-grow: 1;
flex-basis: 0;
}
And the Jquery / Javascript
var $table = $('#the_table_element'),
$bodyCells = $table.find('tbody tr:first').children(),
colWidth;
$table.addClass('scroll');
// Adjust the width of thead cells when window resizes
$(window).resize(function () {
// Get the tbody columns width array
colWidth = $bodyCells.map(function () {
return $(this).width();
}).get();
// Set the width of thead columns
$table.find('thead tr').children().each(function (i, v) {
$(v).width(colWidth[i]);
});
}).resize(); // Trigger resize handler
try below approach, very simple easy to implement
Below is the jsfiddle link
http://jsfiddle.net/v2t2k8ke/2/
HTML:
<table border='1' id='tbl_cnt'>
<thead><tr></tr></thead><tbody></tbody>
CSS:
#tbl_cnt{
border-collapse: collapse; width: 100%;word-break:break-all;
}
#tbl_cnt thead, #tbl_cnt tbody{
display: block;
}
#tbl_cnt thead tr{
background-color: #8C8787; text-align: center;width:100%;display:block;
}
#tbl_cnt tbody {
height: 100px;overflow-y: auto;overflow-x: hidden;
}
Jquery:
var data = [
{
"status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
}, {
"status":"stop","vehno":"tr54","loc":"che", "dri":"ttt"
},{ "status":"idle","vehno":"yy5499999999999994","loc":"bng","dri":"ttt"
},{
"status":"moving","vehno":"tr544","loc":"bng", "dri":"ttt"
}, {
"status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
},{
"status":"idle","vehno":"yy544","loc":"bng","dri":"ttt"
}
];
var sth = '';
$.each(data[0], function (key, value) {
sth += '<td>' + key + '</td>';
});
var stb = '';
$.each(data, function (key, value) {
stb += '<tr>';
$.each(value, function (key, value) {
stb += '<td>' + value + '</td>';
});
stb += '</tr>';
});
$('#tbl_cnt thead tr').append(sth);
$('#tbl_cnt tbody').append(stb);
setTimeout(function () {
var col_cnt=0
$.each(data[0], function (key, value) {col_cnt++;});
$('#tbl_cnt thead tr').css('width', ($("#tbl_cnt tbody") [0].scrollWidth)+ 'px');
$('#tbl_cnt thead tr td,#tbl_cnt tbody tr td').css('width', ($('#tbl_cnt thead tr ').width()/Number(col_cnt)) + 'px');}, 100)
Try this jsfiddle. This is using jQuery and made from Hashem Qolami's answer. At first, make a regular table then make it scrollable.
const makeScrollableTable = function (tableSelector, tbodyHeight) {
let $table = $(tableSelector);
let $bodyCells = $table.find('tbody tr:first').children();
let $headCells = $table.find('thead tr:first').children();
let headColWidth = 0;
let bodyColWidth = 0;
headColWidth = $headCells.map(function () {
return $(this).outerWidth();
}).get();
bodyColWidth = $bodyCells.map(function () {
return $(this).outerWidth();
}).get();
$table.find('thead tr').children().each(function (i, v) {
$(v).css("width", headColWidth[i]+"px");
$(v).css("min-width", headColWidth[i]+"px");
$(v).css("max-width", headColWidth[i]+"px");
});
$table.find('tbody tr').children().each(function (i, v) {
$(v).css("width", bodyColWidth[i]+"px");
$(v).css("min-width", bodyColWidth[i]+"px");
$(v).css("max-width", bodyColWidth[i]+"px");
});
$table.find('thead').css("display", "block");
$table.find('tbody').css("display", "block");
$table.find('tbody').css("height", tbodyHeight+"px");
$table.find('tbody').css("overflow-y", "auto");
$table.find('tbody').css("overflow-x", "hidden");
};
Then you can use this function as follows:
makeScrollableTable('#test-table', 250);
This is the code that works for me to create a sticky thead on a table with a scrollable tbody:
table ,tr td{
border:1px solid red
}
tbody {
display:block;
height:50px;
overflow:auto;
}
thead, tbody tr {
display:table;
width:100%;
table-layout:fixed;/* even columns width , fix width of table too*/
}
thead {
width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
width:400px;
}
For using "overflow: scroll" you must set "display:block" on thead and tbody. And that messes up column widths between them. But then you can clone the thead row with Javascript and paste it in the tbody as a hidden row to keep the exact col widths.
$('.myTable thead > tr')
.clone()
.appendTo('.myTable tbody')
.addClass('hidden-to-set-col-widths')
;
http://jsfiddle.net/Julesezaar/mup0c5hk/
<table class="myTable">
<thead>
<tr>
<td>Problem</td>
<td>Solution</td>
<td>blah</td>
<td>derp</td>
</tr>
</thead>
<tbody></tbody>
</table>
<p>
Some text to here
</p>
The css:
table {
background-color: #aaa;
width: 100%;
}
thead,
tbody {
display: block; // Necessary to use overflow: scroll
}
tbody {
background-color: #ddd;
height: 150px;
overflow-y: scroll;
}
tbody tr.hidden-to-set-col-widths,
tbody tr.hidden-to-set-col-widths td {
visibility: hidden;
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
}
td {
padding: 3px 10px;
}

Non Uniform Dashed Border in Table Cells

I have applied CSS border-bottom:1px dashed #494949; on several consecutive cells of a single row of an HTML table, but the border is not uniform. The dashes at the end of each cell appear little longer. Dotted border is also not uniform. I am also using border-collapse:collapse;
Here is the screenshot:
Is there any way I can get uniform dashed border?
The way I fixed this problem on my app was by adding an extra row with the same colspan as the row with the dashed border. The border will be uniform to the length of the span:
<table>
<!--row with dashed border-->
<tr>
<td style = "border-bottom: 1px dashed green;" colspan="3"></td>
</tr>
<!--added row so dotted border looks uniform-->
<tr>
<td style="height: 5px;" colspan="3"></td>
</tr>
<!--existing rows with lots of columns-->
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
Browsers have oddities in rendering dashed borders. You can fight against them by removing cell spacing and cell padding and setting the border on a tr element and not on cells, e.g.
table { border-collapse: collapse; }
td { padding: 0; }
tr { border-bottom:1px dashed #494949; }
But this still seems to fail on IE 9 (at cell junctions), and old browsers ignore borders set on table rows.
Consider using a solid gray border instead. It works consistently and might be visually acceptable, maybe even better.
Hard to say for sure what's going on without a screenshot or demo, but it sounds like they appear to be longer at the transition to the next cell because the last dash is touching the first dash in the next cell.
In that case, try to put the border on the entire row instead of the individual cells.
I'm not sure but it looks like rendering issue. Even using a background-image instead of border-bottom will have same kind of issue.
Your best bet in this case would be to create a repeating image file, the height of which is the height of the table row. Set it as the table background, and make sure it repeats. I've tested it, and it works. Note that in the PNG file created for this example, the dashes are each 3px long, and there are three blank trailing pixels on the right, for final dimensions of 30px (width) x 29px (height).
Here's the code:
.borderTable {
background: url(http://www.windycitywebsites.com/wp-content/uploads/2012/03/dash_png.png);
background-repeat: repeat;
}
.borderTable td {
height: 29px;
}
<table class="borderTable" width="350" border="0" cellspacing="0" cellpadding="0">
<tr class="stuff">
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr class="stuff">
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
DIZAD's answer has almost worked for me, but adding borders to the td still resulted in weird dashed borders. Adding the border to a div inside the td fixed it for me.
const RowBorder = styled('div')`
border-top: 1px dashed black;
width: 100%;
`;
return (
<table>
<thead>
<tr>
<td colSpan="6">
<RowBorder />
</td>
</tr>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
<td>Col4</td>
<td colSpan="2">Col5</td>
</tr>
<tr>
<td colSpan="6">
<RowBorder />
</td>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
)
Nine years on, and this is still giving people a headache!
This method works from IE11+ and all other major browsers without having to create an empty row just for a border:
table {
width: 100%;
border-collapse: collapse;
position: relative; /* Required #1 */
}
td {
height: 60px;
text-align: center;
background: #EEE;
border: 1px solid #CCC;
}
tr:nth-child(even) td {
background: #DDD;
}
td:nth-child(1) {
padding: 0; /* Required #2 */
width: 30%;
}
/* Required #3 */
td:nth-child(1)::after {
display: block;
content: ' ';
width: 100%;
margin-bottom: -1px;
position: absolute;
border-bottom: 2px dashed;
}
td:nth-child(2) {
width: 50%;
}
td:nth-child(3) {
width: 20%;
}
/* Required #4 */
span {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
<table>
<tr>
<td><span>Row 1, Cell 1</span></td>
<td>Row 1, Cell 2</td>
<td>Row 1, Cell 3</td>
</tr>
<tr>
<td><span>Row 2, Cell 1</span></td>
<td>Row 2, Cell 2</td>
<td>Row 2, Cell 3</td>
</tr>
<tr>
<td><span>Row 3, Cell 1</span></td>
<td>Row 3, Cell 2</td>
<td>Row 3, Cell 3</td>
</tr>
</table>
This works because the border is attached to a psuedo element with a position of absolute that takes its width from the table, rather than being bind purely to the cell.
There are four main areas to be aware of (commented in the CSS):
The table has position: relative so the line adapts to that width; unfortunately you can't apply it on a table row.
The first cell of each row should not have any padding, otherwise the line may not be flush with the bottom of the row; if you require padding, then this can be defined in #4.
This creates the line itself; it's basically a pseudo element of position: absolute, with a width: 100% to stretch across the table. I have also added a negative margin half the size of the border so it sits nicely in between the two rows. You may also notice that there are no top/left/right/bottom properties; this is so that the element remains where it was before the absolute positioning.
This is the element inside the first cell of each row; the main thing is to add height: 100% so it forces the line created at #3 to be at the bottom of the row. After that is considered, you can style it however you like.
The standard border inside the td is not required; I've included that to demonstrate where the cells are.

CSS solution to positioning Span element on a Table element

I am trying to position a span element relative to the upper-right corner of a table object.
This table may be wider or move around based on what the user does on the tool, so I was looking for something simpler than the jQuery.position method. I was hoping to do something elegant with CSS.
I've built a small example of my dilemma in jsfiddle: http://jsfiddle.net/xerf/ZSGfc/
<div>
<table>
<thead>
<tr>
<th colspan="3">Title</th>
</tr>
</thead>
<tbody>
<tr>
<td>Stuff 1</td>
<td>Stuff 2</td>
<td>Stuff 3</td>
</tr>
<tr>
<td>Stuff 1</td>
<td>Stuff 2</td>
<td>Stuff 3</td>
</tr>
<tr>
<td>Stuff 1</td>
<td>Stuff 2</td>
<td>Stuff 3</td>
</tr>
</tbody>
</table>
<span>×</span>
</div>
Below are the CSS Styles
body
{
font-family:sans-serif;
}
table
{
border-collapse: collapse;
border: 1px solid black;
margin: 20px;
}
th
{
padding: 6px;
}
td
{
padding: 3px;
border: 1px solid black;
}
UPDATE: Added some images to show required positions:
Needs to be where the red Square appears above
I wrapped your span in a div and placed it in the <th> with your title:
<th colspan="3"><div id="container">Title
<span>×</span></div></th>
css:
#container{
width:auto;
height:auto;
position:relative;
}
span{
position:absolute;
right:0px;
top:0px;
Here is a demo: http://jsfiddle.net/ZSGfc/6/
A very simple way would be to simply add another row to the very top of the table, removing its left, top and right borders. Then move your span so that it is contained by this new row and align the text to the right.
I would recommend using the div or adding another div that will control the width of the table, and then have the table inherit the width of that div. From there make the div's position property set to relative. Then you can absolutely position the span on the div.
Something similar to this fiddle. With some tweaking.
Try this:
div{
position:relative;
width: XXXpx;
}
table{
width: XXXpx;
}
span{
position: absolute;
top: 0px;
right: 0px;
}
an additional table cell on top with colspan="3" and text-align:right would work.