To make part of the table scrollable I'm using a div inside of the table but getting the warning:
Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody>
I understand the warning, but I would like part of the table (most of it) to be scrollable, thus limiting the maxheight of part of the table:
<div className="main-table">
<table className="main-edit-table" align="right">
<tbody>
<tr>
<th>haveri</th>
</tr>
<div className="inst-container">
{this.state.list && this.state.list.map((collection, key) => (
<tr key={key}>
<td>{key+1}</td>
<td>
<div className="main-item-container">
<span>{collection}</span>
</div>
</td>
<td>{collection.subjects[0] && collection.subjects[0].name}</td>
</tr>
))}
</div>
</tbody>
</table>
</div>
CSS:
.inst-container {
border: 1px solid #eeccee;
max-height: 300px;
overflow-y: scroll;
width: 100%;
}
All I'm doing is inserting a div inside the table, after its headings, to make the table itself scrollable.
Two questions:
Is the warning "that bad"? I mean, I get the warning but it's working fine
What would you do to create the heading (which can contain a few columns) and a scrollable table underneath? Is using grid system the only option?
I would rather wrap the whole table inside a div container with the overflow and set the column headers to sticky position.
See below:
<div className="container">
<table className="main-edit-table" align="right">
<thead>
<tr>
<th className="sticky-column">haveri</th>
</tr>
</thead>
<tbody>
{this.state.list && this.state.list.map((collection, key) => (
<tr key={key}>
<td>{key+1}</td>
<td>
<div className="main-item-container">
<span>{collection}</span>
</div>
</td>
<td>{collection.subjects[0] &&
collection.subjects[0].name}</td>
</tr>
))}
</tbody>
</table>
</div>
CSS:
.sticky-column {
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0
}
.container {
border: 1px solid #eeccee;
max-height: 300px;
overflow-y: scroll;
width: 100%;
}
Have a look at the CodeSandBox sample: https://xyv5nl.csb.app/
Related
I have a table with two columns. One has some property names and the other has descriptions, including pre tags. I need the pre tags to not wrap and instead scroll to see overflow. I also need the first column to be sized based on the largest property name. I can't get the two to play nicely with each other.
For example I can get the first column to size based on the content but the pre won't scroll:
.main-content {
max-width: 800px;
border: 1px solid red;
}
pre {
overflow: auto;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</td>
</tr>
</tbody>
</table>
</div>
I can also get the pre to scroll but then I can't get the first column to resize:
.main-content {
max-width: 800px;
border: 1px solid red;
}
table {
table-layout: fixed;
width: 100%;
}
th:first-of-type {
width: 15%; /* Faking it here - the size of the first td/th should be based on the largest */
}
pre {
overflow: auto;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</td>
</tr>
</tbody>
</table>
</div>
Any ideas how I can get both working while retaining a table layout? I know how to do it with other methods like grid and flexbox, that's not what I'm asking about.
You can consisder width:0;min-width:100%; trick on the pre. The idea is that the width:0 will disable the contribution of pre on defining the width of the container then min-width:100% will force it to fill all the space:
.main-content {
max-width: 800px;
border: 1px solid red;
}
th:first-of-type {
white-space:nowrap;
}
pre {
overflow: auto;
width:0;
min-width:100%;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</td>
</tr>
</tbody>
</table>
</div>
Related question: How to match width of text to width of dynamically sized image?
The only way I can see to do this is to wrap your <pre> in a <div> with overflow: auto and set the cell to display: grid
.main-content {
max-width: 800px;
border: 1px solid red;
}
table {
table-layout: auto;
width: 100%;
}
.config-name {
white-space: nowrap;
}
.config-description {
display: grid;
}
.config-description div {
overflow: auto;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<div>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</div>
</td>
</tr>
<tr>
<td class="config-name">longer property name</td>
<td class="config-description">
<p>Just another description, this one without a <pre></p>
</td>
</tr>
</tbody>
</table>
</div>
I have a table with two columns. One has some property names and the other has descriptions, including pre tags. I need the pre tags to not wrap and instead scroll to see overflow. I also need the first column to be sized based on the largest property name. I can't get the two to play nicely with each other.
For example I can get the first column to size based on the content but the pre won't scroll:
.main-content {
max-width: 800px;
border: 1px solid red;
}
pre {
overflow: auto;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</td>
</tr>
</tbody>
</table>
</div>
I can also get the pre to scroll but then I can't get the first column to resize:
.main-content {
max-width: 800px;
border: 1px solid red;
}
table {
table-layout: fixed;
width: 100%;
}
th:first-of-type {
width: 15%; /* Faking it here - the size of the first td/th should be based on the largest */
}
pre {
overflow: auto;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</td>
</tr>
</tbody>
</table>
</div>
Any ideas how I can get both working while retaining a table layout? I know how to do it with other methods like grid and flexbox, that's not what I'm asking about.
You can consisder width:0;min-width:100%; trick on the pre. The idea is that the width:0 will disable the contribution of pre on defining the width of the container then min-width:100% will force it to fill all the space:
.main-content {
max-width: 800px;
border: 1px solid red;
}
th:first-of-type {
white-space:nowrap;
}
pre {
overflow: auto;
width:0;
min-width:100%;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</td>
</tr>
</tbody>
</table>
</div>
Related question: How to match width of text to width of dynamically sized image?
The only way I can see to do this is to wrap your <pre> in a <div> with overflow: auto and set the cell to display: grid
.main-content {
max-width: 800px;
border: 1px solid red;
}
table {
table-layout: auto;
width: 100%;
}
.config-name {
white-space: nowrap;
}
.config-description {
display: grid;
}
.config-description div {
overflow: auto;
}
<div class="main-content">
<table border="0" class="config">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="config-name">name</td>
<td class="config-description">
<p>Foo bar talking about some random things related to our code here in the paragraph:</p>
<div>
<pre>// some really long code section here that should have its own scroll bar (and not wrap) some really long code section here that should have its own scroll bar (and not wrap)</pre>
</div>
</td>
</tr>
<tr>
<td class="config-name">longer property name</td>
<td class="config-description">
<p>Just another description, this one without a <pre></p>
</td>
</tr>
</tbody>
</table>
</div>
I have a table with a lot of information in the header columns, and there are a lot of columns. I need the table width to fit into reasonable laptop widths such as 1280.
My original idea was to align the column content vertically, but that's not an option for several reasons.
So now the idea is to display only part of the content in the header, something along the lines of overflow:hidden, and show full content on hover, but without altering the width of the column.
This sample picture shows the column content how it looks like now - and how I need it to look like. The columns need to shrink to 50px, hiding text that did not fit, and show the rest of the text on hover, but without expanding the column width.
This is what I got so far:
https://jsfiddle.net/2em3c44q/
here, the column expands on hover. How do i expand only header without expanding the entire column?
On hover position the internal div absolutely, and it won't change the dimensions of the table column:
table {
width: 100%;
}
th,
td {
border-right: 1px solid grey;
}
.narrow {
position: relative; /* the context by which to position the inner div */
width: 50px;
}
.narrow div {
width: 50px;
overflow: hidden;
white-space: nowrap;
pointer-events: none; /* optional - enables hovering on other headers, when the current one is expanded */
}
.narrow:hover div { /* the hover is on narrow */
position: absolute;
top: 5px;
left: -75px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
width: 200px;
background: white;
z-index: 1;
}
<table>
<thead>
<tr>
<th class="wide">
wide column
</th>
<th class="narrow">
<div>
column 1<br/> some info
</div>
</th>
<th class="narrow">
<div>
column 1<br/> some info
</div>
</th>
<th class="narrow">
<div>
column 1<br/> some info
</div>
</th>
<th class="narrow">
<div>
column 1<br/> some info
</div>
</th>
<th class="narrow">
<div>
column 1<br/> some info
</div>
</th>
<th class="narrow">
<div>
column 1<br/> some info
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
</tr>
</tbody>
</table>
I read http://getbootstrap.com/css/#tables which didn't mention resizing tds in any specific way, so I tried the following css:
.cbCell {
width: 25px;
}
.smallerCell {
width: 240px;
}
.textfield {
width: 230px;
}
with this html
<thead>
<tr>
<th class="cbCell"><input type='checkbox' class='form-control' id='selectall'></th>
<th class="text-center smallerCell">Employee Name</th>
<th class="text-center smallerCell">Mail</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td class="cbCell"><input type='checkbox' class='form-control case'></td>
<td class="smallerCell"><input type="text" name='name0' placeholder='Name' class="form-control textfield"/></td>
<td class="smallerCell"><input type="text" name='mail0' placeholder='Mail' class="form-control textfield"/></td>
</tr>
<tr id='addr1'>
</tr>
</tbody>
The textfields have been resized but the td has not, the 'smallerCell' style isn't applied
I tried Change column width bootstrap tables which didn't work for me. I used the grid system to float the establishment info to the right, I ultimately want the name and mail columns to fit the smaller textfield size, and for there to be a margin and vertical rule dividing the People and Establishment columns.
Change table width to auto. In boot strap table width is set to 100%
.table {
width: 100%;
margin-bottom: 20px;
}
so make it
.table {
width: auto;
}
in you css.
I'm having trouble getting my table to behave. The content keeps overflowing and my attempts to restrict it are not producing the desired effect.
This is my markup:
<div class="repeatingdiv">
<div class="hastitle">Some title</div>
<div class="hastable">
<table>
<thead><tr><th></th></tr></thead>
<tfoot><tr><th></th></tr></tfoot>
<tbody>
<tr>
<td class="col1">Col 1</td>
<td class="col2">Col 2</td>
<td class="col3">Col 3</td>
</tr>
</tbody>
</table>
</div>
</div>
I then have some style. The td's are overflowing, but I didn't have any luck setting their overflow to hidden/auto. I did have better luck setting overflow in the hastable class that contains the table. But I'm still having trouble getting Firefox to respect the width distribution for the 3 columns: 30%, 35%, 35%. I also tried setting min-width, but still no luck. I have several of these tables on the page, and each one takes its own width. Any help with this table mess?
.repeatingdiv { }
.hastitle { margin:0 10px; padding:3px 3px 1px 6px; }
.hastable { overflow:hidden;
text-overflow: ellipsis;
margin:10px;
padding:10px;
}
table { }
table tbody { width: 100%; }
tr { width: 100%; }
td.col1 { width:30%; min-width:30%; }
td.col2 { width:35%; min-width:35%; }
td.col3 { width:35%; min-width:35%; }
Tables are notoriously difficult to style. Try adding this to your CSS:
table { table-layout: fixed; width: 100% /* or whatever fixed width */; }
I'd also suggest using actual HTML COL / COLGROUP elements to define your columns, as so:
<table>
<colgroup class="col1" />
<colgroup class="col2" />
<colgroup class="col3" />
<thead><tr><th></th></tr></thead>
<tfoot><tr><th></th></tr></tfoot>
<tbody>
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
</tbody>
</table>
Do take note that, despite this, cells with overflowing data will force the containing cell, row, and table to expand to fit. CSS overflow: auto / hidden / scroll do not affect cells.
Ref:
CSS: Table Layout,
HTML: COLGROUP
Wrap your table in a div and set overflow for the div.
<div style='overflow:scroll;'>
<table>
...
</table>
</div>