Truncating text within a span within a table - html

I have a table setup to truncate text perfectly.... until I wrap the text in that table into a div. See this JSFiddle as an example: http://jsfiddle.net/3DKMJ/
This works for truncating the text in the cell:
<table>
<tr>
<td>Text</td>
</tr>
</table>
This does not work for truncating the text in the cell:
<table>
<tr>
<td><div>Text</div></td>
</tr>
</table>
Here is my css:
table {border:1px solid #000; width:100px;table-layout: fixed;}
td { width:100px;white-space:nowrap; overflow:hidden; text-overflow: ellipsis; }
The thing about the div is that it still prevents the text from wrapping, and the text is just hidden, but the ellipses that I have set to show don't show with the div attached.
Any ideas how to get this to work when there are div's within the table?
[EDIT] As mentioned, I could add td, td div { to it and that will work. I realized this after posting, my problem seems to be more specific. I actually have a span that is being displayed as an inline block. I assumed it was the block part that was causing problems, but I guess it is the fact that it is a span with an inline block. See this upadted fiddle: http://jsfiddle.net/P2PZW/2/

You could use display:inline; on the div elements in question.
jsFiddle here.
In reply to question edit:
Use display:inline instead of display:inline-block on your td span.
jsFiddle here.
In reply to comments:
If you really need to keep it as display:inline-block, you can do it like this:
td span {
display:inline-block;
text-overflow:ellipsis;
overflow:hidden;
width:100%;
}
jsFiddle here.

Try
td, td div { width:100px;white-space:nowrap; overflow:hidden; text-overflow: ellipsis; }
instead
td { width:100px;white-space:nowrap; overflow:hidden; text-overflow: ellipsis; }

Related

Regarding showing a button when you hover over HTML table row

I have created an HTML table, with one column dedicated to a button that's invisible by default. When you hover over a row, I have the corresponding button become visible. This all works fine, and here's an example of the HTML and CSS.
HTML:
<table>
<tr>
<td></td>
<td></td>
<td><button class="btn btn-danger btn-sm hidden-button">Delete</button></td>
</tr>
</table>
CSS:
.hidden-button {
opacity:0;
}
td:hover .hidden-button {
opacity:1;
}
My question though, is why does this work? I was experimenting, but completely expected all of the buttons with class .hidden-button to become visible. Could someone take a second and explain to me why this is not the case? Thank you!
td:hover .hidden-button applies your opacity: 1; to elements with the hidden-button class nested under each given td that is in the hover state.
your below CSS code applying globally on all TD
td:hover .hidden-button {
opacity:1;
}
td:hover .hidden-button actually refers to only the hidden-button which is present inside the td over which your mouse is hovering. So only this one element will appear when your mouse hovers over the td element.
In CSS, you come to the class of parent to child by reading the code from left to right.
The reason this works is because your specifically targeting ALL td elements inside of your html, so whenever you hover over a td, you target that td element of all td elements inside of the table.
.box {
height:100px;
width:100px;
background-color:black;
margin:10px;
float:left
}
.box:hover {
background-color:red
}
<div class="box box1">1</div>
<div class="box box2">2</div>

display table cell none in style tag

I might be missing something really obvious, however consider the following code (tested in Edge and Chrome):
<head>
<style>
.table td { display:table-cell; }
.hide { display: none; }
</style>
</head>
<body>
<table class="table">
<tr>
<td class="hide">This is supposed to be hidden</td>
</tr>
</table>
</body>
Here is a JSFiddle demo as well.
Why is the <td> child ignoring the display:none?
Now, I know that, for example, removing the .table class or in-lining <td style="display:none"> will get me the desired outcome (hiding the cell).
I'm interested in understanding the logic of this behivour.
Why is the child ignoring the display:none?
Because .table td is more specific as .hide. You ran into a concept called css specifitiy.
Take a look here: https://specificity.keegan.st
The actual reason is,
You can't add both the display:table-cell; and display: none; to the same DOM property.
In this case, you're giving two different values for the same property where CSS gives the importance to the display:table-cell;
Check out the another answer given here which speaks about 'CSS Specificity'.
Two ways to overcome this issue.
One is adding the !important tag for the style which you want to apply that is a bad practice.
Another solution is adding visibility: hidden which will hide the element from the view.
It's because .table td { display:table-cell; } is the closest css selector to the td than .hide { display: none; } so you can solve this by adding td.hide { display:none; }

Child style overriden by parent style CSS (different issues)

Sorry.. I'm just a little bit confused with other answer in SO..
I have 2 tables,
and one of them rendered inside a table. (table in table)
<table class="master">
<tr>
<td>ID</td><td>Name</td><td>Information</td>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>
<table class="detail">
<tr>
<td>ID</td><td>Order</td>
</tr>
<tr>
<td>1</td><td>CA09-WYOMING-BR</td>
</tr>
</table>
</td>
</tr>
</table>
style
<style>
table.detail{
border:1px solid red;
border-collapse: collapse;
/* etc...about 20 lines code */
}
table.detail td{
border:1px solid red;
background:red;
/* etc...about 20 lines code */
}
table.master {
border:1px solid black;
border-collapse: collapse;
}
table.master td {
border:1px solid black;
background:gray;
}
</style>
And the detail table style not rendered properly because overridden by parent table CSS.
I know there are !important tag to make child CSS style not overridden, but if the CSS style about 20 lines of code should I add '!important' tag to all of them?
?
http://jsfiddle.net/vxdM3/
No need for !important here... Reverse the order of your styles. Put the css for the master table before detail. The way you have it is that the css for detail is being applied first then the master css is applied overriding what was set for detailed.
re-orded css fiddle
Or if you don't want to move css around you can update the selectors to table.master table.detail{} and table.master table.detail td{}.
updated selector fiddle
As a general rule, I use > to avoid styling nested elements unintentionally.
.master > tr > td
{
....
}
Actually, since I always use tbody, it is more like:
.master > tbody > tr > td
I don't like surprises, so I try to be careful to write css that is very explicit on what it is styling. Sure, it is a bit slower, but I find it is insignificant to the user experience and I can get stuff done a lot quicker. Others may do it differently, of course.

html table white-space: nowrap not working?

I have a KnockoutJS template that creates a input[type=text] and a select next to each other with no <br/> inbetween. However it puts a linebreak between even with white-space: nowrap; I'm currently testing in chrome.
CSS:
table.grid tbody tr td {
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 0px;
white-space: nowrap;
vertical-align: top;
}
Question: Why isn't white-space: nowrap; not working? Is there a fix to this or a way around it?
As noted above, this may be due to either/both your input and/or select elements being set to display at block level using display:block which will force them onto a 'new line' instead of displaying inline and following through with the anticipate nowrap behaviour
Demo Fiddle
I had a div inside my td. Inside the div had 2 button. Even with white-space:nowrap, display:inline-block and position:relative applied to all these elements it did still wrapped.
For me what did the trick was removing a float:left that was being applied to the buttons, from another class, since it "kind of force" the browser to act as those elements were display:block.

How to add CSS if element has more than one child?

I have td tags and a several div inside td:
<td>
<div class='test'></div>
<div class='test'></div>
</td>
<td>
<div class='test'></div>
</td>
I want to add margin-bottom to div if there are more than one in the td. How can I do this with the css?
You can't directly 'count' total numbers of elements in CSS, so there's no way to only apply the class if there's 2 or more divs (you'd need JavaScript for that).
But a possible workaround is to apply the class to all divs in the td...
td > div {
margin-bottom: 10px;
}
... and then override/disable it with a different style when there's only one element. That indirectly lets you add the style when there's 2+ more child elements.
td > div:only-child {
margin-bottom: 0px;
}
Alternatively you can apply to every div after the first one, if that happens to work for your situation.
td > div:not(:first-child) {
margin-bottom: 10px;
}
Edit: Or as Itay says in the comment, use a sibling selector
td > div + div {
margin-bottom: 10px;
}
td > div:not(:only-child) { margin-bottom: 10px; }
Well actually you can do this with css using the nth-last-child selector
FIDDLE
So if your markup was like this:
<table>
<td>
<div class='test'>test</div>
<div class='test'>test</div>
</td>
</table>
<hr />
<table>
<td>
<div class='test'>test</div>
</td>
</table>
CSS
div:nth-last-child(n+2) ~ div:last-child{
margin-bottom: 40px;
}
... the above css will style the last div element only if there exists a container that has at least 2 child divs
Just to see how this works better - here's another example fiddle
did a nice little combo with the accepted answer
only applies style to the first child when its NOT the only child.. so when there is more than 1
td > div:not(:only-child):first-child { }
CSS-Has has limited browser support:
but here you go:
td:not(:has(div:first-child:last-child))
bonus:
td:not(:has(div:only-child))
i think there is no way to add the 10px margin to each div inside a td without the use of css3.
so a solution would be to use javascript and check if there are more than 1 div's inside the td and then if yes add a special class.
css
.myMarginClass div{
margin-bottom:10px;
}
js
var td=document.getElementsByTagName('td'),
l=td.length;
while(l--){
if(td[l].getElementsByTagName('div').length>1){
td[l].className='myMarginClass';
}
}
else for modern browsers the proper solution is the :only-child
proposed by #mikel
If there are other kinds of elements inside the td, you can still select the only div with this :only-of-type
<td>
<div class='test'></div>
<div class='test'></div>
</td>
<td>
<div class='test'></div>
<p class='test'></p>
</td>
CSS
td > div:only-of-type{
margin-bottom:10px;
}