column width issues in html tables that only scroll the body - html

I have a table where I have successfully set up the body to scroll, and leave the header alone, but this now appears to be causing problems with column widths:
One has to specify the widths of columns in the tbody to be the same as the ones in the thead, else the browser decides to do things how it thinks it should be done, ie: wrong.
however, the browser (and this is consistent across the three recognised mainstream browsers - ie, firefox and chrome) still seems to want to vary the size of my columns.
here is a code sample:
CSS:
<style>
#divPersonalTables tbody:nth-child(2) {max-height: 350px; overflow-y: scroll; overflow-x: hidden}
.tdTextColumn { width: 200px }
.tdCheckColumn { width: 86px }
</style>
HTML:
<div style="display: flex" id="divPersonalTables">
<table id='tblTables' style="display: inline-block; width: 500px">
<thead>
<tr>
<th class="tdTextColumn">Forename</th>
<th class="tdTextColumn">Surname</th>
<th class="tdCheckColumn">Current</th>
<th style="width: 14px"></th>
</tr>
</thead>
<tbody style="display: block">
<tr>
<td style="display: none"></td>
<td class="tdTextColumn"><input type="text" /></td>
<td class="tdTextColumn"><input type="text" /></td>
<td class="tdCheckColumn"><input type="checkbox" /></td>
</tr>
</tbody>
</table>
</div>
The scrolling body style is applied to all tbody elements contained within that div, as there are two - one omitted here for conciseness.
So in summary: how can I make sure the browser is setting the columns to the widths I think it should be ?

The order of your columns does not match.
Put your hidden column to the right and you should be set.
<div style="display: flex" id="divPersonalTables">
<table id='tblTables' style="display: inline-block; width: 500px">
<thead>
<tr>
<th class="tdTextColumn">Forename</th>
<th class="tdTextColumn">Surname</th>
<th class="tdCheckColumn">Current</th>
<th style="width: 14px"></th>
</tr>
</thead>
<tbody style="display: block">
<tr>
<td class="tdTextColumn"><input type="text" /></td>
<td class="tdTextColumn"><input type="text" /></td>
<td class="tdCheckColumn"><input type="checkbox" /></td>
<td style="display: none"></td>
</tr>
</tbody>
</table>
btw: Why do you set <td style="display: none"></td> ?

Related

Having images not shrink on bootstrap 5 table

I am using bootstrap 5.
I have a table and I need to display four images side by side. This seems to work on a large screen:
However, on a phone the images are shrunken and no longer visible:
How can I force the images to remain at least 16px even on phone screens? The table will have a horizontal scroll but that is ok.
Is there a better way to display 4 img tags in one td and force all of them to be on the same line? The only way I found to do it is by putting them in row and col divs.
Code:
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">Username</th>
<th scope="col">Match Predictions Made</th>
<th scope="col">Winner</th>
<th scope="col">Finals</th>
<th scope="col">Top 4</th>
<th scope="col">Points</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Marcipanas</th>
<td>5/36</td>
<td><img src="assets/flags/be.svg" class=" float-start flag-img" alt="be"></td>
<td>
<div class="row">
<div class="col"><img src="assets/flags/it.svg" class="flag-img" alt="it"></div>
<div class="col"><img src="assets/flags/cz.svg" class="flag-img" alt="cz"></div>
</div>
</td>
<td>
<div class="row">
<div class="col"><img src="assets/flags/be.svg" class="flag-img" alt="be"></div>
<div class="col"><img src="assets/flags/dk.svg" class="flag-img" alt="dk"></div>
<div class="col"><img src="assets/flags/fi.svg" class="flag-img" alt="fi"></div>
<div class="col"><img src="assets/flags/ru.svg" class="flag-img" alt="ru"></div>
</div>
</td>
<td>0</td>
</tr>
<tr>
<th scope="row">test3</th>
<td>0/36</td>
<td><img src="assets/flags/it.svg" class=" float-start flag-img" alt="it"></td>
<td class="text-muted">No prediction</td>
<td class="text-muted">No prediction</td>
<td>0</td>
</tr>
<tr>
<th scope="row">testing1</th>
<td>1/36</td>
<td class="text-muted">No prediction</td>
<td class="text-muted">No prediction</td>
<td class="text-muted">No prediction</td>
<td>0</td>
</tr>
<tr>
<th scope="row">test2</th>
<td>0/36</td>
<td class="text-muted">No prediction</td>
<td class="text-muted">No prediction</td>
<td class="text-muted">No prediction</td>
<td>0</td>
</tr>
</tbody>
</table>
</div>
EDIT
As John suggested bellow I tried to add nowrap instead of using row-col but that seems to have forced everything into separate lines.
Code:
<td>
<div class="no-wrap">
<img src="assets/flags/be.svg" class="flag-img" alt="be">
<img src="assets/flags/dk.svg" class="flag-img" alt="dk">
<img src="assets/flags/fi.svg" class="flag-img" alt="fi">
<img src="assets/flags/ru.svg" class="flag-img" alt="ru">
</div>
</td>
css:
.flag-img {
max-height: 32px;
min-height: 16px;
min-width: 16px;
}
.no-wrap {
flex-wrap: nowrap !important;
}
Image of results:
So bootstrap defaults .row to have flex-wrap: wrap; You can add this to your CSS for force it to stop wrapping:
.row {
flex-wrap: nowrap !important;
}
Though I'd might consider adding a new class to each row with the images and calling that class instead of just outright .row incase there are areas where you want it to wrap. But this code will work.
As for the shrinking issue, if you want your pictures to never be smaller than 16px you can add this code to your CSS:
.flag-img {
min-width: 16px;
}

Table column sizing involving colspan

I managed to kinda achieve my intended design but it feels kinda like a hack.
So I'm working with this table and now cell size looks exactly as I'd like it to be, but I have to add extra row on top of my table (and hide it, but not in example so it's easier to understand). So if you try and delete that top row you can see how it all gets messed up (description fields don't look the same).
http://jsfiddle.net/nooorz24/cea57mhd/4/
table {
width: 100%;
}
table td {
border: 1px solid black;
}
<table>
<tr>
<td style="width: 1px;"></td>
<td style="width: 10000px;"></td>
<td style="width: 1px;"></td>
<td style="width: 10000px;"></td>
</tr>
<tr>
<td style="width: 1px;">IMG</td>
<td style="width: 10000px;" colspan="2">Description text</td>
<td></td>
</tr>
<tr>
<td colspan="2"></td>
<td style="width: 1px;">IMG</td>
<td style="width: 10000px;">Description text</td>
</tr>
</table>
As far as I can understand it's because I try to set width to a cell that has colspan="2" and html doesn't understand how to work with that.
Can this be solved without adding extra row?
You can use the HTML col element which is designed just for that: styling or defining common attributes for an entire column.
table {
width: 100%;
}
table td {
border: 1px solid black;
}
<table>
<colgroup>
<col style="width: 1px">
<col style="width: 10000px;">
<col style="width: 1px">
<col style="width: 10000px;">
</colgroup>
<tr>
<td>IMG</td>
<td colspan="2">Description text</td>
<td></td>
</tr>
<tr>
<td colspan="2"></td>
<td>IMG</td>
<td>Description text</td>
</tr>
</table>

Shrink table cell height despite content

I'm hoping there is a way to shrink the height of a td so that the height is exactly what I want, example 6px when it is holding 11px text. I'm envisioning being able to see the top half of the cell content.
The reason I don't want to just set the div height is I want each row to be the same height, and there are cells spanning rows so the div would be cutting off content to one cell when it should be able to expand to the two cells. I hope that makes some sense...
<table>
<thead>
<tr>
<th style="height: 0px; width: 0px;">
</th>
<th style="width: 25px;">
</th>
<th style="width: 25px;">
</th>
</tr>
</thead>
<tbody>
<tr>
<td style="height: 6px;">
</td>
<td>
<div>
Some table data</div>
</td>
<td rowspan="2">
<div>
Some data that is two rows high</div>
</td>
</tr>
<tr>
<td style="height: 6px;">
</td>
<td>
<div>
Some more data</div>
</td>
</tr>
</tbody>
</table>
You can't restrict the table cells' height but you can enforce height on the immediate <div>s:
td > div {
overflow: hidden;
height: 6px;
}

Chrome - Colspan not working as expected

I have this code:
<tr>
<td width="40%" align="left" class="form_cell">
<span class="sub_header">Update or Delete</span><br />
Please select whether you would like us to update this contacts details, or delete them from the system.
</td>
<td width="60%" align="left" class="form_cell">
[class=form__parser func=updateDetails__updel(150.$update_or_delete$.true)]
</td>
</tr>
<tr>
<td width="100%" align="left" colspan="2" id="ammend_contact_details" style="display: none;">
<table border="0" cellspacing="0" cellpadding="0" width="100%" align="left">
<tr>
<td width="40%" align="left" class="form_cell">
<span class="sub_header">New Title</span><br />
Please enter the contacts new title, IE Mr, Mrs, Dr, Miss, Ms
</td>
<td width="60%" align="left" class="form_cell">
<input type="text" name="update_contact_title" class="input" size="48" maxlength="6" value="$update_contact_title$" />
</td>
</tr>
</table>
</td>
</tr>
The code which start with [class=form__parser...] creates a drop down list. If you click one of the options, the cell below it (ID ammend_contact_details) is displayed, otherwise its hidden.
The website address for this page is: http://www.westlandstc.com/index.php?plid=6#eyJwbGlkIjoiNTkiLCJjbGlkIjoiNDQ2Iiwic2NsaWQiOiJudWxsIiwiZHluYW0iOiJudWxsIiwiYXBwSWQiOiJudWxsIn0= and the element in question is at the very bottom of the page.
The problem is, the colspanattribute works fine in internet explorer (surprise surprise), however, in Chrome, all the content which is supposed to be spread over the 2 parent columns, only goes into the 1st column.
I have narrowed the bug down further, if I remove the style="display: none" attribute it works fine. Everytime I try to change either the display style or visibility style, Chrome places everything back into the first column.
In addition, I tried setting the background colour of the cell which spans 2 columns to red. In internet explorer, again this works as expected. In chrome, no background-color is displayed.
Any ideas how to fix this?
What are you setting the 'display' property to in order to show it? iirc you would need to use 'display:table-cell' (or similar - can't remember the exact value) in order for chrome to treat it as a table cell
style.display=''
works for me with chrome.
'display:table-cell'
does not
Rather than adding the CSS property display:inline to the <td>, which for some reason IE is happy with and Chrome is not, I would update your JavaScript to just remove the display:none style and let the browser's default display:table-cell take affect.
In the <select name="update_or_delete"> onchange method simply have:
if(this.value=='Update') {
document.getElementById('ammend_contact_details').style.display='';
} else {
document.getElementById('ammend_contact_details').style.display='none';
}
Chrome doesn't seem to respect colspan unless it has at least 1 row exactly matching number of columns in the table. I tried to make a grid with 2 items in 1st row and 3 items in 2nd row. For Firefox that's all you need:
td {
display: table-cell;
padding: 10px;
text-align: center;
background: #eee;
}
<table style="width: 100%">
<tr>
<td colspan="3" style="width: 50%">box 1.1</td>
<td colspan="3" style="width: 50%">box 1.2</td>
</tr>
<tr>
<td colspan="2" style="width: 33.33%">box 2.1</td>
<td colspan="2" style="width: 33.33%">box 2.2</td>
<td colspan="2" style="width: 33.33%">box 2.3</td>
</tr>
</table>
But it doesn't work on Chrome and Edge, even though all <td>s have default styling: display: table-cell. To fix it you need to add empty row with exact match for column count so it finally looks like this:
td {
display: table-cell;
padding: 10px;
text-align: center;
background: #eee;
}
<table style="width: 100%">
<tr>
<td colspan="3" style="width: 50%">box 1.1</td>
<td colspan="3" style="width: 50%">box 1.2</td>
</tr>
<tr>
<td colspan="2" style="width: 33.33%">box 2.1</td>
<td colspan="2" style="width: 33.33%">box 2.2</td>
<td colspan="2" style="width: 33.33%">box 2.3</td>
</tr>
<tr style="visibility: hidden">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>

HTML Table width in percentage, table rows separated equally

When I create a table in html, a table with a width of 100%, if I want all the cells (tds) to be divided in equal parts, do I have to enter the width % for each cell? Am I "obliged" to do it?
E.g.:
<table cellpadding="0" cellspacing="0" width="100%" border="0">
<tr>
<td width="25%"></td>
<td width="25%"></td>
<td width="25%"></td>
<td width="25%"></td>
</tr>
</table>
OR the following could also be the right procedure, not to write the width in each tds if I want each of them to be devided equally:
<table cellpadding="0" cellspacing="0" width="100%" border="0">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
I know it works with both manners but I just want to know the "legit" way to do it.
Use the property table-layout:fixed; on the table to get equally spaced cells. If a column has a width set, then no matter what the content is, it will be the specified width. Columns without a width set will divide whatever room is left over among themselves.
<table style='table-layout:fixed;'>
<tbody>
<tr>
<td>gobble de gook</td>
<td>mibs</td>
</tr>
</tbody>
</table>
Just to throw it out there, you could also use <colgroup><col span='#' style='width:#%;'/></colgroup>, which doesn't require repetition of style per table data or giving the table an id to use in a style sheet. I think setting the widths on the first row is enough though.
You need to enter the width % for each cell. But wait, there's a better way to do that, it's called CSS:
<style>
.equalDivide tr td { width:25%; }
</style>
<table class="equalDivide" cellpadding="0" cellspacing="0" width="100%" border="0">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
Yes, you will need to specify the width for each cell, otherwise they will try to be "intelligent" about it and divide the 100% between whichever cells think they need it most. Cells with more content will take up more width than those with less.
To make sure you get equal width for each cell you need to make it clear. Either do it as you already have, or use CSS.
table.className td { width: 25%; }
you can try this, I would do it with CSS, but i think you want it with tables without CSS.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body leftmargin=0 rightmargin=0>
<table cellpadding="0" cellspacing="0" width="100%" border="1" height="350px">
<tr>
<td width="25%"> </td>
<td width="25%"> </td>
<td width="25%"> </td>
<td width="25%"> </td>
</tr>
</table>
</body>
</html>
This is definitely the cleanest answer to the question: https://stackoverflow.com/a/14025331/1008519.
In combination with table-layout: fixed I often find <colgroup> a great tool to make columns act as you want (see codepen here):
table {
/* When set to 'fixed', all columns that do not have a width applied will get the remaining space divided between them equally */
table-layout: fixed;
}
.fixed-width {
width: 100px;
}
.col-12 {
width: 100%;
}
.col-11 {
width: 91.666666667%;
}
.col-10 {
width: 83.333333333%;
}
.col-9 {
width: 75%;
}
.col-8 {
width: 66.666666667%;
}
.col-7 {
width: 58.333333333%;
}
.col-6 {
width: 50%;
}
.col-5 {
width: 41.666666667%;
}
.col-4 {
width: 33.333333333%;
}
.col-3 {
width: 25%;
}
.col-2 {
width: 16.666666667%;
}
.col-1 {
width: 8.3333333333%;
}
/* Stylistic improvements from here */
.align-left {
text-align: left;
}
.align-right {
text-align: right;
}
table {
width: 100%;
}
table > tbody > tr > td,
table > thead > tr > th {
padding: 8px;
border: 1px solid gray;
}
<table cellpadding="0" cellspacing="0" border="0">
<colgroup>
<col /> <!-- take up rest of the space -->
<col class="fixed-width" /> <!-- fixed width -->
<col class="col-3" /> <!-- percentage width -->
<col /> <!-- take up rest of the space -->
</colgroup>
<thead>
<tr>
<th class="align-left">Title</th>
<th class="align-right">Count</th>
<th class="align-left">Name</th>
<th class="align-left">Single</th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-left">This is a very looooooooooong title that may break into multiple lines</td>
<td class="align-right">19</td>
<td class="align-left">Lisa McArthur</td>
<td class="align-left">No</td>
</tr>
<tr>
<td class="align-left">This is a shorter title</td>
<td class="align-right">2</td>
<td class="align-left">John Oliver Nielson McAllister</td>
<td class="align-left">Yes</td>
</tr>
</tbody>
</table>
<table cellpadding="0" cellspacing="0" border="0">
<!-- define everything with percentage width -->
<colgroup>
<col class="col-6" />
<col class="col-1" />
<col class="col-4" />
<col class="col-1" />
</colgroup>
<thead>
<tr>
<th class="align-left">Title</th>
<th class="align-right">Count</th>
<th class="align-left">Name</th>
<th class="align-left">Single</th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-left">This is a very looooooooooong title that may break into multiple lines</td>
<td class="align-right">19</td>
<td class="align-left">Lisa McArthur</td>
<td class="align-left">No</td>
</tr>
<tr>
<td class="align-left">This is a shorter title</td>
<td class="align-right">2</td>
<td class="align-left">John Oliver Nielson McAllister</td>
<td class="align-left">Yes</td>
</tr>
</tbody>
</table>