Proper scaling of overlaying div in table - html

I have a problem that I do not understand regarding scaling of child elements inside html tables.
To start from the beginning, my goal is to have a table and to overlay the table body with a div using z-index. With the proper color this then looks like the table is inactive and it can not be clicked.
Below you find a minimal example of how this looks like due to some other requirement. As you can see, the overlay div always scales to the full table and not only a part of it. No matter if it is a child of tbody nor of one cell (as it is right now in the example code - I thought maybe a div is not allowed as a direct child of tbody but instead I could put one overlay div in each table cell).
table {
border: 1;
border-color: blue;
}
#content {
position: relative;
}
#content * {
position: inherit;
}
#overlay {
top: 0;
left: 0;
/*bottom: 0;
right: 0;*/
position: absolute !important;
background: rgba(0, 0, 0, .4);
z-index: 3;
width: 100%;
height: 100%
}
<div id="content">
<div>
Some stuff before
</div>
<br>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
Cell
</div>
<div id="overlay"></div>
</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
<td>Footer 2</td>
</tr>
</tfoot>
</table>
<br>
<div>
Some stuff after
</div>
</div>
I do not understand why this happens which makes it hard for me to think of a fix and I hope somebody can help me with that and provide an explanation.
Cheers

Your table cells also need to be set to position: relative. Instead of #content * directly set them using td or at least #content td.
td {
position: relative;
}
#overlay {
top: 0;
left: 0;
position: absolute;
background: rgba(0, 0, 0, .4);
z-index: 3;
width: 100%;
height: 100%
}
<div id="content">
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
Cell
</div>
<div id="overlay"></div>
</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
<td>Footer 2</td>
</tr>
</tfoot>
</table>
</div>
So why does this work?
Short answer: position is not inheritable and Chrome has some problems with table tags.
But that's only half the truth. All major browsers (Tested with Chrome, Firefox and IE11) allow most (or probably even all) properties to inherit from their parent. When you test your snippet in Firefox or IE11 you will see that it indeed works. So why not in Chrome then?
It turns out that Chrome has some issues with the table-* display modes and the table-tags themselves. It always uses the default position value (which is static) when being inherited. Even if the closest parent has position: relative set, it won't work as illustrated in the next code snippet.
So to conclude: It's best to always explicitly set position: relative and in most cases avoid using inherit all together.
main {
position: relative;
border: 2px solid #000;
width: 200px;
margin-bottom: 20px;
}
table, .fake-table {
min-height: 50px;
margin: 10px;
}
table, tr, td, .fake-table div {
position: inherit;
}
.relative {
position: relative;
}
em {
position: absolute;
left: 0;
top: 0;
width: 100%;
min-width: 100px;
height: 100%;
background: rgba(166, 199, 252, .9);
text-shadow: 0 0 10px #fff;
}
.fake-table .table {
display: block;
}
.fake-table .row {
display: flex;
justify-content: flex-start;
}
.fake-table .cell {
display: inline-block;
min-width: 40px;
}
<main>
<table>
<tr>
<td>...</td>
<td>
cell
<em>Starting point (inherited table)</em>
</td>
</tr>
</table>
</main>
<main>
<table>
<tr class="relative">
<td>...</td>
<td>
cell
<em>Parent is set to relative</em>
</td>
</tr>
</table>
</main>
<main class="fake-table">
<table class="table">
<tr class="row">
<td class="cell">...</td>
<td class="cell">
cell
<em>Table tags in different display mode</em>
</td>
</tr>
</table>
</main>
<main class="fake-table">
<div class="table">
<div class="row">
<div class="cell">...</div>
<div class="cell">
cell
<em>Table using flex (behaves correctly)</em>
</div>
</div>
</div>
</main>
<main>
<table>
<tr>
<td>...</td>
<td class="relative">
cell
<em>Expected rendering</em>
</td>
</tr>
</table>
</main>

Related

CSS: How to set minimum and maximum height according to inside?

Suppose I have a table with 100vh height, how to set minimum height for thead according to inside and maximum tbody?
<table style="height: 100vh;">
<thead>...</thead>
<tbody>...</tbody>
</table>
Is this what you look for?
Updated
Did a few tests and noticed giving height to the body didn't work properly cross browser, which below update does (tested on Chrome, Firefox, Edge, IE11)
html, body {
margin: 0;
}
table {
width: 100%;
height: 100vh;
}
table thead tr {
height: 80px; /* on table elements, height works kind of like min-height */
background: yellow;
}
table tbody tr {
background: lime;
}
<table>
<thead>
<tr>
<td>
HEAD<br>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>
BODY
</td>
</tr>
</tbody>
</table>
you can follow the hack to achieve your goal.
Use least height for thead, but not 0.Use 0% for tbody
html,body{
margin:0;
}
table{
width:100%;
height: 100vh;
border: 1px solid black;
}
thead{
background: red;
height:1px;
}
tbody{
background: blue;
height:0%;
}
<table>
<thead>
<tr>
<td colspan="4">
<img src="http://dummyimage.com/100x100/eb00eb/fff">
</td>
</tr>
</thead>
<tbody>
<tr>
<td>BODY</td>
<td>BODY</td>
<td>BODY</td>
<td>BODY</td>
</tr>
</tbody>
</table>

Get column to fill 100% of remaining space in position absolute tbody

A simple quick question, i have this HTML
<div id="list">
<table class="t">
<thead>
<tr>
<th class="w100"><div>ID</div></th>
<th><div>NAME</div></th>
<th class="w100"><div>EXTRA</div></th>
<th class="w100"><div>EXTRA1</div></th>
</tr>
</thead>
<tbody style="top: 0px;" page="0">
<tr>
<td class="w100">ID</td>
<td>NAME</td>
<td class="wr100">EXTRA</td>
<td class="w100">EXTRA1</td>
</tr>
<tr>
<td class="w100">ID</td>
<td>NAME</td>
<td class="wr100">EXTRA</td>
<td class="w100">EXTRA1</td>
</tr>
</tbody>
</table>
</div>
CSS
#list {
position: relative;
height: 200px;
overflow: auto;
}
.t {
height: 20000px;
overflow: auto;
width: 100%;
}
.t>tbody {
position: absolute;
border:solid 1px;
}
tr {
height: 20px;
width: 100%;
}
.w100 {
width: 100px;
}
how can I extend the NAME column to fill up the remaining space inside a position absolute tbody just like the thead does?
I need this css to remain like this:
.t>tbody {
position: absolute;
}
and the table must have a height so that I can scroll past the tbody content
everything else can be changed
here is a demo
https://jsfiddle.net/wyzixg/f3gqgjgj/5/
Can this be achieved by css and/or js/jquery?
I think that the following is what you need.
You were pretty close, except that the absolute positioning was confusing the auto sizing algorithm used in table layouts.
If you set the width of the table to 100%, then the table will resize the columns to fill up the space. Since you set the width of all columns (except the 2nd one for NAME) to 100px, any remaining width will be allocated to the 2nd column since its width will be auto.
Since you need the tbody element to be position: absolute, you can still get the auto table sizing effect by using display: table on tbody, which looks a bit bizarre but it might do the trick.
I am not sure if your JavaScript will work as expected, but the layout seems to be what you need.
There is an artifact, a second horizontal scroll bar, which can probably be removed with some experimentation, but I did not try it (yet).
body { margin: 0;}
.c-list {
position: absolute;
width: 99%;
height: 400px;
overflow: auto;
-webkit-overflow-scrolling: touch;
border: 1px dotted blue;
}
table {
}
.t tbody {
position: absolute;
width: 100%;
display: table;
}
table td {
text-align: center;
border: solid 1px;
margin: 0;
padding: 0;
}
.w100, .wr100 {
width: 100px;
}
.wr100 {
text-align: right;
}
<div class="c-list">
<table class="t">
<tbody>
<tr>
<td class="w100">ID</td>
<td>NAME</td>
<td class="wr100">EXTRA</td>
<td class="w100">EXTRA1</td>
</tr>
<tr>
<td class="w100">1</td>
<td>1</td>
<td class="wr100">1</td>
<td class="w100">1</td>
</tr>
<tr>
<td class="w100">2</td>
<td>2</td>
<td class="wr100">2</td>
<td class="w100">2</td>
</tr>
<tr>
<td class="w100">3</td>
<td>3</td>
<td class="wr100">3</td>
<td class="w100">3</td>
</tr>
<tr>
<td class="w100">4</td>
<td>4</td>
<td class="wr100">4</td>
<td class="w100">4</td>
</tr>
<tr>
<td class="w100">5</td>
<td>5</td>
<td class="wr100">5</td>
<td class="w100">5</td>
</tr>
</tbody>
</table>
</div>
Use <thead> for table headers, along with <th>, so you can set the header width to 100% to fill the remaining space, and it will apply for the entire column.
Check this snippet for a better view of the result.
Also you don't really need the height for the table, and absolute.
.c-list {
position: absolute;
width:99%;
height:400px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
table td {
text-align: center;
border:solid 1px;
margin:0;
padding:0;
}
.t > tbody {
position: absolute;
width: 99%;
}
table {
width:100%;
}
table tr{
width:100%;
}
table tbody {
width:100%;
}
.w100 {
width:100px;
}
.wr100 {
width:100px;
text-align: right;
}
<div class="c-list" >
<table style="height: 2000px;" class="t">
<tbody style="top: 0px;" page="0">
<tr><td class="w100">ID</td><td>NAME</td><td class="wr100">EXTRA</td><td class="w100">EXTRA1</td></tr>
<tr><td class="w100">1</td><td>1</td><td class="wr100">1</td><td class="w100">1</td></tr>
<tr><td class="w100">2</td><td>2</td><td class="wr100">2</td><td class="w100">2</td></tr>
<tr><td class="w100">3</td><td>3</td><td class="wr100">3</td><td class="w100">3</td></tr>
<tr><td class="w100">4</td><td>4</td><td class="wr100">4</td><td class="w100">4</td></tr>
<tr><td class="w100">5</td><td>5</td><td class="wr100">5</td><td class="w100">5</td></tr>
</tbody>
</table>
</div>

Resize Table Proportionally to fit within div

My issue is simple and i suspect the answer is its not possible as i couldn't find any examples.
I have a table built with css and HTML. I would like to re-size it proportionally as if it was an image so it fits inside a DIV. I know you guys know what a table looks like but seems like i have to submit some code to submit this questions so i added it below
<table>
<tr>
<td></td>
</tr>
</table>
Assuming that's not possible is it possible to convert a table into an image and then i can re-size the image?
You can set the width of the table to be 100% of the containing div, then set the <td>'s to be a percentage of the table.
An example would be something like this: http://jsfiddle.net/9VFQ5/
<div class="container">
<table>
<tr>
<td>Test 1</td>
<td>Test 2</td>
</tr>
</table>
</div>
.container {
width: 25%;
background-color: red;
}
table {
width: 80%;
margin: 0 auto;
background-color: blue;
}
td {
width: 50%;
color: white;
}
.container {
width: 100%;
background-color: blue;
}
table {
width: 80%;
margin: 0 auto;
background-color: red;
}
td {
width: 50%;
color: white;
padding: 1rem;
background-color: green;
}
th {
color: black;
}
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 container">
<table>
<tr>
<th>1st COLUMN</th>
<th>2nd COLUMN</th>
</tr>
<tr>
<td>Table Data1 Row1</td>
<td>Table Data2 Row1</td>
</tr>
<tr>
<td>Table Data1 Row2</td>
<td>Table Data2 Row2</td>
</tr>
</table>
</div>

Centered text in fully clickable table cell

This one is driving me mad, unfortunately I'm not very good in CSS yet.
How can I get a horizontally and vertically centered text-link into a table cell which is fully clickable?
I researched, tried several solutions, none of them worked. Here is my best approach so far:
HTML
<table class="dataTable">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
I wanne be centered!
</td>
<td>
Me too!
</td>
</tr>
</tbody>
</table>
CSS
.dataTable td a {
width: 100%;
height: 100%;
text-align: center;
vertical-align: middle;
display:block;
text-decoration: none;
}
.dataTable td {
display:inline-block;
}
This one gives me centered text, but the link only covers the width of the cell, not the height. If I change the css for the link to display:inline-block, then the full cell is clickable, but the text is not vertically centered anymore.
I need both. Help!
i think you should remove this :
.dataTable td {
display:inline-block;
}
see this fiddle
I think that's what you want:
.dataTable {
text-align: center;
}
.dataTable a {
display: inline-block;
width: 100%;
height: 100%;
}
/* Just for better visualization */
.dataTable td {
background: red;
}
<table class="dataTable">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
I wanne be centered!
</td>
<td>
Me too!
</td>
</tr>
</tbody>
</table>
If you want to increase td's height, you should do it by modifying a's height. Otherwise, the link will not occupy the whole cell's height. You can achieve that with height property or also with line-height.
.dataTable {
text-align: center;
}
.dataTable a {
display: inline-block;
width: 100%;
height: 100%;
line-height: 5; /* To get a 5 text lines high cell */
}
.dataTable td {
/* Just for better visualization */
background: red;
}
<table class="dataTable">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
I wanne be centered!
</td>
<td>
Me too!
</td>
</tr>
</tbody>
</table>
Wrap your text in a
div style="padding-top:5px;".
That will center it approximately.

What does a table way to small for the screen create a scrollbar?

Here's a DEMO
Here's my HTML:
<div>
<table>
<tbody>
<tr>
<td>A1</td>
<td>B1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</tbody>
</table>
</div>
and CSS:
div {
position: relative;
left: 100px;
}
table {
border: 1px solid black;
}
As you can see in the demo, it causes horizontal scrollbars. Is there any way to get rid of this, other than using javascript?
instead of left maybe try
margin-left: 100px;