Why parent rows do not extend across the entire width - css

I'm trying to create a simple table in Vue.js and with Bootstrap. After clicking the arrow, the child row is displayed, I would like the child row to be displayed below the parent row. Which i solved by setting
display:flexbox; flex-direction:column;
HTML table:
`
<thead>
<tr>
<th scope="col"></th>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Gender</th>
<th scope="col">Ability</th>
<th scope="col">Minimal distance</th>
<th scope="col">Weight</th>
<th scope="col">Born</th>
<th scope="col">In space since</th>
<th scope="col">Beer consumption (l/y)</th>
<th scope="col">Knows the answer?</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr class="parent" v-for="item in data" :key="item.data.ID">
<td>
<button class="bg-transparent" #click="toggleChildren(item)"><i class="bi bi-caret-right-fill"></i></button>
</td>
<td>{{ item.data.ID }}</td>
<td>{{ item.data.Name }}</td>
<td>{{ item.data.Gender }}</td>
<td>{{ item.data.Ability }}</td>
<td>{{ item.data['Minimal distance'] }}</td>
<td>{{ item.data.Weight }}</td>
<td>{{ item.data.Born }}</td>
<td>{{ item.data['In space since'] }}</td>
<td>{{ item.data['Beer consumption (l/y)'] }}</td>
<td>{{ item.data['Knows the answer?'] }}</td>
<td>
<button class="btn btn-danger" #click="removeItem(item,null)">Remove</button>
</td>
<template v-if="item.children && item.children.has_nemesis && Array.isArray(item.children.has_nemesis.records) && item.children.has_nemesis.records.length && item.childrenVisible">
<tr v-for="child in item.children.has_nemesis.records" :key="child.data.ID">
<td scope="row">{{ child.data.ID }}</td>
<td class="">{{ child.data['Character ID'] }}</td>
<td>{{ child.data['Is alive?'] }}</td>
<td>{{ child.data.Years }}</td>
<td>
<button #click="toggleChildren(child)" ><i class="bi bi-caret-right-fill"></i></button>
</td>
<td>
<button #click="removeItem(child, item)">Remove</button>
</td>
<template v-if="child.childrenVisible">
<tr v-for="secret in child.children.has_secrete.records" :key="secret.data.ID">
<td >{{ secret.data.ID }}</td>
<td >{{ secret.data['Nemesis ID'] }}</td>
<td >{{ secret.data['Secrete Code'] }}</td>
</tr>
</template>
</tr>
</template>
</tr>
</tbody>
</table>
</div>`
However, this caused the parent rows to not extend the full length of the row(see image)
CSS:
table {
border: 5px solid red !important;
display: flex;
flex-direction: column;
}
thead{
border: 5px solid blue;
}
tbody{
border: 5px solid green;
grid-template-columns: repeat(12, 1fr);
grid-gap: 8px;
}
.parent{
border: 1px solid brown;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 8px;
}
td{
border: 5px solid black;
}

You don't want to use flex in the table. You can use table-layout: fixed;. Since the table is relatively complex you could use id on the headers and headers for the rows. Like so:
<table>
<thead>
<tr>
<th id="col"></th>
<th id="id">ID</th>
<th id="name">Name</th>
<th id="gender">Gender</th>
<th id="ability">Ability</th>
<th id="min-distance">Minimal distance</th>
<th id="weight">Weight</th>
<th id="born">Born</th>
<th id="in-space-since">In space since</th>
<th id="beer-consumption">Beer consumption (l/y)</th>
<th id="answer">Knows the answer?</th>
<th id="action">Actions</th>
</tr>
</thead>
<tbody>
<tr class="parent" v-for="item in data" :key="item.data.ID">
<td headers="col">
<button class="bg-transparent" #click="toggleChildren(item)"><i class="bi bi-caret-right-fill"></i></button>
</td>
<td headers="id">{{ item.data.ID }}</td>
<td headers="name">{{ item.data.Name }}</td>
<td headers="gender">{{ item.data.Gender }}</td>
<td headers="ability">{{ item.data.Ability }}</td>
<td headers="min-distance">{{ item.data['Minimal distance'] }}</td>
<td headers="weight">{{ item.data.Weight }}</td>
<td headers="born">{{ item.data.Born }}</td>
<td headers="in-space-since">{{ item.data['In space since'] }}</td>
<td headers="beer-consumption">{{ item.data['Beer consumption (l/y)'] }}</td>
<td headers="answer">{{ item.data['Knows the answer?'] }}</td>
<td headers="action">
<button class="btn btn-danger" #click="removeItem(item,null)">Remove</button>
</td>
</tr>
</tbody>
</table>
Then use thead th:nth-child(n) to set the widths for the column. Here's a start for you.
table {
table-layout: fixed;
width: 100%;
border: 1px solid;
border-collapse: collapse;
}
thead th:nth-child(1) {
width: 8%;
}
thead th:nth-child(2) {
width: 8%;
}
thead th:nth-child(3) {
width: 12%;
}
thead th:nth-child(4) {
width: 8%;
}
thead th:nth-child(5) {
width: 8%;
}
thead th:nth-child(6) {
width: 8%;
}
thead th:nth-child(7) {
width: 8%;
}
thead th:nth-child(8) {
width: 8%;
}
thead th:nth-child(9) {
width: 8%;
}
thead th:nth-child(10) {
width: 8%;
}
thead th:nth-child(11) {
width: 8%;
}
thead th:nth-child(12) {
width: 8%;
}
th, td {
padding: 0.5rem;
border: 1px solid;
}

Related

Table background color and responsive to mobile on Next.js using Tailwindcss

<table className="table-auto bg-orange-500">
<thead>
<tr>
<th>Song</th>
<th>Artist</th>
<th>Year</th>
</tr>
</thead>
<tbody>
<tr className="bg-orange-500">
<td>
The Sliding Mr.
Boaosjdofijasodifjoasidjfoiasdjfoisajdfoijasdoifjsaoidfjoasidjfaoisjdfoisjdofijnes
(Next Stop, Pottersville)
</td>
<td>Malcolm Lockyer</td>
<td>1961</td>
</tr>
<tr>
<td>Witchy Woman</td>
<td>The Eagles</td>
<td>1972</td>
</tr>
<tr>
<td>Shining Star</td>
<td>Earth, Wind, and Fire</td>
<td>1975</td>
</tr>
</tbody>
</table>
I have this table example from Tailwind. I want to change the background color for the even number of the item.
#layer utilities {
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
.tr:nth-child(even) {
background-color: #ccc;
}
.tr:nth-child(od) {
background-color: #fff;
}
}
I tried something like this and also wanted to change the background color of the thead.
I did <thead className="bg-orange-500"> and nothing happens to its background. I couldn't find any information about the background color of the table on the doc.
There are two mistakes
You are using class selector . for a element type .
Change:
.tr:nth-child(even) {
background-color: #ccc;
}
to:
tr:nth-child(even) {
background-color: #ccc;
}
Spelling of odd has become od in your code.
For thead bg-color try the following code:
<table class="table-auto">
<thead class="bg-cyan-300">
<tr>
<th class="px-4 py-2">Item</th>
<th class="px-4 py-2">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td class="px-4 py-2">Item 1</td>
<td class="px-4 py-2">Value 1</td>
</tr>
<tr>
<td class="px-4 py-2">Item 2</td>
<td class="px-4 py-2">Value 2</td>
</tr>
<tr>
<td class="px-4 py-2">Item 3</td>
<td class="px-4 py-2">Value 3</td>
</tr>
<tr>
<td class="px-4 py-2">Item 4</td>
<td class="px-4 py-2">Value 4</td>
</tr>
</tbody>
</table>
<style>
tbody tr:nth-child(even) {
background-color: #ccc;
}
tbody tr:nth-child(odd) {
background-color: #ffec20;
}
</style>
Output:

Table header height different from chrome to firefox in grid layout

example pen:
https://codepen.io/backit/pen/zJmxqm
here's the html:
<div class="view-content">
<main class="building-phonebook">
<header>This is header</header>
<table class="building-phonebook-table building-phonebook-table-employees">
<tr>
<th colspan="3">Employees</th>
</tr>
<tr>
<td><strong>Name and Surname</strong></td>
<td><strong>Telephone</strong></td>
<td><strong>Office/Info</strong></td>
</tr>
<tr>
<td colspan="3"><strong>Administration<strong></td>
</tr>
<tr>
<td colspan="3"><strong>Technicians<strong></td>
</tr>
<tr>
<td>name surname1</td>
<td>1234</td>
<td>roomA</td>
</tr>
<tr>
<td>name surname 2</td>
<td>4321</td>
<td>roomB - roomC</td>
</tr>
<tr>
<td colspan="3"><strong>Others Employeees<strong></td>
</tr>
<tr>
<td>name surname 3</td>
<td>5463 - 5478</td>
<td>133</td>
</tr>
<tr>
<td>name surname 4</td>
<td>5468 - 4569 - 213546879</td>
<td>215</td>
</tr>
</table>
<table class="building-phonebook-table building-phonebook-table-labs" >
<tr><th colspan="2">Labs</th></tr>
<tr>
<td><strong>Name</strong></td>
<td><strong>Telephone</strong></td>
</tr>
<tr>
<td colspan="3"><strong>Labs type 1<strong></td>
</tr>
<tr>
<td>lab 1</td>
<td>4712</td>
</tr>
<tr>
<td>lab 2</td>
<td>4568</td>
</tr>
<tr>
<td colspan="3"><strong>Other Laboratories<strong></td>
</tr>
<tr>
<td>labs banana</td>
<td>7841</td>
</tr>
<tr><td colspan="3"><strong>Services<strong></td></tr>
</table>
</main>
css:
.view-content{
width: 400px;
}
/**
* Building Phonebook
*/
.building-phonebook-table tr td:nth-child(2),
.building-phonebook-table tr td:nth-child(3){
max-width:100px;
}
.building-phonebook-table th{
background:purple;
height:20px;
line-height:20px;
overflow: hidden;
color:#fff;
}
.building-phonebook-table th, .building-phonebook-table td{
height:20px;
line-height:20px;
}
.building-phonebook-table{
margin: 0px;
padding: 0px;
border-collapse: collapse;
border-spacing: 0;
}
.building-phonebook header{
background: yellow;
}
/**
* Building-phonebook grid
*/
main.building-phonebook{
display: grid;
grid-template-areas:
"header header"
"main side"
"other other";
grid-template-columns: auto auto;
grid-template-rows: auto auto;
grid-row-gap:2px;
grid-column-gap:2px;
}
.building-phonebook header{
grid-area: header;
}
.building-phonebook .building-phonebook-table-employees{
grid-area: main;
}
.building-phonebook .building-phonebook-table-labs{
grid-area: side;
}
if you browse by chrome it's ok, in firefox "Labs" header cell is higher than "employees".
As you see these are two tables side by side with grid layout.
I tried to set height, line-height, overflow, nothing works.
Ok maybe it's a firefox bug, i don't care, how may i solve this??
Many thanks.
Add align-self: start; to .building-phonebook-table-labs so it won't stretch to full cell-height:
.view-content {
width: 400px;
}
/**
* Building Phonebook
*/
.building-phonebook-table tr td:nth-child(2),
.building-phonebook-table tr td:nth-child(3) {
max-width: 100px;
}
.building-phonebook-table th {
background: purple;
height: 20px;
line-height: 20px;
overflow: hidden;
color: #fff;
}
.building-phonebook-table th,
.building-phonebook-table td {
height: 20px;
line-height: 20px;
}
.building-phonebook-table {
margin: 0px;
padding: 0px;
border-collapse: collapse;
border-spacing: 0;
}
.building-phonebook header {
background: yellow;
}
/**
* Building-phonebook grid
*/
main.building-phonebook {
display: grid;
grid-template-areas: "header header" "main side" "other other";
grid-template-columns: auto auto;
grid-template-rows: auto auto;
grid-row-gap: 2px;
grid-column-gap: 2px;
}
.building-phonebook header {
grid-area: header;
}
.building-phonebook .building-phonebook-table-employees {
grid-area: main;
}
.building-phonebook .building-phonebook-table-labs {
grid-area: side;
align-self: start;
}
<div class="view-content">
<main class="building-phonebook">
<header>This is header</header>
<table class="building-phonebook-table building-phonebook-table-employees">
<tr>
<th colspan="3">Employees</th>
</tr>
<tr>
<td><strong>Name and Surname</strong></td>
<td><strong>Telephone</strong></td>
<td><strong>Office/Info</strong></td>
</tr>
<tr>
<td colspan="3"><strong>Administration<strong></td>
</tr>
<tr>
<td colspan="3"><strong>Technicians<strong></td>
</tr>
<tr>
<td>name surname1</td>
<td>1234</td>
<td>roomA</td>
</tr>
<tr>
<td>name surname 2</td>
<td>4321</td>
<td>roomB - roomC</td>
</tr>
<tr>
<td colspan="3"><strong>Others Employeees<strong></td>
</tr>
<tr>
<td>name surname 3</td>
<td>5463 - 5478</td>
<td>133</td>
</tr>
<tr>
<td>name surname 4</td>
<td>5468 - 4569 - 213546879</td>
<td>215</td>
</tr>
</table>
<table class="building-phonebook-table building-phonebook-table-labs" >
<tr><th colspan="2">Labs</th></tr>
<tr>
<td><strong>Name</strong></td>
<td><strong>Telephone</strong></td>
</tr>
<tr>
<td colspan="3"><strong>Labs type 1<strong></td>
</tr>
<tr>
<td>lab 1</td>
<td>4712</td>
</tr>
<tr>
<td>lab 2</td>
<td>4568</td>
</tr>
<tr>
<td colspan="3"><strong>Other Laboratories<strong></td>
</tr>
<tr>
<td>labs banana</td>
<td>7841</td>
</tr>
<tr><td colspan="3"><strong>Services<strong></td></tr>
</table>
</main>
</div>

CSS Table Styling: Separate Borders and Borders for Row Groups

I've been struggling with styling this table. The header titles need to have separate underlines, and I need a separating line between the two groups of "Name" rows. (These will be different in the final render.)
This is what it looks like presently:
This is what I'm looking for:
I have a Codepen if you want to see it in action: Table Styling Codepen
I've been experimenting with border-collapse. I was able to get separate borders under some conditions, and the section separator under others. But there were always issues, such as no spacing between cells, so the styling looked very cramped.
Here's the HTML:
<table class="data-table">
<thead>
<tr>
<th></th>
<th colSpan="2" class="title">Source</th>
<th colSpan="2" class="title">Destination</th>
</tr>
<tr>
<th></th>
<th colSpan="1" class="fieldname title">Field</th>
<th colSpan="1" class="title">Value</th>
<th colSpan="1" class="fieldname title">Field</th>
<th colSpan="1" class="title">Value</th>
</tr>
</thead>
<tbody class="bodySection">
<tr>
<td rowSpan="2" class="side-title">Name</td>
<td class="fieldname src-data">Short Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Short Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
<tr>
<td class="fieldname src-data">Long Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Long Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
</tbody>
<tbody class="bodySection">
<tr>
<td rowSpan="2" class="side-title">Name</td>
<td class="fieldname src-data">Short Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Short Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
<tr>
<td class="fieldname src-data">Long Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Long Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
</tbody>
And here's the CSS:
body {
padding: 10px;
}
.data-table {
width: 100%;
border-spacing: 0 4px;
border-collapse: separate;
thead tr th {
border-collapse: separate;
border-spacing: 0 5px;
}
.title {
border-bottom: 1px solid #bbb;
text-align: left;
border-spacing: 0 5px;
}
.side-title {
transform: rotate(-90deg);
width: 25px;
}
.fieldname {
width: 130px;
}
.fieldvalue.dest-data input[type=text] {
width: 100%;
}
.bodySection {
border-bottom: 10px solid #bbb;
margin-bottom: 10px;
}
tr {
// border-bottom: 10px solid #bbb;
}
}
Thanks for your help.
Replace your header with (I've added a div inside each th):
<thead>
<tr>
<th></th>
<th colSpan="2" class="title"><div>Source</div></th>
<th colSpan="2" class="title"><div>Destination</div></th>
</tr>
<tr>
<th></th>
<th colSpan="1" class="fieldname title"><div>Field</div></th>
<th colSpan="1" class="title"><div>Value</div></th>
<th colSpan="1" class="fieldname title"><div>Field</div></th>
<th colSpan="1" class="title"><div>Value</div></th>
</tr>
</thead>
Than replace your .title with:
.title {
text-align: left;
padding-right: 5px;
}
tr .title:last-child {
padding-right: 0px;
}
.title div {
width: 100%;
border-bottom: 1px solid #bbb;
}
And your .bodySection with:
.bodySection tr:last-child td {
border-bottom: 1px solid #bbb;
padding-bottom: 15px;
}
.bodySection tr:first-child td {
padding-top: 10px;
}
That's the snippet:
body {
padding: 10px;
}
.data-table {
width: 100%;
border-spacing: 0 4px;
border-collapse: separate;
}
.title {
text-align: left;
padding-right: 5px;
}
tr .title:last-child {
padding-right: 0px;
}
.title div {
width: 100%;
border-bottom: 1px solid #bbb;
}
.side-title {
transform: rotate(-90deg);
width: 25px;
}
.fieldname {
width: 130px;
}
.fieldvalue.dest-data {
padding-right: 5px;
}
.fieldvalue.dest-data input[type=text] {
width: 100%;
}
.bodySection tr:last-child td {
border-bottom: 1px solid #bbb;
padding-bottom: 15px;
}
.bodySection tr:first-child td {
padding-top: 10px;
}
tr {
// border-bottom: 10px solid #bbb;
}
<table class="data-table">
<thead>
<tr>
<th></th>
<th colSpan="2" class="title"><div>Source</div></th>
<th colSpan="2" class="title"><div>Destination</div></th>
</tr>
<tr>
<th></th>
<th colSpan="1" class="fieldname title"><div>Field</div></th>
<th colSpan="1" class="title"><div>Value</div></th>
<th colSpan="1" class="fieldname title"><div>Field</div></th>
<th colSpan="1" class="title"><div>Value</div></th>
</tr>
</thead>
<tbody class="bodySection">
<tr>
<td rowSpan="2" class="side-title">Name</td>
<td class="fieldname src-data">Short Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Short Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
<tr>
<td class="fieldname src-data">Long Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Long Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
</tbody>
<tbody class="bodySection">
<tr>
<td rowSpan="2" class="side-title">Name</td>
<td class="fieldname src-data">Short Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Short Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
<tr>
<td class="fieldname src-data">Long Name</td>
<td class="fieldvalue src-data"My Store/td>
<td class="fieldname dest-data">Long Name</td>
<td class="fieldvalue dest-data"><input type="text" value="My Store" /></td>
</tr>
</tbody>
</table>

How to create Chrome DevTool style bar charts with grids using plain CSS/HTML?

I have a table with numerical data and I want to show a bar for every row. The challenge is to have grid lines like those found in Chrome dev tools:
You see those lines that say 400ms, 600ms, etc? That's what I'm after. One solution is to have multiple columns in the table but then how can the bar expand across multiple columns? Another solution is to use some sort of repeating background image that has those lines, but then it's tricky to adjust it for various designs (for example if the padding changes or if I want to change the grid color I have to redo the image, etc.)
I have come up with the code below but got stuck with the grid part. I want grid lines on 25%, 50%, 75% and 100%. Grids should be lines that go all over the bars all the way down to the bottom of the table.
table {
background-color: gray;
}
td {
width: 200px;
background-color: lightgray;
}
.bar {
background-color: red;
height: 1em;
}
<table>
<tr>
<th>value</th>
<th>25%| 50%| 75%| 100%|</th>
</tr>
<tr>
<th>100</th>
<td><div class="bar" style="width: 100%">.</div></td>
</tr>
<tr>
<th>80</th>
<td><div class="bar" style="width: 80%">.</div></td>
</tr>
<tr>
<th>95</th>
<td><div class="bar" style="width: 95%">.</div></td>
</tr>
<tr>
<th>18</th>
<td><div class="bar" style="width: 18%">.</div></td>
</tr>
<tr>
<th>5</th>
<td><div class="bar" style="width: 5%">.</div></td>
</tr>
</table>
And this is the result I want:
table {
width: 30%;
}
th, td {
border-right: 1px solid #000;
border-bottom: 1px solid #000;
width: 20%;
text-align: center;
font-weight: bold;
padding: 0px;
}
th{
background: #606060;
border: none;
border-right: 1px solid black;
}
td {
vertical-align: top;
z-index: -1;
}
.bar-row td {
position: relative;
height: 0px;
font-size: 0px;
border-width: 0px;
}
.bar {
background: #f00;
height: 15px;
position: absolute;
top: -17px;
}
<table cellspacing="0">
<tr>
<th>value</th>
<th>25%</th>
<th>50%</th>
<th>75%</th>
<th>100%</th>
</tr>
<tr>
<th rowspan="2">100</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 100%" class="bar"><div></td>
</tr>
<tr class="grey-bg">
<th rowspan="2">80</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 80%" class="bar"><div></td>
</tr>
<tr>
<th rowspan="2">95</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 95%" class="bar"><div></td>
</tr>
<tr class="grey-bg">
<th rowspan="2">18</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 18%" class="bar"><div></td>
</tr>
<tr>
<th rowspan="2">5</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 5%" class="bar"><div></td>
</tr>
</table>
The complete solution you may here.
The main idea is to add 2 separate tr for each line: one for background, ticks, etc and another one - for the bar iteself. The 2nd row contains only 2 cells: for heading and for the bar. So the 2ns cell has width of 100%. Changing width of the div inside will draw the correct bar. Also div has to be shifted to the upper row:
.bar {
height: 15px;
position: absolute;
top: -17px;
}
but to make it works - the row has to become relative:
.bar-row td {
position: relative;
height: 0px;
font-size: 0px;
border-width: 0px;
}
table {
width: 100%;
}
th, td {
border-right: 1px solid #000;
border-bottom: 1px solid #000;
width: 20%;
text-align: right;
padding: 0px;
}
td {
vertical-align: top;
}
.grey-bg {
background: #ccc;
}
.bar-row td {
position: relative;
height: 0px;
font-size: 0px;
border-width: 0px;
}
.bar {
background: #f00;
height: 15px;
position: absolute;
top: -17px;
}
<table cellspacing="0">
<tr>
<th>value</th>
<th>25%</th>
<th>50%</th>
<th>75%</th>
<th>100%</th>
</tr>
<tr>
<th rowspan="2">100</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 100%" class="bar"><div></td>
</tr>
<tr class="grey-bg">
<th rowspan="2">80</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 80%" class="bar"><div></td>
</tr>
<tr>
<th rowspan="2">95</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 95%" class="bar"><div></td>
</tr>
<tr class="grey-bg">
<th rowspan="2">18</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 18%" class="bar"><div></td>
</tr>
<tr>
<th rowspan="2">5</th>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="bar-row">
<td colspan="4"><div style="width: 5%" class="bar"><div></td>
</tr>
</table>

How to make fixed header table inside scrollable div?

I want to make header of my table fixed. Table is present inside the scrollable div. Below is my code.
<div id="table-wrapper">
<div id="table-scroll">
<table bgcolor="white" border="0" cellpadding="0" cellspacing="0" id="header-fixed" width="100%" overflow="scroll" class="scrollTable">
<thead>
<tr>
<th>Order ID</th>
<th>Order Date</th>
<th>Status</th>
<th>Vol Number</th>
<th>Bonus Paid</th>
<th>Reason for no Bonus</th>
</tr>
</thead>
<tbody>
<tr>
<td><%=snd.getOrderId()%></td>
<td><%=snd.getDateCaptured()%></td>
<td><%=snd.getOrderStatus()%></td>
<td>Data Not Available</td>
<td>Data Not Available</td>
<td>Data Not Available</td>
</tr>
</tbody>
</table>
</div>
</div>
Below is my CSS, which I am using for the above div:
#table-wrapper {
position:relative;
}
#table-scroll {
height:250px;
overflow:auto;
margin-top:20px;
}
#table-wrapper table {
width:100%;
}
#table-wrapper table * {
background:white;
color:black;
}
#table-wrapper table thead th .text {
position:absolute;
top:-20px;
z-index:2;
height:20px;
width:35%;
border:1px solid red;
}
How about doing something like this? I've made it from scratch...
What I've done is used 2 tables, one for header, which will be static always, and the other table renders cells, which I've wrapped using a div element with a fixed height, and to enable scroll, am using overflow-y: auto;
Also make sure you use table-layout: fixed; with fixed width td elements so that your table doesn't break when a string without white space is used, so inorder to break that string am using word-wrap: break-word;
Demo
.wrap {
width: 352px;
}
.wrap table {
width: 300px;
table-layout: fixed;
}
table tr td {
padding: 5px;
border: 1px solid #eee;
width: 100px;
word-wrap: break-word;
}
table.head tr td {
background: #eee;
}
.inner_table {
height: 100px;
overflow-y: auto;
}
<div class="wrap">
<table class="head">
<tr>
<td>Head 1</td>
<td>Head 1</td>
<td>Head 1</td>
</tr>
</table>
<div class="inner_table">
<table>
<tr>
<td>Body 1</td>
<td>Body 1</td>
<td>Body 1</td>
</tr>
<!-- Some more tr's -->
</table>
</div>
</div>
Using position: sticky on th will do the trick.
Note: if you use position: sticky on thead or tr, it won't work.
https://jsfiddle.net/hrg3tmxj/
Some of these answers seem unnecessarily complex. Make your tbody:
display: block; height: 300px; overflow-y: auto
Then manually set the widths of each column so that the thead and tbody columns are the same width. Setting the table's style="table-layout: fixed" may also be necessary.
None of the other examples provided worked in my case - e.g. header would not match table body content when scrolling. I found a much simpler and clean way, allowing you to setup the table the normal way, and without too much code.
Example:
.table-wrapper{
overflow-y: scroll;
height: 100px;
}
.table-wrapper th{
position: sticky;
top: 0;
background-color: #FFF;
}
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
</tbody>
</table>
</div>
Thanks to https://algoart.fr/articles/css-table-fixed-header
I think you need something like this ?
.....
<style>
.table{width: 500px;height: 200px;border-collapse:collapse;}
.table-wrap{max-height: 200px;width:100%;overflow-y:auto;overflow-x:hidden;}
.table-dalam{height:300px;width:500px;border-collapse:collapse;}
.td-nya{border-left:1px solid white;border-right:1px solid grey;border-bottom:1px solid grey;}
</style>
<table class="table">
<thead>
<tr>
<th>Judul1</th>
<th>Judul2</th>
<th>Judul3</th>
<th>Judul4</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4">
<div class="table-wrap" >
<table class="table-dalam">
<tbody>
<?php foreach(range(1,10) as $i): ?>
<tr >
<td class="td-nya">td1 </td>
<td class="td-nya">td2</td>
<td class="td-nya">td2</td>
<td class="td-nya">td2</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
Source
I needed the same and this solution worked the most simple and straightforward way:
http://www.farinspace.com/jquery-scrollable-table-plugin/
I just give an id to the table I want to scroll and put one line in Javascript. That's it!
By the way, first I also thought I want to use a scrollable div, but it is not necessary at all. You can use a div and put it into it, but this solution does just what we need: scrolls the table.
This is my "crutches" solution by using html and css.
There used 2 tables and fixed width of tables and table cell`s
https://jsfiddle.net/babaikawow/s2xyct24/1/
HTML:
<div class="container">
<table class="table" border = 1; > <!-- fixed width header -->
<thead >
<tr>
<th class="tbDataId" >№</th>
<th class="tbDataName">Працівник</th>
<th class="tbDataData">Дата</th>
<th class="tbDataData">Дійсно до</th>
<th class="tbDataDiseases">Критерій1</th>
<th class="tbDataDiseases">Критерій2</th>
<th class="tbDataDiseases">Критерій3</th>
<th class="tbDataDiseases">Критерій4</th>
<th class="tbDataDiseases">Критерій5</th>
</tr>
</thead>
</table>
<div class="scrollTable"> <!-- scrolling block -->
<table class="table" border = 1;>
<tbody>
<tr>
<td class="tbDataId" >№</td>
<td class="tbDataName">Працівник</td>
<td class="tbDataData">Дата</td>
<td class="tbDataData">Дійсно до</td>
<td class="tbDataDiseases">Критерій1</td>
<td class="tbDataDiseases">Критерій2</td>
<td class="tbDataDiseases">Критерій3</td>
<td class="tbDataDiseases">Критерій4</td>
<td class="tbDataDiseases">Критерій5</td>
</tr>
<tr>
<td class="tbDataId" >№</td>
<td class="tbDataName">Працівник</td>
<td class="tbDataData">Дата</td>
<td class="tbDataData">Дійсно до</td>
<td class="tbDataDiseases">Критерій1</td>
<td class="tbDataDiseases">Критерій2</td>
<td class="tbDataDiseases">Критерій3</td>
<td class="tbDataDiseases">Критерій4</td>
<td class="tbDataDiseases">Критерій5</td>
</tr>
<tr>
<td class="tbDataId" >№</td>
<td class="tbDataName">Працівник</td>
<td class="tbDataData">Дата</td>
<td class="tbDataData">Дійсно до</td>
<td class="tbDataDiseases">Критерій1</td>
<td class="tbDataDiseases">Критерій2</td>
<td class="tbDataDiseases">Критерій3</td>
<td class="tbDataDiseases">Критерій4</td>
<td class="tbDataDiseases">Критерій5</td>
</tr>
<tr>
<td class="tbDataId" >№</td>
<td class="tbDataName">Працівник</td>
<td class="tbDataData">Дата</td>
<td class="tbDataData">Дійсно до</td>
<td class="tbDataDiseases">Критерій1</td>
<td class="tbDataDiseases">Критерій2</td>
<td class="tbDataDiseases">Критерій3</td>
<td class="tbDataDiseases">Критерій4</td>
<td class="tbDataDiseases">Критерій5</td>
</tr>
<tr>
<td class="tbDataId" >№</td>
<td class="tbDataName">Працівник</td>
<td class="tbDataData">Дата</td>
<td class="tbDataData">Дійсно до</td>
<td class="tbDataDiseases">Критерій1</td>
<td class="tbDataDiseases">Критерій2</td>
<td class="tbDataDiseases">Критерій3</td>
<td class="tbDataDiseases">Критерій4</td>
<td class="tbDataDiseases">Критерій5</td>
</tr>
</tbody>
</table>
</div>
</div>
CSS:
*{
box-sizing: border-box;
}
.container{
width:1000px;
}
.scrollTable{
overflow: scroll;
overflow-x: hidden;
height: 100px;
}
table{
margin: 0px!important;
width:983px!important;
border-collapse: collapse;
}
/* Styles of the th and td */
/* Id */
.tbDataId{
width:5%;
}
/* Дата,
Дійсно до */
.tbDataData{
/*width:170px;*/
width: 15%;
}
/* П І Б */
.tbDataName{
width: 15%;
}
/*Критерії */
.tbDataDiseases{
width:10%;
}
A Fiddle would have been more helpful nevertheless from what I understand, I guess what you need is persistent headers, look into this
http://css-tricks.com/persistent-headers/
This code works form me. Include the jquery.js file.
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script>
var headerDivWidth=0;
var contentDivWidth=0;
function fixHeader(){
var contentDivId = "contentDiv";
var headerDivId = "headerDiv";
var header = document.createElement('table');
var headerRow = document.getElementById('tableColumnHeadings');
/*Start : Place header table inside <DIV> and place this <DIV> before content table*/
var headerDiv = "<div id='"+headerDivId+"' style='width:500px;overflow-x:hidden;overflow-y:scroll' class='tableColumnHeadings'><table></table></div>";
$(headerRow).wrap(headerDiv);
$("#"+headerDivId).insertBefore("#"+contentDivId);
/*End : Place header table inside <DIV> and place this <DIV> before content table*/
fixColumnWidths(headerDivId,contentDivId);
}
function fixColumnWidths(headerDivId,contentDivId){
/*Start : Place header row cell and content table first row cell inside <DIV>*/
var contentFirstRowCells = $('#'+contentDivId+' table tr:first-child td');
for (k = 0; k < contentFirstRowCells.length; k++) {
$( contentFirstRowCells[k] ).wrapInner( "<div ></div>");
}
var headerFirstRowCells = $('#'+headerDivId+' table tr:first-child td');
for (k = 0; k < headerFirstRowCells.length; k++) {
$( headerFirstRowCells[k] ).wrapInner( "<div></div>");
}
/*End : Place header row cell and content table first row cell inside <DIV>*/
/*Start : Fix width for columns of header cells and content first ror cells*/
var headerColumns = $('#'+headerDivId+' table tr:first-child td div:first-child');
var contentColumns = $('#'+contentDivId+' table tr:first-child td div:first-child');
for (i = 0; i < contentColumns.length; i++) {
if (i == contentColumns.length - 1) {
contentCellWidth = contentColumns[i].offsetWidth;
}
else {
contentCellWidth = contentColumns[i].offsetWidth;
}
headerCellWidth = headerColumns[i].offsetWidth;
if(contentCellWidth>headerCellWidth){
$(headerColumns[i]).css('width', contentCellWidth+"px");
$(contentColumns[i]).css('width', contentCellWidth+"px");
}else{
$(headerColumns[i]).css('width', headerCellWidth+"px");
$(contentColumns[i]).css('width', headerCellWidth+"px");
}
}
/*End : Fix width for columns of header and columns of content table first row*/
}
function OnScrollDiv(Scrollablediv) {
document.getElementById('headerDiv').scrollLeft = Scrollablediv.scrollLeft;
}
function radioCount(){
alert(document.form.elements.length);
}
</script>
<style>
table,th,td
{
border:1px solid black;
border-collapse:collapse;
}
th,td
{
padding:5px;
}
</style>
</head>
<body onload="fixHeader();">
<form id="form" name="form">
<div id="contentDiv" style="width:500px;height:100px;overflow:auto;" onscroll="OnScrollDiv(this)">
<table>
<!--tr id="tableColumnHeadings" class="tableColumnHeadings">
<td><div>Firstname</div></td>
<td><div>Lastname</div></td>
<td><div>Points</div></td>
</tr>
<tr>
<td><div>Jillsddddddddddddddddddddddddddd</div></td>
<td><div>Smith</div></td>
<td><div>50</div></td>
</tr-->
<tr id="tableColumnHeadings" class="tableColumnHeadings">
<td> </td>
<td>Firstname</td>
<td>Lastname</td>
<td>Points</td>
</tr>
<tr style="height:0px">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr >
<td><input type="radio" id="SELECTED_ID" name="SELECTED_ID" onclick="javascript:radioCount();"/></td>
<td>Jillsddddddddddddddddddddddddddd</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td><input type="radio" id="SELECTED_ID" name="SELECTED_ID"/></td>
<td>Eve</td>
<td>Jackson</td>
<td>9400000000000000000000000000000</td>
</tr>
<tr>
<td><input type="radio" id="SELECTED_ID" name="SELECTED_ID"/></td>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td><input type="radio" id="SELECTED_ID" name="SELECTED_ID"/></td>
<td><div>Jillsddddddddddddddddddddddddddd</div></td>
<td><div>Smith</div></td>
<td><div>50</div></td>
</tr>
<tr>
<td><input type="radio" id="SELECTED_ID" name="SELECTED_ID"/></td>
<td>Eve</td>
<td>Jackson</td>
<td>9400000000000000000000000000000</td>
</tr>
<tr>
<td><input type="radio" id="SELECTED_ID" name="SELECTED_ID"/></td>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
</form>
</body>
</html>
use StickyTableHeaders.js for this.
Header was transparent . so try to add this css .
thead {
border-top: none;
border-bottom: none;
background-color: #FFF;
}
I know this question is old, but if anyone have this same issue, an easy way without having to write lots of CSS, just wrap your <table> with <div> and your <div> should have a style with overflow-y: auto; and some height.
As below example:
<div style="overflow-y: auto; height: 400px;">
<table>...</table>
</div>
Add a style to the thead as below:
thead {
position: sticky;
top: 0;z-index: 2;
}

Resources