can anyone give me an idea of how to approach the attached grid/table layout using bootstrap4 flex/grid (must be responsive)?
It's like a table with sticky first row and sticky first column as navigation items.
I tried using w- & h- but it's not responsive without media query. Would like to know the best solution on bootstrap4.
Thanks a lot! :)
(Pardon my English...)
Freeze First Row & First Column
However, to get this behavior for both first row and first column, you need to separate the first row, first column, and first cell from the table, and then continuously set the position of these elements based on the scrolled position of the table body, upon a scroll event.
$(document).ready(function() {
$('tbody').scroll(function(e) {
$('thead').css("left", -$("tbody").scrollLeft());
$('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()-5);
$('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()-5);
});
});
body {
margin: 0;
}
th, td {
text-align: center;
background-color: white
}
table {
position: relative;
width: 400px;
overflow: hidden;
}
thead {
position: relative;
display: block;
width: 400px;
overflow: visible;
}
thead th {
min-width: 80px;
height: 40px;
}
thead th:nth-child(1) {
position: relative;
display: block;
height: 40px;
padding-top: 20px;
}
tbody {
position: relative;
display: block;
width: 400px;
height: 90px;
overflow: scroll;
}
tbody td {
min-width: 80px;
}
tbody tr td:nth-child(1) {
position: relative;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Tanggal</th>
<th>Judul Pekerjaan</th>
<th>Deskripsi</th>
<th>Level</th>
<th>Category</th>
<th>Severity</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1 May 2017</td>
<td>Satu</td>
<td>Satu</td>
<td>5</td>
<td>Lorem</td>
<td>Ipsum</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
</tbody>
</table>
Related
As I am a beginner in designing and have not much idea about CSS manipulating so need some help.
I have one HTML page and want to implement the same functionality of freeze as we are using in Word.
Here I am having the table and want to freeze the first 4 columns so it doesn't move and stay sticky and the last column to show the total and only allow in between columns to move with scrolling bar.
NOTE: The table is dynamic and rows and columns will be dynamic. Here is my code [https://jsfiddle.net/padhiyarmahavirsinh/b51k20sr/3/][2]
The basic idea is to make two tables, give one a fixed height and add a scroll bar. You're gonna have to tweak it for your site
//not part of styling, just to get the total
const total = document.querySelector("table:last-of-type tr td:last-child");
const money = document.querySelectorAll("table:first-of-type tr td:last-child");
let sum = 0;
money.forEach(({
innerText
}) => {
sum += parseInt(innerText);
});
total.innerText = sum;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
table {
border-collapse: collapse;
width: 125px;
display: flex;
overflow: hidden;
}
table:first-of-type {
height: 150px;
overflow-y: scroll;
}
td,
th {
border: 1px solid grey;
text-align: center;
}
td {
height: 40px;
width: 50px;
}
<table>
<tr>
<th>name</th>
<th>money</th>
</tr>
<tr>
<td>a</td>
<td>7923</td>
</tr>
<tr>
<td>b</td>
<td>7981</td>
</tr>
<tr>
<td>c</td>
<td>3724</td>
</tr>
<tr>
<td>d</td>
<td>4234</td>
</tr>
<tr>
<td>e</td>
<td>12939</td>
</tr>
<tr>
<td>f</td>
<td>3247</td>
</tr>
<tr>
<td>g</td>
<td>5798</td>
</tr>
<tr>
<td>h</td>
<td>5324</td>
</tr>
</table>
<table>
<tr>
<td>total</td>
<td>0</td>
</tr>
</table>
This question already has answers here:
Hide scrollbar (with scroll enabled)
(2 answers)
Closed 2 years ago.
I created a table which has a container that has a specific max height. I want to keep the scroll functionality for the overflowing table, but hide the scrollbar itself.
I tried some solutions that are present on the internet, but couldn't make this work.
HTML:
<div id="container">
<table id="codexpl">
<tr>
<th>#</th>
<th>Columna</th>
<th>Relative</th>
<th>Isso</th>
</tr>
<tr>
<td>1</td>
<td>This</td>
<td>Column</td>
<td>Is</td>
</tr>
<tr>
<td>2</td>
<td>Coloumn</td>
<td>two</td>
<td>this</td>
</tr>
<tr>
<td>3</td>
<td>is</td>
<td>not equals</td>
<td>a</td>
</tr>
<tr>
<td>4</td>
<td>the</td>
<td>Column</td>
<td>real</td>
</tr>
<tr>
<td>5</td>
<td>first</td>
<td>One</td>
<td>Coloumn</td>
</tr>
</table>
</div>
CSS:
#codexpl th, #codexpl td{
padding:0.8em;
border: 1px solid;
}
#codexpl th{
background-color:#6699FF;
font-weight:bold;
}
#container {
max-height:200px;
overflow:auto;
}
This is the jsfiddle I created to play with:
http://jsfiddle.net/k6rp1vsh/
Edit:
The browser where the website needs to run in is Opera version 11 which does not support the newest features!
Thanks in advance!
See the snippet. Let me know if you have any doubt.
#codexpl th, #codexpl td{
padding:0.8em;
border: 1px solid;
}
#codexpl th{
background-color:#6699FF;
font-weight:bold;
}
#container {
width: 100%;
overflow: hidden;
max-height: unset;
}
table#codexpl {
display: block;
width: 105%;
max-height: 200px;
overflow: auto;
}
<div id="container">
<table id="codexpl">
<tr>
<th>#</th>
<th>Columna</th>
<th>Relative</th>
<th>Isso</th>
</tr>
<tr>
<td>1</td>
<td>This</td>
<td>Column</td>
<td>Is</td>
</tr>
<tr>
<td>2</td>
<td>Column</td>
<td>two</td>
<td>this</td>
</tr>
<tr>
<td>3</td>
<td>is</td>
<td>not equals</td>
<td>a</td>
</tr>
<tr>
<td>4</td>
<td>the</td>
<td>Column</td>
<td>real</td>
</tr>
<tr>
<td>5</td>
<td>first</td>
<td>One</td>
<td>Column</td>
</tr>
</table>
</div>
add this in the css file
::-webkit-scrollbar {
display: none;
}
All you need to do is to set the scrollbar width to 0
#container::-webkit-scrollbar {
width: 0px;
}
Try this
::-webkit-scrollbar ::-webkit-scrollbar-track ::-webkit-scrollbar-thumb {
display: none;
}
You can achieve it easily using CSS.
To hide the scrollbars, but still be able to keep scrolling, you can use the following code:
/* Hide scrollbar for Chrome, Safari and Opera */
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE and Edge */
.hide-scrollbar {
-ms-overflow-style: none;
}
I've created this fiddle for you: http://jsfiddle.net/u105fbx4/
Add class="hide-scrollbar" to your DIV , like this.
HTML
<div id="container" class="hide-scrollbar">
and this to the end of CSS FILE:
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
.hide-scrollbar {
-ms-overflow-style: none;
}
This is my web template. I want to freeze the header part and also the "#" and "Rank" columns. Vertical scrolling should scroll through the rows only and horizontal scrolling should scroll through Header3 onwards.
| # | Rank | Header3 | Header4 | Header5 | Header6 |
[] | #1 | Rank1 |
[] | #2 | Rank2 |
[] | #3 | Rank3 |
[] | #4 | Rank4 |
[] | #5 | Rank5 |
[] | #6 | Rank6 |
I would think there should be separate tags with different css styles. One of which the headers css style should contain position:fixed.
<div class="form-horizontal table-responsive table-masterinput">
<table class="table table-hover table-bordered table-striped" id="whatever">
<thead>
<tr>
<th></th>
<th class="text-center">#</th>
<th class="text-center">Rank</th>
<th class="text-center">Header3</th>
<th class="text-center">Header4</th>
<th class="text-center">Header5</th>
<th class="text-center">Header6</th>
</tr>
</thead>
<tbody>
#{
var index = 1;
if (Model != null && Model.Any())
{
foreach (var items in Model)
{
total += 1;
<tr class="checkCountData" id=#("item" + index)>
<td>
<input type="checkbox" name="#items.Id" id="#items.Id" />
</td>
<td>
<label data-Id="#items.Id" style="width: 100px; text-align: center" class="inputRank" name="inputRank">#items.RANK_CODE</label>
</td>
<td>Item3</td>
<td>Item4</td>
<td>Item5</td>
<td>Item6</td>
</tr>
index++;
}
}
}
</tbody>
</table>
This is my css:
.table-masterinput {
overflow-x: auto;
height: auto;
bottom: 0px;
top: 300px;
right: 0px;
left: 180px;
position: fixed;
}
Can someone please help?
try this with jquery and css or try this fiddle check here
$(document).ready(function() {
$('tbody').scroll(function(e) { //detect a scroll event on the tbody
/*
Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement
of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain it's relative position at the left of the table.
*/
$('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling
$('thead th:nth-child(1), thead th:nth-child(2)').css("left", $("tbody").scrollLeft()); //fix the first cell of the header
$('tbody td:nth-child(1), tbody td:nth-child(2)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody
});
});
table {
position: relative;
width: 700px;
background-color: #aaa;
overflow: hidden;
border-collapse: collapse;
}
/*thead*/
thead {
position: relative;
display: block; /*seperates the header from the body allowing it to be positioned*/
width: 700px;
overflow: visible;
}
thead th {
background-color: #99a;
min-width: 120px;
height: 32px;
border: 1px solid #222;
}
thead th:nth-child(1) {/*first cell in the header*/
position: relative;
display: block; /*seperates the first cell in the header from the header*/
background-color: #88b;
}
thead th:nth-child(2) {/*first cell in the header*/
position: relative;
background-color: #88b;
}
/*tbody*/
tbody {
position: relative;
display: block; /*seperates the tbody from the header*/
width: 700px;
height: 239px;
overflow: scroll;
}
tbody td {
background-color: #bbc;
min-width: 120px;
border: 1px solid #222;
}
tbody tr td:nth-child(1) { /*the first cell in each tr*/
position: relative;
display: block; /*seperates the first column from the tbody*/
height: 40px;
background-color: #99a;
}
tbody tr td:nth-child(2) { /*the first cell in each tr*/
position: relative;
height: 40px;
background-color: #99a;
}
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<table>
<thead>
<tr>
<th>#</th>
<th>Rank</th>
<th>Header1</th>
<th>Header2</th>
<th>Header3</th>
<th>Header4</th>
<th>Header5</th>
<th>Header6</th>
</tr>
</thead>
<tbody>
<tr>
<td>#1</td>
<td>Rank1</td>
<td>Cheshire</td>
<td>52</td>
<td>Brewer</td>
<td>£47,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>#2</td>
<td>Rank2</td>
<td>Cumbria</td>
<td>34</td>
<td>Shepherdess</td>
<td>£28,000</td>
<td>Single</td>
<td>0</td>
</tr>
<tr>
<td>#3</td>
<td>Rank3</td>
<td>Wiltshire</td>
<td>57</td>
<td>Musician</td>
<td>£124,000</td>
<td>Married</td>
<td>4</td>
</tr>
<tr>
<td>#4</td>
<td>Rank4</td>
<td>Worchestershire</td>
<td>48</td>
<td>Naturalist</td>
<td>£65,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>#5</td>
<td>Rank5</td>
<td>Hertfordshire</td>
<td>67</td>
<td>Pharmasist</td>
<td>Retired</td>
<td>Married</td>
<td>3</td>
</tr>
<tr>
<td>#6</td>
<td>Rank6</td>
<td>Lothian </td>
<td>36</td>
<td>Vigilante</td>
<td>£86,000</td>
<td>Single</td>
<td>Unknown</td>
</tr>
<tr>
<td>#7</td>
<td>Rank7</td>
<td>Bedfordshire</td>
<td>43</td>
<td>Housewife</td>
<td>N/A</td>
<td>Married</td>
<td>1</td>
</tr>
<tr>
<td>#8</td>
<td>Rank8</td>
<td>New York</td>
<td>55</td>
<td>Policewoman</td>
<td>$36,000</td>
<td>Single</td>
<td>1</td>
</tr>
<tr>
<td>#9</td>
<td>Rank9</td>
<td>Lincolnshire</td>
<td>45</td>
<td>Landowner</td>
<td>Lots</td>
<td>Married</td>
<td>6</td>
</tr>
<tr>
<td>#10</td>
<td>Rank10</td>
<td>Cheshire</td>
<td>352</td>
<td>Arcanist</td>
<td>A pile of gems</td>
<td>Single</td>
<td>0</td>
</tr>
</tbody>
</table>
</body>
</html>
Currently, I have a table in my page and I am trying to make the first column freeze. The freeze column works fine using position: fixed for that particular column.
However there is another problem. When the content has more than one row, the <tr> doesn't extend its height based on its content. Therefore, is there any solution for this?
Here is my demo:
https://jsfiddle.net/yusrilmaulidanraji/ckfdubsf/121/
#table-wrapper {
width: 95%;
float: left;
overflow-x: scroll;
background: #ddd;
}
table {
background: #fff;
width: 1200px;
text-align: center;
overflow: hidden;
position: relative;
}
table thead tr th {
width: 15em;
}
table thead tr th:first-child,
table tbody tr td:first-child {
top: auto;
left: 0.5;
position: fixed;
width: 6em;
}
table thead tr th:nth-child(2),
table tbody tr td:nth-child(2) {
padding-left: 7em;
/*to show second column behind the first*/
}
<button id="left">←</button>
<button id="right">→</button>
<div id="table-wrapper">
<table border="1">
<thead>
<tr>
<th>Heading1</th>
<th>Heading2</th>
<th>Heading3</th>
<th>Heading4</th>
<th>Heading5</th>
</tr>
</thead>
<tbody>
<tr>
<td>1<br/>asdasdada</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<td>2<br/>asdasdada<br/>asdasdada</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
</tr>
<tr>
<td>3<br/>asdasdada</td>
<td>32</td>
<td>33</td>
<td>34</td>
<td>35</td>
</tr>
<tr>
<td>4<br/>asdasdada<br/>asdasdada<br/>asdasdada<br/>asdasdada<br/>asdasdada</td>
<td>42</td>
<td>43</td>
<td>44</td>
<td>45</td>
</tr>
<tr>
<td>5<br/>asdasdada</td>
<td>52</td>
<td>53</td>
<td>54</td>
<td>55</td>
</tr>
</tbody>
</table>
</div>
You can go through all td fixed elements and then set those heights to default td elements.
$('table tbody tr td:first-child').each(function(){
var height = $(this).height();
$(this).parent().find('td').height(height);
});
Working example https://jsfiddle.net/ckfdubsf/122/
I ended up by using #feesar answer, however I had another issue regarding performance. Therefore, Here is the final result for my case:
https://jsfiddle.net/yusrilmaulidanraji/ckfdubsf/124/
// Adjust the th and td's height.
// Improve the performance by using native js + for loop.
var firstHeader = $('#table-wrapper th:first-child');
firstHeader[0].style.height = firstHeader[0].parentNode.offsetHeight + "px";
var firstColumn = $('#table-wrapper td:first-child');
for (var i = 0; i < firstColumn.length; i++) {
firstColumn[i].parentNode.style.height = firstColumn[i].offsetHeight + "px";
}
The logic and the result are the same, but it has a better performance. Hopefully, it can help.
In terms of performance, I think you will be best off simply cloning the first table column and painting it above the "real" one, like this:
var $overlayTable = $("#table-wrapper table").clone().addClass("overlay");
$overlayTable.find("tr > *:not(:first-child)").remove();
$overlayTable.appendTo("#table-wrapper");
$(window).on("scroll", function () {
$overlayTable.css("left", $(window).scrollLeft() + "px");
});
#table-wrapper {
position: relative;
}
#table-wrapper table {
text-align: center;
table-layout: fixed;
overflow-x: scroll;
width: 1200px;
border-collapse: collapse;
}
#table-wrapper table tr > * {
margin-left: 150px;
width: auto;
}
#table-wrapper table tr > *:first-child {
width: 6em;
}
#table-wrapper table.overlay {
position: absolute;
top: 0;
color: red;
background-color: white;
width: 6em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<button id="left">←</button>
<button id="right">→</button>
</p>
<div id="table-wrapper">
<table border="1">
<thead>
<tr>
<th>Heading1</th>
<th>Heading2</th>
<th>Heading3</th>
<th>Heading4</th>
<th>Heading5</th>
</tr>
</thead>
<tbody>
<tr>
<td>1<br/>asdasdada</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<td>2<br/>asdasdada<br/>asdasdada</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
</tr>
<tr>
<td>3<br/>asdasdada</td>
<td>32</td>
<td>33</td>
<td>34</td>
<td>35</td>
</tr>
<tr>
<td>4<br/>asdasdada<br/>asdasdada<br/>asdasdada<br/>asdasdada<br/>asdasdada</td>
<td>42</td>
<td>43</td>
<td>44</td>
<td>45</td>
</tr>
<tr>
<td>5<br/>asdasdada</td>
<td>52</td>
<td>53</td>
<td>54</td>
<td>55</td>
</tr>
</tbody>
</table>
</div>
I have a code to display the content of table as scrollable. But i am not sure on how to do scroll only on body not with head. Currently it happening for whole table.
Please help me.
tbody {
display: block;
}
tbody {
height: 300px;
/* Just for the demo */
overflow-y: auto;
/* Trigger vertical scroll */
overflow-x: hidden;
/* Hide the horizontal scroll */
}
<table cellspacing="0" id="itemtable" align="center">
<tr>
<th> SLno</th>
<th>Item name</th>
<th>Item code</th>
</tr>
<tr>
<td>1</td>
<td>icecream</td>
<td>100</td>
</tr>
<tr>
<td>2</td>
<td>biscuits</td>
<td>200</td>
</tr>
</table>
First of all you need your thead of the table to be separate from the rest of your table by either applying position: relative; or absolute.
Apply display: block to your tbody so that you have a block level element which you can then apply height and overflow properties to have a desirable scrollable table.
Refer code:
table {
position: relative;
width: 700px;
background-color: #aaa;
overflow: hidden;
border-collapse: collapse;
}
/*thead*/
thead {
position: relative;
display: block;
/*seperates the header from the body allowing it to be positioned*/
width: 700px;
overflow: visible;
}
thead th {
background-color: #99a;
min-width: 120px;
height: 36px;
min-height: 36px;
border: 1px solid #222;
}
thead th:nth-child(1) {
/*first cell in the header*/
position: relative;
display: block;
background-color: #88b;
}
/*tbody*/
tbody {
display: block;
width: 700px;
height: 239px;
overflow-y: auto;
}
tbody td {
background-color: #bbc;
min-width: 120px;
border: 1px solid #222;
height: 36px;
min-height: 36px;
}
<body>
<table>
<thead>
<tr>
<th>Name</th>
<th>Town</th>
<th>County</th>
<th>Age</th>
<th>Profession</th>
<th>Anual Income</th>
<th>Matital Status</th>
<th>Children</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Smith</td>
<td>Macelsfield</td>
<td>Cheshire</td>
<td>52</td>
<td>Brewer</td>
<td>£47,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>Jenny Jones</td>
<td>Threlkeld</td>
<td>Cumbria</td>
<td>34</td>
<td>Shepherdess</td>
<td>£28,000</td>
<td>Single</td>
<td>0</td>
</tr>
<tr>
<td>Peter Frampton</td>
<td>Avebury</td>
<td>Wiltshire</td>
<td>57</td>
<td>Musician</td>
<td>£124,000</td>
<td>Married</td>
<td>4</td>
</tr>
<tr>
<td>Simon King</td>
<td>Malvern</td>
<td>Worchestershire</td>
<td>48</td>
<td>Naturalist</td>
<td>£65,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>Lucy Diamond</td>
<td>St Albans</td>
<td>Hertfordshire</td>
<td>67</td>
<td>Pharmasist</td>
<td>Retired</td>
<td>Married</td>
<td>3</td>
</tr>
<tr>
<td>Austin Stevenson</td>
<td>Edinburgh</td>
<td>Lothian</td>
<td>36</td>
<td>Vigilante</td>
<td>£86,000</td>
<td>Single</td>
<td>Unknown</td>
</tr>
<tr>
<td>Wilma Rubble</td>
<td>Bedford</td>
<td>Bedfordshire</td>
<td>43</td>
<td>Housewife</td>
<td>N/A</td>
<td>Married</td>
<td>1</td>
</tr>
<tr>
<td>Kat Dibble</td>
<td>Manhattan</td>
<td>New York</td>
<td>55</td>
<td>Policewoman</td>
<td>$36,000</td>
<td>Single</td>
<td>1</td>
</tr>
<tr>
<td>Henry Bolingbroke</td>
<td>Bolingbroke</td>
<td>Lincolnshire</td>
<td>45</td>
<td>Landowner</td>
<td>Lots</td>
<td>Married</td>
<td>6</td>
</tr>
<tr>
<td>Alan Brisingamen</td>
<td>Alderley</td>
<td>Cheshire</td>
<td>352</td>
<td>Arcanist</td>
<td>A pile of gems</td>
<td>Single</td>
<td>0</td>
</tr>
</tbody>
</table>
</body>