How to make table equally spaced and wrap word - css

I'm using twitter bootstrap, but I think it has nothing to do with the solution, so here is the code:
div.span12
table.table.table-hover
thead
tr
th Device Name
th Device ID
th Device Description
tbody
each dev in devices
tr
td #{dev.dname}
td #{dev.did}
td #{dev.ddesc}
If one of the attributes gets too big, the table shifts to one side allowing space for the big item. How can I keep the original even spacing and allow word wrap on the rows of the table?
<div class="span12">
<table class="table table-hover">
<thead>
<tr>
<th>Device Name</th>
<th>Device ID</th>
<th>Device Description</th>
</tr></thead>
<tbody>
<tr>
<td>nn</td>
<td>ii</td>
<td>dd</td>
</tr>
</tbody></table></div>

Just override properties for td
td {
width: 33.33%;
}
DEMO

Related

CSS - Hide td in body if th has class

I need to hide td in the body if the th in the head has the class .isSystem
Is this possible in straight CSS?
More info: the table is built dynamically. The head/columns is an array... and the tbody/rows is another array. I'm using Angular/typescript...
I tried this: th.isSystem ~ td { text-decoration: line-through; color: red; }
If the table is built dynamically, then the obvious way is to use col rather than th to drive this behaviour. <col> elements have special powers which enable them to affect the cells they belong to.
table {border:1px outset;}
th, td {border:1px inset;}
col.isSystem {visibility:collapse;}
<table>
<col/><col class="isSystem"/><col/><col/>
<thead>
<tr><th>One</th> <th>Two</th> <th>Three</th> <th>Four</th></tr>
</thead>
<tbody>
<tr><td>This</td> <td>This</td> <td>This</td> <td>This</td></tr>
<tr><td>is</td> <td>is</td> <td>is</td> <td>is</td></tr>
<tr><td>the</td> <td>the</td> <td>the</td> <td>the</td></tr>
<tr><td>first</td> <td>second</td><td>third</td> <td>fourth</td></tr>
<tr><td>column</td><td>column</td><td>column</td><td>column</td></tr>
</tbody>
</table>
Disclaimer: this works as advertised in Firefox, IE11 and Edge. Chrome however... sorry.
Bottom Line:
No, because <td> and <th> can not be siblings since they are not proper children of a <table> and even if your source markup has them that way - the browser will adjust the markup and overrule your styles.
Long explanation:
Looking at a more JS related SO question on the subject, the browser automatically will inject <thead> and <tbody> around your <th> and <tr> (subsequently <td>) elements. <thead> and <tbody> are valid child elements of <table> - <th> and <tr> are not.
As a result, finding the siblings of <th> will only return other th tags, since they technically live in a <thead> - the <td> are in a <tr> in <tbody>
Take a look at these examples:
Example 1
Codepen with straight <th> and <tr> elements
.isSystem + .row { background:red }
<table>
<th class="isSystem">Table Heading</th>
<tr class="row">
<td>Table Item</td>
</tr>
</table>
<div class="isSystem">Div Heading</div>
<div class="row">Div Item</div>
In this example, you would expect the table row to be red... The div elements in the example do this but the <tr> doesn't
Example 2
Codepen with proper <thead> and <tbody> elements
In example 2, wrapping the table with the correct thead and tbody elements, you can acheive this:
.isSystem + .rows tr { background:red; }
<table>
<thead class="isSystem"><th>Heading</th></thead>
<tbody class="rows">
<tr class="row"><td>Item</td></tr>
</tbody>
</table>
Unfortunately if your items are dynamically generated and you can not apply your classes in this way, then your only option will be using JS to target your elements as others have already mentioned. However, I would do what's possible to create proper semantic markup first.

select the last element having some style property

table {
border-collapse: collapse;
border : 1px solid #e2e2e2;
}
caption, th, td {
text-align: left;
line-height: 1.4;
padding: 8px;
}
tr {
border-bottom: 1px solid #ccc;
vertical-align: top;
}
<table>
<caption>Optional table caption.</caption>
<thead>
<tr class="heade_class">
<th>#</th>
<th style="display:table-cell">First Name</th>
<th style="display:table-cell">Last Name</th>
<th style="display:none">Username</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td style="display:none">#mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td style="display:none">#fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td style="display:none">#twitter</td>
</tr>
</tbody>
</table>
code here is just example here note that th and tr are dynamically set with the values.
hi guys i wan to select only last th of the which having the style"display:table-cell" property only
now i have tried little bit with using last-child
here i can get the all th with the style"display:table-cell" property only but could not find last th among them
using only css
.heade_class th[style*="display: table-cell"]:last-child {
}
In short, you cannot do this with CSS alone.
The Problem
First of all, spaces are important. You cannot have a space after th and the style attribute must match exactly the same as the style defined in the HTML. So for it to be valid it should be as follows:
.heade_class th[style*="display:table-cell"]
However, you still won't get what you want because last-child doesn't work as you think. In order for it to match it must be the last child, not just the last element that matches your other specification.
So if you consider this:
.heade_class th[style*="display:table-cell"]:last-child
What it means is as follows:
Is a th element
And the style attribute contains display:table-cell
And it is the last child element
For this you will notice none of your elements match all three conditions and that is why it doesn't work.
Other Options
Some other options, but they are probably not quite what you are looking for:
You could try nth-last-child as follows, but it relies on you knowing how many elements are going to be hidden after it, which probably isn't what you want:
.heade_class th[style*="display:table-cell"]:nth-last-child(2)
An alternative, depending on how you render your HTML, would be to either omit the hidden ones completely, or change the hidden ones to td. If you change them to td then you can use last-of-type like so:
.heade_class th:last-of-type
But you may want to check the browser support for that before using it.

CSS selector for first TH after a caption in a table

I have a table that I want to select the very first TH only if it contains a caption. I thought it might be something like this:
.myTable caption + tr th:first-child
{
/* stuff */
}
It's instead selecting nothing. Is this a bug in CSS or just my logic?
See my JSFiddle: https://jsfiddle.net/ukb13pdp/1/
.objectTable th:first-child
{
background-color: blue;
color: white;
}
.objectTable caption + tr th:first-child
{
background-color: red;
}
<table class='objectTable'>
<caption>Caption Table</caption>
<tr>
<th>A</th>
<th>B</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
</tr>
</table>
<br/><br/>
<span>No Caption Table</span>
<table class='objectTable'>
<tr>
<th>C</th>
<th>D</th>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
</table>
The cause here is exactly the same as the one described in this related question about the use of child selectors with tr. The problem is that tr elements are made children of an implicit tbody element, so what ends up being the sibling of the caption is that tbody and not the tr:
.myTable caption + tbody th:first-child
As an aside, if your th elements reside in a header row they should ideally be contained in a thead element and the data rows contained in explicit tbody element(s):
<table class=myTable>
<caption>Table with header group</caption>
<thead>
<tr><th>Header<th>Header
<tbody>
<tr><td>Row 1<td>Row 1
<tr><td>Row 2<td>Row 2
</table>
And selected using
.myTable caption + thead th:first-child
You're forgetting about the <tbody> element which wraps the <tr> element. Even though not specified in your (otherwise invalid) HTML, the <tbody> element is automatically implemented by the browser as a way of validating this, so instead of:
<caption>
<tr>
You end up with:
<caption>
<tbody>
<tr>
As seen in this element inspector capture below:
To select the very first <tr> element after a <caption> element, you can instead use:
caption + tbody tr:first-child {
...
}
JSFiddle demo.

Inbox Table Like Gmail - Fixed Row Height

I'm writing an angular email app and have used bootstrap tables in my mail template.
The body of the message is large and I would like to limit this to be just a single line, something similar to how gmail does it. Right now, my cell auto sizes which increases the size of the overall row. I used a couple of angular filters to limit the characters but I don't think that's all that Gmail is doing. There is some sort of an overflow hidden applied to the table row and also the height of each row is consistent.
How do I tweak my table css so that the row does not auto size when the cell data is a lot?
My HTML Code : http://pastebin.com/13jd9EfqI'm using the latest version of bootstrap css.
I know you'd want overflow: hidden and white-space: nowrap styles. If you want you can also add the text-overlow: ellipsis style for a nice effect. You can use table-layout: fixed to ignore the size of the contents of the cells and only look at the heading sizes, otherwise automatic column sizing can take into account the full width of the string (fiddle):
table.special { table-layout: fixed }
table.special th { width: 20% }
table.special th.content { width: 40% }
table.special td {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis
}
On your <tr> tags you should add style="width:[desired width]" so they don't resize, example:
<table class="table table-responsive table-striped table-hover">
<thead>
<tr>
<th style="width: 100px">MessageID</th>
<th style="width: 100px">Sender</th>
<th style="width: 100px">Content</th>
<th style="width: 100px">Date</th>
</tr>
</thead>
<tbody>
<tr ng-click="changeRoute('mail',message)" ng-repeat="message in mails.messages | filter:search | orderBy:sortField:reverse">
<td>ID</td>
<td>Sender</td>
<td>Content</td>
<td>Date</td>
</tr>
<tr ng-click="changeRoute('mail',message)" ng-repeat="message in mails.messages | filter:search | orderBy:sortField:reverse">
<td>ID</td>
<td>Sender</td>
<td>Content</td>
<td>Date</td>
</tr>
</tbody>
</table>
You can change the text of the <td> tags and it won't resize. You might want to add a padding to the left on your <td> tags so they are more 'inline' with the <tr> tag's text. DEMO

How to add padding to the top and bottom cell of a dynamically generated table?

I have a dynamically generated table i.e. the contents of it's cells are drawn from a database and each row is created depending on how many rows are in the database.
Each cell has a rounded border and padding, say of 2px.
The effect I want is that all cells look evenly spaced and padded vertically.
The problem is, and I haven't been able to solve this Googling or looking through Stack Exchange, that the top and bottom cells appear to have less 'top' and 'bottom' padding resp. than the other cells as they do not have the added padding of an 'adjoining' cell.
Is there a way to add extra 'padding-top' to the top cell only and 'padding-bottom' to the bottom cell only, or am I going about this the wrong way?
ps: the other consideration is that the table is enclosed with a border, so the solution needs to add space in a way that can maintain the existing borders (or have them applied).
pps: the code structure of the table is:
<table cellpadding="0" cellspacing="0" border="0" class="display" id="example">
<thead>
<tr>
<th width="268px">column one</th>
<th width="156px">column two</th>
<th width="188px">column three</th>
<th width="70px">column four</th>
<th width="62px">column five</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5" class="Tables_empty">loading data</td>
</tr>
</tbody>
<!--<tfoot>
<tr>
<th>column one</th>
<th>column two</th>
<th>column three</th>
<th>column four</th>
<th>column five</th>
</tr>
</tfoot>-->
</table>
Exactly which cells?
For all of the cells in the first and last rows:
table#example tbody tr:first-child td, table#example tbody tr:last-child td { padding: 10px 5px } /* moar padding */
For the first and last cell of every row:
table#example tbody tr td:first-child, table#example tbody tr td:last-child { padding: 10px 5px } /* moar padding */
Hi now used to this in your css
td{
padding:xxpx xxpx xxpx xxpx; // acording to your design
}

Resources