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>
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 html code that defines a table, like this:
<table>
<th>
<td style="width:200px">
col1
</td>
</th>
<tr>
<td id="a1">
text1
</td>
</tr>
</table>
I like to draw a rectangle right of "text1", i.e. into the cell #a1, with a custom width (e.g. 40px) and a fixed offset (e.g. 100px) from the left side of the cell, using only CSS, so that it appears like this:
text1 XXXX
(XXXX is meant to be the filled rectangle)
I have no control over the html, i.e. I cannot change it, so please don't suggest that. No JS, either.
It is important that the css does not alter the appearance and positioning of the text.
Is that doable with CSS?
Use a background:
#a1 {
background:
linear-gradient(red, red)
left 100px top 50%
/
40px 10px /*width height (use 100% instead of 10px for full height)*/
no-repeat;
}
<table>
<tr>
<th style="width:200px">
col1
</th>
</tr>
<tr>
<td id="a1">
text1
</td>
</tr>
</table>
Use ::after pseudo-element. outline is added to show the 100px offset; clearly, it's not required.
#a1 {
outline: red 1px solid
}
#a1::after {
content: '\a0';
display: inline-block;
width: 40px;
background: #000;
transform: translateX(50px)
}
<table>
<tr>
<th style="width:200px">
col1
</th>
</tr>
<tr>
<td id="a1">
text1
</td>
</tr>
</table>
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/
I [unfortunately] have a table inside of a table. The last <td> of the outer table looks like so:
<td class="valign-top width-40 padding-right-4px">
<div class="grid-filter-container" style="overflow:auto;">
<table id="FilterColumns" class="fullwidth fimscaletable">
<thead>
<tr>
<th class="width-25 textalign-left k-header k-grid-header">
<span class="text-white">Field Name</span>
</th>
<th class="width-75 textalign-center k-header k-grid-header">
<span class="text-white">Condition</span>
</th>
</tr>
</thead>
<tbody></tbody>
<tbody></tbody>
</table>
</div>
</td>
The inner table programatically gets rows added to it, it's part of a data exporting module. The user is presented with a list of fields on the left, and then they can select it from the list and set some parameters and add it to this table on the right.
As you can see, the <div> containing the inner table has its overflow property set to auto. But during run time it only "gains" a horizontal scrollbar:
The table on the right started as the same size as the control on the left, but as I add more conditions to it, it grows in height. I want it to instead just scroll the div. Note this screenshot was taken in IE; haven't tested other browsers yet.
The grid-filter-container class is defined as so:
.k-window .grid-filter-container {
border: solid 1px #909090;
min-height: 200px;
padding: 0px;
margin: 0px;
}
js fiddle is actually blocked by my company's internet filters, otherwise I'd try to provide a sample.
Add height to the container
.k-window .grid-filter-container {
border: solid 1px #909090;
min-height: 200px;
padding: 0px;
margin: 0px;
height: 200px;
}