This question already has answers here:
Table cell width is ignored depending on input width set on unrelated row
(1 answer)
Table cell element ignoring width in CSS
(4 answers)
Why is my HTML table not respecting my CSS column width?
(10 answers)
Closed 3 months ago.
I was just going through this Github doc when I noticed the table was hard to read and started poking around the CSS to make it more eye appealing.
However, I realised that the td elements in the table were not respecting any width properties that I set. To reproduce the issue, I created this codepen. The styles in the codepen are from the Github docs.
The codepen has 2 tables: one whose contents contain a pre and a code tag and another which contains plain text. I have added an additional style in my codepen for all td elements: width: 50%. The first table does not respect this style while the second one does. Can anyone tell me why? Also, is there any explanation to why all the cells in the first table are affected and do not respect the width when only one cell has the pre and code tags?
Edit: Here's a code sample:
:root {
--color-border-muted: #21262d;
--color-canvas-default: #0d1117;
--color-fg-default: #c9d1d9;
--color-canvas-subtle: #161b22;
--color-border-default: #30363d;
}
body {
/* Styles from Githun docs */
color-scheme: dark;
}
* {
box-sizing: border-box;
}
table {
/* Styles from Githun docs */
display: table;
border-collapse: collapse;
position: relative;
font-size: 90%;
width: 100%;
line-height: 1.5;
table-layout: auto;
word-wrap: break-word;
color: var(--color-fg-default);
}
table tr {
/* Styles from Githun docs */
background-color: var(--color-canvas-default);
border-top: 1px solid var(--color-border-muted);
}
td {
/* STYLE THAT MARKS THAT CELL WIDTH SHOULD ONLY BE 50% */
width: 50%;
border: 1px solid var(--color-border-muted);
padding: 0.5rem;
}
pre {
/* Styles from Githun docs */
padding: 16px;
overflow: auto;
line-height: 1.45;
background-color: var(--color-canvas-subtle);
border-radius: 6px;
margin-top: .5rem;
border: 1px solid var(--color-border-default);
word-wrap: normal;
}
<table>
<tbody>
<tr>
<td>Hello Margarita tula pera kola papaya. sdkjcnskdcn kjsdnckcnskdjnc k ckjdc ksdc kdjc kd ckd cksdj cjkd c sdk cskdjc kjd ckdj ckdjsc ksdjc kdjc dksc kdj c</td>
<td>World</td>
</tr>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
</tbody>
</table>
<br />
<table>
<tbody>
<tr>
<td>Hello Margarita tula pera kola papaya. sdkjcnskdcn kjsdnckcnskdjnc k ckjdc ksdc kdjc kd ckd cksdj cjkd c sdk cskdjc kjd ckdj ckdjsc ksdjc kdjc dksc kdj c</td>
<td>World</td>
</tr>
<tr>
<td><pre><code class="hljs language-yaml"><span class="hljs-attr">run-name:</span> <span class="hljs-string">${{</span> <span class="hljs-string">github.actor</span> <span class="hljs-string">}}</span> <span class="hljs-string">is</span> <span class="hljs-string">learning</span> <span class="hljs-string">GitHub</span> <span class="hljs-string">Actions</span> <span class="hljs-string">Actions</span> <span class="hljs-string">Actions</span> <span class="hljs-string">Actions</span> <span class="hljs-string">Actions</span> <span class="hljs-string">Actions</span></code></pre></td>
<td>World</td>
</tr>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
</tbody>
</table>
TLDR: In the codepen the table with pre and code tags in cells does not respect the width: 50% style set on cell elements (td). Why?
Credits: #CBroe
In the above CSS, there is one specific style that was responsible for the width not being respected:
table {
.
.
.
table-layout: auto;
.
.
}
As mentioned in the Mozilla docs, a value of auto to table-layout results as follows:
By default, most browsers use an automatic table layout algorithm. The widths of the table and its cells are adjusted to fit the content.
This means that in auto, the content decides the layout. As mentioned in w3schools:
Browsers use an automatic table layout algorithm. The column width is set by the widest unbreakable content in the cells. The content will dictate the layout
So, you can replace it with table-layout:fixed to set your own width.
Note: Simply removing the style table-layout: auto will not do since the browser uses it as the default style. A value of fixed needs to be explicitly passed.
My code is similar to as follows:
table,tr,td {
border-collapse:collapse;
border: 1px solid black;
}
label {
font-size: 0.7rem;
}
table {
table-layout: auto;
}
<table>
<tbody>
<tr>
<td>
<input>
</td>
</tr>
<tr>
<td>
<label>Foo bar</label>
</td>
</tr>
</tbody>
</table>
The issue occurs when the element on top is bigger than the element on the bottom. I know the solution seems obvious: use table-layout: auto; However, as you can see, that doesn't work.
There is no padding or margin, and the height is not set manually on either of them. My question is as follows: Why is the space there, and, more importantly, how can I remove it?
I feel really stupid now: it was just the line-height property. I set it lower and that fixed it.
Edit: A more simple solution suggested by VilleKoo is to set the display property of the <label> to block or flex (setting the padding to 0, which is mentioned in the comment, is not required)
I've already tried some of the solutions provided by this site but apparently, none of them worked for me. So I thought I'd post this as another question.
I have this table containing buttons which I've designed using CSS.
I did not set the table height and width so it should adjust itself according to its content. The problem is there's this 'gap' below the buttons, as seen from the image and I can't seem to find a way to remove this. I've also tried setting every cell height but it didn't work.
I have this for the button
.arrow
{
background-color:#78E9DE;
box-shadow: 0px 4px 0px 0px #45C3B8;
border-radius: 5px;
color: white;
border: none;
font-size: 30px;
};
and a simple html table
<table>
<tr>
<td></td>
<td>[up button here]</td>
<td></td>
</tr>
<tr>
<td>[left button here]</td>
<td></td>
<td>[right button here]</td>
</tr>
<tr>
<td></td>
<td>[down button here]</td>
<td></td>
</tr>
</table>
I want fit every cell with the content inside so it would look nice and easier to click. Please help thanks.
try this:
table {
border-collapse: collapse;
}
table,td {
padding: 0;
}
img {
display: inherit;
}
and here is the result :
I would like to create a table header row that includes a title on the left as well as "Sample header" on the right. For accessibility and to be semantically correct, the title should probably be in a <caption> tag, but "Sample header" isn't part of the title so it probably shouldn't be inside of <caption>. The caption can't be inside the row since it has to be the first element after <table>.
Here is the HTML structure:
<table>
<caption>Caption</caption>
<thead>
<tr class="sample">
<th colspan="2">Sample header</th>
</tr>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>
The caption ends up as a separate line above the table, while I would like it to be on the same line as "Sample header".
Here is a sample of what I'm trying to achieve: http://jsfiddle.net/vueLL5ce/5/. It sets 'caption`'s position to relative and manually moves it where I want. The two main problems with this approach is that repositioning the caption still leaves its original space above the table and I'm working with pixels which vary between browsers so it won't necessarily line up correctly.
Is there a good way of achieving this? Am I stuck with including the header info inside of <caption> (and styling to look like a table row) or creating a regular table row and not using <caption>?
Move background color from div to table and it should remove the color from the top for you. see attached fiddle here
table {
border: solid 1px Black;
width: 100%;
background-color: #FFFFDD;
}
I would remove the caption, use the column head and separate the two items with there own class then align them in your css. Updated the example here This way you don't have the spacing issue at all.
I think I found a cross-browser solution. The key is to set line-height: 0 (plain 0 doesn't work in IE6, but I don't need to support it). Firefox also wouldn't let me reposition the caption directly, so I had to add another span. I still don't like dealing with pixels directly, so any suggestions on that end would be great.
Fiddle: http://jsfiddle.net/vueLL5ce/8/
HTML:
<div>
<table>
<caption><span>Caption</span></caption>
<thead>
<tr class="captionRow">
<th colspan="2">Sample header</th>
</tr>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>
</div>
CSS:
div {
background-color: #FFFFDD;
}
table {
border: solid 1px Black;
width: 100%;
}
table caption {
line-height: 0;
text-align: left;
}
table caption span {
position: relative;
left: 4px;
top: 14px;
}
table th {
background-color: #CCC;
}
.captionRow th {
text-align: right;
}
I want to make an html table with the top row frozen (so when you scroll down vertically you can always see it).
Is there a clever way to make this happen without javascript?
Note that I do NOT need the left column frozen.
I know this has several answers, but none of these really helped me. I found this article which explains why my sticky wasn't operating as expected.
Basically, you cannot use position: sticky; on <thead> or <tr> elements. However, they can be used on <th>.
The minimum code I needed to make it work is as follows:
table {
text-align: left;
position: relative;
}
th {
background: white;
position: sticky;
top: 0;
}
With the table set to relative the <th> can be set to sticky, with the top at 0
NOTE: It's necessary to wrap the table with a div with max-height:
<div id="managerTable" >
...
</div>
where:
#managerTable {
max-height: 500px;
overflow: auto;
}
This is called Fixed Header Scrolling. There are a number of documented approaches:
http://www.imaputz.com/cssStuff/bigFourVersion.html
You won't effectively pull this off without JavaScript ... especially if you want cross browser support.
There are a number of gotchyas with any approach you take, especially concerning cross browser/version support.
Edit:
Even if it's not the header you want to fix, but the first row of data, the concept is still the same. I wasn't 100% which you were referring to.
Additional thought
I was tasked by my company to research a solution for this that could function in IE7+, Firefox, and Chrome.
After many moons of searching, trying, and frustration it really boiled down to a fundamental problem. For the most part, in order to gain the fixed header, you need to implement fixed height/width columns because most solutions involve using two separate tables, one for the header which will float and stay in place over the second table that contains the data.
//float this one right over second table
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</table>
<table>
//Data
</table>
An alternative approach some try is utilize the tbody and thead tags but that is flawed too because IE will not allow you put a scrollbar on the tbody which means you can't limit its height (so stupid IMO).
<table>
<thead style="do some stuff to fix its position">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody style="No scrolling allowed here!">
Data here
</tbody>
</table>
This approach has many issues such as ensures EXACT pixel widths because tables are so cute in that different browsers will allocate pixels differently based on calculations and you simply CANNOT (AFAIK) guarantee that the distribution will be perfect in all cases. It becomes glaringly obvious if you have borders within your table.
I took a different approach and said screw tables since you can't make this guarantee. I used divs to mimic tables. This also has issues of positioning the rows and columns (mainly because floating has issues, using in-line block won't work for IE7, so it really left me with using absolute positioning to put them in their proper places).
There is someone out there that made the Slick Grid which has a very similar approach to mine and you can use and a good (albeit complex) example for achieving this.
https://github.com/6pac/SlickGrid/wiki
According to Pure CSS Scrollable Table with Fixed Header , I wrote a DEMO to easily fix the header by setting overflow:auto to the tbody.
table thead tr{
display:block;
}
table th,table td{
width:100px;//fixed width
}
table tbody{
display:block;
height:200px;
overflow:auto;//set tbody to auto
}
My concern was not to have the cells with fixed width. Which seemed to be not working in any case.
I found this solution which seems to be what I need. I am posting it here for others who are searching of a way. Check out this fiddle
Working Snippet:
html, body{
margin:0;
padding:0;
height:100%;
}
section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
}
section.positioned {
position: absolute;
top:100px;
left:100px;
width:800px;
box-shadow: 0 0 15px #333;
}
.container {
overflow-y: auto;
height: 160px;
}
table {
border-spacing: 0;
width:100%;
}
td + td {
border-left:1px solid #eee;
}
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div{
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div{
border: none;
}
<section class="">
<div class="container">
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</section>
You can use CSS position: sticky; for the first row of the table
MDN ref:
.table-class tr:first-child>td{
position: sticky;
top: 0;
}
you can use two divs one for the headings and the other for the table. then use
#headings {
position: fixed;
top: 0px;
width: 960px;
}
as #ptriek said this will only work for fixed width columns.
It is possible using position:fixed on <th> (<th> being the top row).
Here's an example
The Chromatable jquery plugin allows a fixed header (or top row) with widths that allow percentages--granted, only a percentage of 100%.
http://www.chromaloop.com/posts/chromatable-jquery-plugin
I can't think of how you could do this without javascript.
update: new link -> http://www.jquery-plugins.info/chromatable-00012248.htm
I use this:
tbody{
overflow-y: auto;
height: 350px;
width: 102%;
}
thead,tbody{
display: block;
}
I define the columns width with bootstrap css col-md-xx. Without defining the columns width the auto-width of the doesn't match the . The 102% percent is because you lose some sapce with the overflow
Using css zebra styling
Copy paste this example and see the header fixed.
<style>
.zebra tr:nth-child(odd){
background:white;
color:black;
}
.zebra tr:nth-child(even){
background: grey;
color:black;
}
.zebra tr:nth-child(1) {
background:black;
color:yellow;
position: fixed;
margin:-30px 0px 0px 0px;
}
</style>
<DIV id= "stripped_div"
class= "zebra"
style = "
border:solid 1px red;
height:15px;
width:200px;
overflow-x:none;
overflow-y:scroll;
padding:30px 0px 0px 0px;"
>
<table>
<tr >
<td>Name:</td>
<td>Age:</td>
</tr>
<tr >
<td>Peter</td>
<td>10</td>
</tr>
</table>
</DIV>
Notice the top padding of of 30px in the div leaves
space that is utilized by the 1st row of stripped data
ie tr:nth-child(1) that is "fixed position"
and formatted to a margin of -30px