Regarding showing a button when you hover over HTML table row - html

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>

Related

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; }

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;
}

Truncating text within a span within a table

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; }

TD Hover will not work

I have the following CSS:
td: hover {
background-color:red;
}
td {
cursor: pointer;
background-color: rgb(150,150,150);
}
and my HTML is just:
<table>
<tr><td> </td></tr>
</table>
I can't get the hover to work. Why is that?
:hover is a pseudo-selector, and everything beginning with : is such (e.g. :active, :before etc.).
This can be confused with specifying values:
something: value;
So you need to think about pseudo-selectors as separate objects, not a value.
That's why you need to fix your td: hover so it looks like td:hover.
Note that if you put a space after td like so:
td :hover { ...
This is equal to:
td: *:hover { ...
and therefore will select all items descending from td and apply a style on hover to them (see this example).
Remember, spaces have a meaning in CSS.
You need to remove the space before :hover:
td:hover {
background-color: red;
}
You just need to remove the space between td :hover as the <td> has no descendants ..
td:hover will work
http://jsfiddle.net/xwYTa/

Css hovering link show table

So I am trying to make a dropdown menu where when hovering a link. A table is shown underneath the link. I don't understand why it wont work. Check out the fiddle link.
FIXED LINK
http://jsfiddle.net/ThobiasN/Pt3db/
Html code example:
<a class='nav' href='#'>Hover me</a>
<table>
<tr>
<td class='dropdown'><p>Show me</p></td>
</tr>
</table>
Css code example:
td.dropdown
{
display:none;
}
a.nav:hover > table
{
display:block;
}
Because the table isn't a child of the link.
The sign > in CSS is equivalent to "direct child of"
Try to put the table inside of the link.
<table> is a sibling to link element. Use + for operating over the sibling.
a.nav + table {
display: none;
}
a.nav:hover + table {
display: block;
}
I think at the end you would need to use some Javascript code to achieve that, but what you are doing wrong is this:
> simbol is for direct child
You want to set display: none for the table element, not the td
Solution:
change the > symbold for this one: + to get the next element
change a little bit your css
HTML
<a class='nav' href='#'>Hover me</a>
<table>
<tr>
<td class='dropdown'><p>Show me</p></td>
</tr>
</table>
CSS
table{
display:none;
}
a.nav:hover + table{
display:block;
}
JSFiddle
http://jsfiddle.net/Pt3db/5/
Plus advices
Use an unordered list instead table (table for tabular data)
You wouldn't be able to click on the subnav elements, so that's why I think you would need some Javascript
Out there are a lot of good navigation plugins that you can use, don't reinvent the wheel at least you are learning ;)
a.nav:hover > table means that table should be inside a.nav. First of all don't use table here, use ul better and put it inside a.nav
<a class='nav' href='#'>Hover me
<ul>
<li>Show me</li>
</ul>
</a>
This is the proper way to do it, CSS:
a.nav + table tr td.dropdown
{
display:none;
}
a.nav:hover + table tr td.dropdown
{
display:block;
}
You need to hide and show the same element, if you hide a table, don't show a TD, and vice versa
Alternatively, show and hide table instead of TD, CSS:
a.nav + table
{
display:none;
}
a.nav:hover + table
{
display:block;
}
One more thing to keep in mind, + refers to sibling elements, > refers to direct child
Working with css Fiddle
It seems to work either way but here is the way that I prefer
even though it's not css:
$('.nav').hover(function () {
$('table').css('display', 'block');
});
table{
display:none;
}
HTML Code
<a class='nav' href='#'>Hover me </a>
<table class='dropdown'>
<tr>
<td ><p>Show me</p></td>
</tr>
</table>
CSS Code
table.dropdown
{
display:none;
}
a.nav:hover + table
{
display:block;
color: green;
}