Understanding tables in html / css - html

I am trying to understand tables in html / css, but I don't understand anything of it. I have a lot of questions about it, but i will start with the first one.
Here:
http://www.w3schools.com/cssref/pr_tab_table-layout.asp
they are saying in case of "table-layout: fixed;":
"The horizontal layout only depends on the table's width and the width of the columns, not the contents of the cells"
Okay....so it does not depend on the contents of the cell? Let's test it:
I made a table with table-layout: fixed and I gave one column a width of 200px (inline css in the html):
.myTable {
border: 1px solid black;
}
.myTable th,
.myTable td {
border: 1px solid black;
}
<table class="myTable" style="width: auto; table-layout: fixed;">
<tr>
<th>Column A</th>
<th style="width: 200px">Column B</th>
</tr>
<tr>
<td>A1</td>
<td>B1: This is a sentence with a very long word in it, to check what the behavior is of the table in a case like that. Will long words be broken and wrap onto the next line? Thisisaverylongwordyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitis</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</table>
Why that column with width 200px is now bigger than 200px? If the width would not depend on the contents of the cell then I would expect a width of 200px. In this case i would expect that the long word could overflow, but now the table / column is adjusting its width.
Can anyone tell me how this is working and why it's working like that? I know I can solve it with things like word-wrap: break-word; but I want to understand it.

Because you included a long line of unbroken text. By default the browser won't break up that text unless you tell it to with a rule like word-break:break-all;. So it does work as expected, you're just giving it text that it doesn't want to break because that's the default behavior. You'll also see if you remove that long unbroken string of text that the column is 200px wide.
.myTable {
border: 1px solid black;
}
.myTable th,
.myTable td {
border: 1px solid black;
word-break:break-all;
}
<table class="myTable" style="width: auto; table-layout: fixed;">
<tr>
<th>Column A</th>
<th style="width: 200px">Column B</th>
</tr>
<tr>
<td>A1</td>
<td>B1: This is a sentence with a very long word in it, to check what the behavior is of the table in a case like that. Will long words be broken and wrap onto the next line? Thisisaverylongwordyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitisyesitis</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</table>

Related

one column table with multiple <th>

I have a simple table :
table {
border: 1px solid grey
}
th,
td {
padding: .5rem
}
th {
text-align: right
}
<table>
<tbody>
<tr>
<th scope="row">Feed in Braids</th>
<td>20 / two braids</td>
</tr>
<tr>
<th scope="row">Waves / Curls / Straightening</th>
<td>30</td>
</tr>
<tr>
<th scope="row">Hairstyle for special occasions</th>
<td>45-60</td>
</tr>
</tbody>
</table>
I would like to squeeze the data in one column, which would probably have to look something like this:
table {
border: 1px solid black;
padding: 1rem;
text-align: center;
}
th,
td {
padding: .5rem
}
<table class="table table-hover">
<tr>
<th>Feed in Braids</th>
</tr>
<tr>
<td>20 / two braids</td>
</tr>
<tr>
<th>Waves</th>
</tr>
<tr>
<td>25</td>
</tr>
<tr>
<th>Special</th>
</tr>
<tr>
<td>40 </td>
</tr>
</table>
I have doubts if the "squeezed" table would be a correct construct, in terms of possibly unclear scope of the headings.
Concerning accessibility, a table header (th) can only have either "row" or "column" as its scope, and this is always valid for the whole row or column. So in this way your "one-column table" doesn't really meet accessibility standards and isn't semantically correct.
But if you have everything in one column, you could as well use alternating headers (like h3, h4, h4, whatever) instead of th and paragraphs (or simply contents following the headers) instead of td. And once you are that far, a table itself wouldn't make that much sense – the wparent element might as well be a div...
You also might want to consider a definition list instead, maybe (depending on what your actual usecase looks like, or which function it should fulfill): https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
Or you use nested tables, i.e. multiple tables consisting of one th and one td, nested either in the cells of a larger table (if that semantically makes sense at all) or simply inside a div or section element.

table cell, wrapped text, fit width to content, remove extra right hand white space

I have a set width table container, it will contain 3 text elements separated by single characters (>).
These text elements may contain text that cannot be fit in the container on a single line along with the rest, and must be wrapped.
The issue is when the text wraps, the cell will contain extra white space on the right hand side that then forces the other elements to wrap, where normally, without the white space, the succeeding elements would each fit on a single line.
Here is the desired behavior:
Where the first text element cannot fit on a single line and must wrap.
But any of the other text elements may also not fit on a single line and must wrap, leaving no extra white space.
Using a basic table layout:
<table class="table">
<tbody>
<tr>
<td>Membership Clubs and Organizations</td>
<td>></td>
<td>Books Wholesaler</td>
<td>></td>
<td>Music Management</td>
</tr>
</tbody>
</table>
.table {
width:450px;
border:1px solid black;
}
Here there is extra whitespace, causing the succeeding elements to also wrap.
After a lot of research, the closest i have come is by setting width:0.1% for the text elements.
Unfortunately this results in the separating characters having their own extra white space, which i have not been able to remove, i have been unable to reduce their width to fit their contents.
<table class="table">
<tbody>
<tr>
<td class="text">Membership Clubs and Organizations</td>
<td class="separator">></td>
<td class="text">Books Wholesaler</td>
<td class="separator">></td>
<td class="text">Music Management</td>
</tr>
</tbody>
</table>
.text {
width:0.1%;
}
.table {
width:450px;
border:1px solid black;
}
I settled on using tables because it got me closer to what i need, but i am open to use any format, the only requirement is that it be in pure css, and not use any javascript.
.text {
width:0.1%;
}
.table {
width:450px;
border:1px solid black;
}
<table class="table">
<tbody>
<tr>
<td class="text">Membership Clubs and Organizations</td>
<td class="separator">></td>
<td class="text">Books Wholesaler</td>
<td class="separator">></td>
<td class="text">Music Management</td>
</tr>
</tbody>
</table>
The width of the table is forcing the white-space to be there, no matter what. table-cells have extra space, so the words wrap when necessary, or the cells have no extra space, so the words wrap on every word.
I think the only option for zero whitespace is
td { word-break: break-all; }
.table {
width:450px;
border:1px solid black;
}
td {
word-break: break-all;
}
<table class="table">
<tbody>
<tr>
<td class="text">Membership Clubs and Organizations</td>
<td class="separator">></td>
<td class="text">Books Wholesaler</td>
<td class="separator">></td>
<td class="text">Music Management</td>
</tr>
</tbody>
</table>
just remove
.text {
width:0.1%;
}

Same column width under colspan

How can I make columns under colspan of same width?
I have table header like in example.
<html>
<head>
<style>td {border: solid 1px black;}</style>
</head>
<body>
<table style="width: 100%;border-collapse: collapse;">
<tr>
<td rowspan="2">Some header columns or even several(big or small)</td>
<td colspan="4">pre-defined number of undercolumns</td>
</tr>
<tr>
<td>1</td><td>11</td><td>111</td><td>1111</td>
</tr>
<tr>
<td>data_row</td><td>4444</td><td>333</td><td>22</td><td>1</td>
</tr>
</table>
</body>
</html>
I have created a jsFiddle that demonstrates this.
Potentially the number of columns (to make same width) could be different. Changing the table-layout to fixed is not a solution in my case because of existence of other columns. I can not make them with fixed width since not sure of data content length. I also can not do them with percent width since it is percent of all table, but not column group.
You can try this:
td {
border: solid 1px black;
width: calc(100%/5);
}
And you can divide the width as many columns as you have.

Page break only between tbody when printing from Chrome

I have a <table> of data where consecutive rows are conceptually related and need to stay together. I've group each pair of rows in a <tbody> tag. When it comes time to print the table, I want to make sure that page breaks only happen between <tbody> tags.
I've tried some variations of page-break-inside: avoid and page-break-after: auto, but can't seem to get it to work in Chrome 42 (see screenshot below)
However, it does seems to work as expected in Firefox 40 and IE 11 though. It looks like page-break-* might only apply to block level elements. Is there a good way to accomplish this in html/css?
Example code:
<!doctype html>
<html>
<head>
<style>
table {
width: 70%;
border-collapse: collapse;
}
thead {
display: table-header-group;
text-align: left;
border-bottom: 2px solid #000;
}
tbody {
page-break-inside: avoid;
border-bottom: 1px solid #ccc;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Project #</th>
<th>Owner</th>
<th>% Complete</th>
</tr>
</thead>
<tbody>
<tr>
<td>HR-123</td>
<td>Arther Dent</td>
<td>42%</td>
</tr>
<tr>
<td colspan='3'>Description: Find travel guide to get me back to earth.</td>
</tr>
</tbody>
<tbody>
<tr>
<td>RD-123</td>
<td>Frodo Baggins</td>
<td>9%</td>
</tr>
<tr>
<td colspan='3'>Description: Find a better way to get the ring to Mordor.</td>
</tr>
</tbody>
<!-- repeat tbody sections as necessary to get onto the second page -->
</table>
</body>
</html>
Here's a JSFiddle that'll give you a bit of an idea of what I'm trying to accomplish.
Edit: I considering not using a table but didn't since (i) I want my columns to line up, and (ii) I really don't want to hard-code column widths to make sure they're all the same.
Try wrapping it all in a
make that specific a block element (http://learnlayout.com/inline-block.html)
then use page-break-*

Force table column widths to always be fixed regardless of contents

I have an html table with table-layout: fixed and a td with a set width. The column still expands to hold the contents of text that doesn't contain a space. Is there a way to fix this other than wrapping the contents of each td in a div?
Example: http://jsfiddle.net/6p9K3/29/
<table>
<tbody>
<tr>
<td style="width: 50px;">Test</td>
<td>Testing 1123455</td>
</tr><tr>
<td style="width: 50px;">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</td>
<td>B</td>
</tr>
</tbody>
</table>
table
{
table-layout: fixed;
}
td
{
border: 1px solid green;
overflow: hidden;
}
In the example, you can see that the column with AAAAAAAAAAAA... expands despite being explicitly set to 50px wide.
Specify the width of the table:
table
{
table-layout: fixed;
width: 100px;
}
See jsFiddle
Try looking into the following CSS:
word-wrap:break-word;
Web browsers should not break-up "words" by default so what you are experiencing is normal behaviour of a browser. However you can override this with the word-wrap CSS directive.
You would need to set a width on the overall table then a width on the columns. "width:100%;" should also be OK depending on your requirements.
Using word-wrap may not be what you want however it is useful for showing all of the data without deforming the layout.
Make the table rock solid BEFORE the css. Figure your width of the table, then use a 'controlling' row whereby each td has an explicit width, all of which add up to the width in the table tag.
Having to do hundreds html emails to work everywhere, using the correct HTML first, then styling w/css will work around many issues in all IE's, webkit's and mozillas.
so:
<table width="300" cellspacing="0" cellpadding="0">
<tr>
<td width="50"></td>
<td width="100"></td>
<td width="150"></td>
</tr>
<tr>
<td>your stuff</td>
<td>your stuff</td>
<td>your stuff</td>
</tr>
</table>
Will keep a table at 300px wide. Watch images that are larger than the width by extremes
You can add a div to the td, then style that. It should work as you expected.
<td><div>AAAAAAAAAAAAAAAAAAA</div></td>
Then the css.
td div { width: 50px; overflow: hidden; }
You can also use percentages, and/or specify in the column headers:
<table width="300">
<tr>
<th width="20%">Column 1</th>
<th width="20%">Column 2</th>
<th width="20%">Column 3</th>
<th width="20%">Column 4</th>
<th width="20%">Column 5</th>
</tr>
<tr>
<!--- row data -->
</tr>
</table>
The bonus with percentages is lower code maintenance: you can change your table width without having to re-specify the column widths.
Caveat: It is my understanding that table width specified in pixels isn't supported in HTML 5; you need to use CSS instead.
You can also work with "overflow: hidden" or "overflow-x: hidden" (for just the width). This requires a defined width (and/or height?) and maybe a "display: block" as well.
"Overflow:Hidden" hides the whole content, which does not fit into the defined box.
Example:
http://jsfiddle.net/NAJvp/
HTML:
<table border="1">
<tr>
<td><div>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div></td>
<td>bbb</td>
<td>cccc</td>
</tr>
</table>
CSS:
td div { width: 100px; overflow-y: hidden; }
EDIT: Shame on me, I've seen, you already use "overflow". I guess it doesn't work, because you don't set "display: block" to your element ...
I would try setting it to:
max-width: 50px;
This works for me
td::after {
content: '';
display: block;
width: 30px;
}