so I am using materialize css select to style my dropdowns in a form. When I land on my page, however, the dropdown is always "hidden open". More specifically, if I hover below the "residency" dropdown to the white space and even into the later part of the form and I click, it will change the value of the drop down. The only way to get rid of it is if I open the drop down and close it. Why is this occurring?? Any recommendations?
The Z-index of the closed unordered list is 999. When I change it to -1, it goes away but then when I open the drop down, its behind all the other text.
I have added one more div called wrapper and made header and footer position fixed. I have also added the padding in wrapper div as of height of header, same with the case of footer.
Hope this will help
HTML:
<div class="wrapper" style="overflow-y: auto;overflow-x: hidden;padding-top: 34px;padding-bottom: 126px;">
<header id='header'>Test 0.1</header>
<aside id='aside'>
<p>Menu 1</p>
<p>Menu 2</p>
<p>Menu 3</p>
<p>Menu 4</p>
<p>
<span id='spn'>n</span>
</p>
</aside>
<section>
<div id='divMain'>
<table>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr><tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr><tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr><tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr><tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
</div>
</section>
<footer id='footer'>Address,
<br>phone,
<br>etc.
<br>
<br>Address,
<br>phone,
<br>etc.
</footer>
</div>
CSS:
html,
body {
height: 100%;
margin: 0;
overflow-x: hidden;
overflow-y: hidden;
}
body {
position: relative;
padding-top: 0;
overflow-y: auto;
}
header {
background-color: green;
color: white;
text-align: center;
font-weight: bold;
font-size: 30px;
position: fixed;
width: 100%;
top: 0;
}
section {
float: right;
width: 80%;
overflow-x: auto;
overflow-y: auto;
}
section div {
padding: 10px;
overflow-x: auto;
overflow-y: auto;
}
aside {
float: left;
background-color: lightgreen;
width: 20%;
}
aside p {
margin-left: 20px;
}
footer {
background-color: green;
color: white;
text-align: center;
clear: both;
position: fixed;
bottom: 0;
width: 100%;
}
table {
border-collapse: collapse;
}
th {
border: 1px solid black;
text-align: center;
font-weight: bold;
}
td {
border: 1px solid black;
text-align: center;
}
Related
I want two tables side-by-side that...
Share the same vertical scroll
Have separate horizontal scrolls
Have sticky headers
...all within a container of flexible width and height.
Here is a codepen of my attempt: https://codepen.io/numberjak/pen/gOYGEKz
As you can see I have ticked all my requirements except for both tables having sticky headers.
<div class="container">
<div class="scroll red">
<table>
<thead>
<tr>
<th>Scroll 1</th>
<th>Scroll 2</th>
<th>Scroll 3</th>
<th>Scroll 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>
<div class="scroll blue">
<table>
<thead>
<tr>
<th>Scroll 1</th>
<th>Scroll 2</th>
<th>Scroll 3</th>
<th>Scroll 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>
</div>
html {
height: 100%;
background-color: black;
}
div {
display: flex;
}
.container {
overflow: auto;
align-items: flex-start;
max-height: 20rem;
}
thead th {
position: sticky;
top: 0;
background-color: grey;
}
td, th {
min-width: 30rem;
padding: 1rem;
background-color: white;
}
tr {
height: 10rem;
}
.scroll {
overflow: auto;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
Header and the body of the table are still connected, they will still have the same scroll properties. Now to let them not 'work' as a table anymore you can set the display: block. This way and are separated.
You can add this to your css
table tbody, table thead
{
display: block;
}
table tbody
{
overflow: auto;
height: 100px;
}
The scroll issue can be fixed with some javascript!
$(".red tbody").scroll(function() {
$(".blue tbody").scrollTop($(".red tbody").scrollTop());
});
$(".blue tbody").scroll(function() {
$(".red tbody").scrollTop($(".blue tbody").scrollTop() );
});
so the final product look like this
$(".red tbody").scroll(function() {
$(".blue tbody").scrollTop($(".red tbody").scrollTop());
});
$(".blue tbody").scroll(function() {
$(".red tbody").scrollTop($(".blue tbody").scrollTop() );
});
html {
height: 100%;
background-color: black;
}
div {
display: flex;
}
.container {
overflow: auto;
align-items: flex-start;
max-height: 20rem;
}
thead th {
position: sticky;
top: 0;
background-color: grey;
}
td, th {
min-width: 30rem;
padding: 1rem;
background-color: white;
}
tr {
height: 10rem;
}
.scroll {
overflow: auto;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
table tbody, table thead
{
display: block;
}
table tbody
{
overflow: auto;
height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="scroll red">
<table>
<thead>
<tr>
<th>Scroll 1</th>
<th>Scroll 2</th>
<th>Scroll 3</th>
<th>Scroll 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>
<div class="scroll blue">
<table>
<thead>
<tr>
<th>Scroll 1</th>
<th>Scroll 2</th>
<th>Scroll 3</th>
<th>Scroll 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>
</div>
All the solutions I've seen to make a table with a sticky header and resizable columns seems to be using Jquery. I want a plain old solution using CSS only if possible. If CSS only is not possible then I can go with CSS + Javascript but no JQuery, please. Internet Explorer support is a pipe dream at this point...
I've found separate solutions for a sticky header, and separate solutions for resizable columns but no complete solution for both. Can anyone help?
The only thing missing in my attempt table tbody is display:block for the scrollbar to work, but that messes everything else up.
My attempt:
table{
display:block;
background-color:cyan;
height:300px !important;
}
th, td {
min-width: 25px;
resize: horizontal;
overflow: auto;
}
tbody {
height: 30px !important;
background-color:green;
width: 100%;
font-size: 1.45vmin;
overflow-y: scroll;
}
<div style="height:30px;background-color:red;">
<table>
<thead>
<tr><td>header1</td><td>header2</td><td>header3</td><td>header4</td><td>header5</td></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
</tbody>
</table>
</div>
Here is a solution using the CSS position: sticky attribute with resize: horizontal.
The resizable table headers will show a small icon in the lower-right hand corner, that you can grab and resize. (Due to a bug in Chrome, it may be so small you can barely see it...so look closely.)
<html>
<style>
.fixed_headers {
border-collapse: collapse;
width:100%;
}
.fixed_headers td,
.fixed_headers thead th {
padding: 5px;
text-align: left;
}
.fixed_headers thead, textarea {
background-color: #333;
color: #FDFDFD;
}
.fixed_headers thead tr {
position: relative;
}
.fixed_headers tbody tr:nth-child(even) {
background-color: #DDD;
}
.fixed_headers thead th {
position: sticky;
top: 0; /* REQUIRED: https://stackoverflow.com/a/43707215 */
background-color: #333;
resize: horizontal;
overflow: auto;
min-width: 70px;
}
</style>
<div style="height: 300px;overflow: auto;">
<table class="fixed_headers">
<thead>
<tr><th>header 1</th><th>header 2</th><th>header 3</th><th>header 4</th><th>header 5</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
</tbody>
</table>
</div>
</html>
For CSS resizable columns you could use this trick. Abuse the webkit resizable textarea feature. Wrap header titles in readonly textareas and style as headings, just leave the resizing thumb. Use min-max-width to the same to disable vertical resizing. This is just Proof-of-work. Play with it.
<html>
<style>
.fixed_headers {
border-collapse: collapse;
}
.fixed_headers textarea {
text-decoration: underline;
}
.fixed_headers textarea,
.fixed_headers td {
padding: 5px;
text-align: left;
}
.fixed_headers textarea,
.fixed_headers td {
min-width: 100px;
}
.fixed_headers thead, textarea {
background-color: #333;
color: #FDFDFD;
}
.fixed_headers thead tr {
position: relative;
}
.fixed_headers tbody {
overflow: auto;
width: 100%;
height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
background-color: #DDD;
}
.old_ie_wrapper {
height: 300px;
width: 750px;
overflow-x: hidden;
overflow-y: auto;
}
textarea {
border: none;
min-height: 16px;
max-height: 16px;
}
</style>
<div style="height: 300px;overflow: auto;">
<table class="fixed_headers">
<thead>
<tr><th><textarea readonly>header 1</textarea></th><th><textarea readonly>header 2</textarea></th><th><textarea readonly>header 3</textarea></th><th><textarea readonly>header 4</textarea></th><th><textarea readonly>header 5</textarea></th></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
</tbody>
</table>
</div>
</html>
Demo
http://jsfiddle.net/rft8v4sp/1/
The only thing you really need is position: sticky; on the header th.
This combined with your resize: horizontal will fix your issue if I understand your question right.
table {
display: block;
background-color: cyan;
height: 200px !important;
overflow-y: scroll;
}
thead th {
position: sticky;
top: 0;
background: white;
z-index: 10;
}
th,
td {
resize: horizontal;
overflow: auto;
min-width: 25px;
}
td {
font-size: 1.45vmin;
}
tbody {
height: 30px !important;
background-color: green;
width: 100%;
}
<div style="height:30px;background-color:red;">
<table>
<thead>
<tr>
<th>header1</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
</div>
For the fixed header I used position: sticky and for the scroll I used a container to mimic the tbody scrolling (actually, it is the tbody that scrolls) and avoid a block display on the table or its tbody that would make it somewhat dysfunctional.
The sticky position has more support than resize anyway so with the mandatory resize property it's relatively safe crossbrowser.
https://caniuse.com/#search=sticky
https://caniuse.com/#search=resize
I tried several times editing this post to make the posted code run here on SO, but to no avail, so I made you a public JsFiddle to play with: https://jsfiddle.net/Erik_J/xzhpdqLo/
(#Sølve Tornøe, I wasn't aware of your post before I submitted. Was away for a few hours and missed to refresh before posting. So you were the first to give a valid solution.)
div {
position: relative;
margin: auto;
outline: 1px solid #000;
outline-offset: -1px;
max-width: 900px;
max-height: 300px;
overflow-y: scroll;
}
table{
width: 100%;
border-collapse: collapse;
}
thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
resize: horizontal;
overflow: auto;
background: #cff;
}
th, td {
padding: 5px 10px;
border: 1px solid #000;
}
th {
text-transform: capitalize;
}
<div>
<table>
<thead>
<tr><th></th><th>header 1</th><th>header 2</th><th>header 3</th><th>header 4</th></tr>
</thead>
<tbody>
<tr><th>header 1</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 2 2222</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 3</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 4</th><td>1</td><td>2</td><td>3 3333333 3333333 3333333</td><td>4</td></tr>
<tr><th>header 5</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 6</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 7</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 8</th><td>1</td><td>2 2222 2222 2222</td><td>3</td><td>4</td></tr>
<tr><th>header 9</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 10</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 11</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 12</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 13</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 14</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 15</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th>header 16</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
</tbody>
</table>
</div>
I am making a page with tabular data is scrollable with main page scrollbar but with keeping table header visible. There's a page header that sticks on top and pagination area that sticks on bottom on the page.
I gave it a try here.
var dataHeader = document.querySelector('.data thead');
var scrollValue = 50;
window.onscroll = function () {
if (document.body.scrollTop > scrollValue || document.documentElement.scrollTop > scrollValue) {
dataHeader.className = "fixed";
} else {
dataHeader.className = "";
}
};
.main {
position: relative;
top: 0;
width: 700px;
margin: 0 auto;
}
.header {
position: fixed;
top: 0;
background-color: #abc;
width: 700px;
z-index: 10;
}
.content {
position: relative;
top: 60px;
background: #cfe;
}
.content-header {
color: blue;
padding-top: 10px;
}
.data {
position: relative;
margin-bottom: 18px;
}
.data table {
border-collapse: collapse;
width: 700px;
}
.data thead {
background: grey;
width: 700px;
display: table-header-group;
}
.data tbody {
width: 700px;
}
.data thead.fixed {
position: fixed;
top: 80px;
}
.data thead.fixed th {
width: 90px;
}
.paging {
position: absolute;
bottom: 0;
background-color: black;
color: white;
width: 700px;
}
.column {
padding: 2;
width: 80px;
}
<div class="main">
<div class="header">
<h1>Super Page</h1>
</div>
<div class="content">
<div class="content-header">
<h2>Beautiful Content</h2>
</div>
<div class="data">
<table>
<colgroup>
<col class="column">
<col class="column">
<col class="column">
</colgroup>
<thead>
<tr>
<th class="column">Sr</th>
<th class="column">City</th>
<th class="column">Country</th>
</tr>
<thead>
<tbody>
<tr>
<td>1</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>2</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>3</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>4</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>5</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>6</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>7</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>8</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>9</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>10</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>11</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>12</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>13</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>14</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>15</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>16</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>17</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>18</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>19</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>20</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>21</td>
<td>Prague</td>
<td>Czech Republic</td>
</tr>
</tbody>
</table>
</div>
<!-- /.data -->
<div class="paging">
Displaying 10 of 100 records
</div>
</div>
<!-- /.content -->
</div>
<!-- /.main -->
The only problem is when I scroll down, table header kind of collapses and does not remain aligned with table body's columns. How Can I fix it?
You can adjust your .data thead.fixed th rule to width: calc(700px/3); like so:
var dataHeader = document.querySelector('.data thead');
var scrollValue = 50;
window.onscroll = function () {
if (document.body.scrollTop > scrollValue || document.documentElement.scrollTop > scrollValue) {
dataHeader.className = "fixed";
} else {
dataHeader.className = "";
}
};
.main {
position: relative;
top: 0;
width: 700px;
margin: 0 auto;
}
.header {
position: fixed;
top: 0;
background-color: #abc;
width: 700px;
z-index: 10;
}
.content {
position: relative;
top: 60px;
background: #cfe;
}
.content-header {
color: blue;
padding-top: 10px;
}
.data {
position: relative;
margin-bottom: 18px;
}
.data table {
border-collapse: collapse;
width: 700px;
}
.data thead {
background: grey;
width: 700px;
display: table-header-group;
}
.data tbody {
width: 700px;
}
.data thead.fixed {
position: fixed;
top: 80px;
}
.data thead.fixed th {
width: calc(700px/3);
}
.paging {
position: absolute;
bottom: 0;
background-color: black;
color: white;
width: 700px;
}
.column {
padding: 2;
width: 80px;
<div class="main">
<div class="header">
<h1>Super Page</h1>
</div>
<div class="content">
<div class="content-header">
<h2>Beautiful Content</h2>
</div>
<div class="data">
<table>
<colgroup>
<col class="column">
<col class="column">
<col class="column">
</colgroup>
<thead>
<tr>
<th class="column">Sr</th>
<th class="column">City</th>
<th class="column">Country</th>
</tr>
<thead>
<tbody>
<tr>
<td>1</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>2</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>3</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>4</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>5</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>6</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>7</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>8</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>9</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>10</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>11</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>12</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>13</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>14</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>15</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>16</td>
<td>Amsterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>17</td>
<td>Lahore</td>
<td>Pakistan</td>
</tr>
<tr>
<td>18</td>
<td>Doha</td>
<td>Qatar</td>
</tr>
<tr>
<td>19</td>
<td>Mumbai</td>
<td>India</td>
</tr>
<tr>
<td>20</td>
<td>Rotterdam</td>
<td>Netherlands</td>
</tr>
<tr>
<td>21</td>
<td>Prague</td>
<td>Czech Republic</td>
</tr>
</tbody>
</table>
</div>
<!-- /.data -->
<div class="paging">
Displaying 10 of 100 records
</div>
</div>
<!-- /.content -->
</div>
<!-- /.main -->
I'm not sure if this is even possible to accomplish without JavaScript, but it would be preferable.
This is kind of what my page looks like:
____________________________
| TITLE | |This is a fixed header. I want "TITLE"
|----------------------------| |to be the name of the row, and I want it
| _______ _______ ___| |to show when I hover over one of the
| | | | | | | |image rows.
| | | | | | | |
| |_______| |_______| |___| | [The boxes are the images.]
| _______ _______ ___| |
|__|_______|__|_______|__|___| |
header {
background: #FFFFFF;
position: fixed !important;
width: 100%;
height: 85px;
top: 0;
left: 0;
text-align: left;
font-size: 30px;
border: 1px solid black;
}
body {
padding-top: 100px;
/*equal to the height of your header */
}
r1n {
width: 200px;
height: 200px;
display: inline;
}
r1n:hover {
display: none
}
table tr:hover ~ header r1n {
display: none
}
<header>
<r1n>TITLE_NAME</r1n>
</header>
<body>
<table>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</table>
</body>
Is there a CSS method/trick to make the fixed header show the row's name?
Maybe by concealing a bunch of divs in the header and displaying them depending on which row the cursor is on?
EDIT:
#AndrewBone: CSS and JS solution
#Dekel: JS solution
EDIT^2: Just... just look at all the answers. They're all good. CSS/JS/JQ.
I see lots of people saying this isn't possible, it is though I would never suggest you use it in practice.
Here is an example:
body {
margin: 0;
}
table {
margin: 18px 0 0 0;
position: relative;
border: 1px solid black;
}
tr:nth-child(even) {
background: #DDD;
}
tr:nth-child(odd) {
background: #FFF;
}
tr:hover {
background: tomato;
}
tr[data-header]:hover:after {
content: attr(data-header);
position: absolute;
top: -19px;
left: -1px;
border: 1px solid black;
border-bottom-width: 0px;
width: 100%;
}
td {
padding: 5px 15px;
}
<table>
<tr data-header="Header 1">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Header 2">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Header 3">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Header 4">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</table>
I've added a header attribute to each tr also I've added a pseudo element, this pseudo element puts some content, which in this example is taken from the header attribute thanks to attr(header), and positions it where we want it in relation to the parent, table, just like that we have some code that works and is JS free. But honestly, use JS if you can :-)
Hope this helps.
EDIT:
Here's a pure javascript solution
const trSel = document.querySelectorAll("tr[data-header]");
for (let i = 0; i < trSel.length; i++) {
trSel[i].addEventListener("mouseover", function(evt) {
let headSel = trSel[i].parentElement.parentElement.parentElement.querySelector(":scope > .header");
headSel.innerHTML = trSel[i].dataset.header;
});
}
body {
margin: 0;
}
.header {
padding: 5px 0;
}
tr:nth-child(even) {
background: #DDD;
}
tr:nth-child(odd) {
background: #FFF;
}
tr[data-header]:hover {
background: tomato;
}
td {
padding: 5px 15px;
}
<div>
<div class="header">
Placeholder!
</div>
<table>
<tr data-header="Table 1 Row 1">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Table 1 Row 2">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Table 1 Row 3">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Table 1 Row 4">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</table>
</div>
<h2>
Wild second table appeared
</h2>
<div>
<div class="header">
Placeholder!
</div>
<table>
<tr data-header="Table 2 Row 1">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Table 2 Row 2">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Table 2 Row 3">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-header="Table 2 Row 4">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</table>
</div>
It uses the same principles, but now it's actually updating the text so when you move your mouse away it can keep the last selected row. It works with multiple tables too.
EDIT 2: slight edit, I've changed to using data-header instead of header, just because that's what you're meant to do ;-)
Just because you asked for a js solution in the comment #AndrewBone's answer.
Notice the usage of index to find the current position of the hovered tr inside the table. Index starts in 0, hence the +1 you see there.
$(function() {
$('#tbl1 tr').hover(function() {
i = $('#tbl1 tr').index(this) + 1;
$('r1n').text('Row ' + i);
});
});
header {
background: #FFFFFF;
position: fixed !important;
width: 100%;
height: 85px;
top: 0;
left: 0;
text-align: left;
font-size: 30px;
border: 1px solid black;
}
body {
padding-top: 100px;
/*equal to the height of your header */
}
r1n {
width: 200px;
height: 200px;
display: inline;
}
#tbl1 {
border-collapse: collapse;
}
#tbl1 td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<r1n>TITLE_NAME</r1n>
</header>
<table id="tbl1" border="1">
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</table>
i see that you have some answers ( and an accepted one ) just wanted to put a JQ solution with targets here if anyone prefers something like this :) ( i guess i doesn't hurt another answer )
in this code, table and header are siblings , even if in your posted code, body is the parent of table and sibling with header. here, everything is automatically inserted inside the default <body> tag
$("table tr").hover(function(){
var data = $(this).attr('data-target'),
target = $(this).parents('table').siblings('header').find('h1')
$(target).each(function(){
if($(this).attr('id') == data) {
$(this).toggle()
}
})
})
header {
background: #FFFFFF;
position: fixed !important;
width: 100%;
height: 85px;
top: 0;
left: 0;
text-align: left;
font-size: 30px;
border: 1px solid black;
}
body {
padding-top: 100px;
/*equal to the height of your header */
}
header h1 {
display:none;
position:absolute;
left:0;
top:0;
margin:0;
}
table tr {
cursor:pointer;
background:blue;
}
table tr:nth-child(odd) {
background:red;
}
table,td {
border-collapse:collapse;
padding:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<h1 id="row1">Title row1 </h1>
<h1 id="row2">Title row2 </h1>
<h1 id="row3">Title row3 </h1>
<h1 id="row4">Title row4 </h1>
</header>
<body>
<table>
<tr data-target="row1">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-target="row2">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-target="row3">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr data-target="row4">
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</table>
</body>
I have to create a angular grid with last column frozen. The frozen column is the summation of all the row values. The last row is an editable one. My problem is how to create the HTML/CSS structure. I can create the angular grid but how to create the HTML/CSS structure is my question. Attached is the screen shot of the grid required.
Any pointers very helpful.
Thanks
Here is the solution I came up with : http://jsfiddle.net/anirbankundu/DJqPf/1881/
I implemented using 2 ways - I have indicated in the fiddle which is a more favorable way to implement. Hope that helps
HTML :
<div id="left">
<h4>Left Col</h4>
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
</table>
</div>
<div id="right" style="text-align:right;">
<h4>Right Col</h4>
<table>
<tr>
<td>1</td>
</tr>
<tr>
<td>1</td>
</tr>
</table>
</div>
</div>
</div>
CSS :
.table-wrapper {
overflow-x: scroll;
overflow-y: visible;
width: 250px;
}
td,
th {
padding: 5px 20px;
width: 100px;
}
th:first-child {
position: fixed;
right: 35%
}
#container {
display: table;
width: 100%;
border: 1px solid red;
}
#row {
display: table-row;
}
#left,
#right,
#middle {
display: table-cell;
border: 1px solid green;
}
#left {
width: 80%;
max-width: 350px;
overflow-x: scroll;
}