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;
}
Related
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>
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; }
I am trying to change the background color of Product_image when i hover the whole Table name.
The result i am trying to achieve is when the table changes color on hover, the product image td to change also but with an other color.
I saw similar posts: Make a div css change when hover an other div
But didn't worked on me.
HTML:
<div class="row">
<table class="Tablename">
<tbody><tr>
<td class="Product_image"><div class="Product_image"><a title=""><img src=""></a></div></td>
<td class="Product_name"><div class="Product_name"><a href=""</a></div></td></tr>
</tbody></table>
<div class="clear"></div>
</div>
CSS:
.Tablename:hover{ background-color:#fff}
.Tablename:hover + .Product_image {
background-color:#21825B !important;
}
I am trying to achieve this only with css.
Thanks in advance.
Skip the + sign. Its the adjacent sibling selector. The div you want to change is a child of the table, not a sibling.
I did a similar thing with my ul li structure. Here is the example
#main_nav.sf-menu li ul li:hover a{ color:#fff;}
so in your case it should
.Tablename:hover{ background-color:#fff}
.Tablename:hover Product_image {
background-color:#21825B !important;
}
Remove the + sign:
.Tablename:hover {
background-color: #fff
}
.Tablename:hover .Product_image {
background-color: #21825B !important;
}
See this fiddle.
Explanation: The + sign selects only adjacent siblings. See this small fiddle to get an understanding of this selector.
Well you are very close to the right solution. Try this:
remove the "+" symbol and make the row like that:
.Tablename:hover td.Product_image {
background-color:#21825B !important;
}
So you say: on table hover change the background color of the td with class "Product_image"
you even do not need the !important
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;
}
I found this solution here earlier.
.hiding {
display: none;
}
.trigger:hover + .hiding {
display:table-row;
}
It hides a table row then displays it when hovering over another table row (class trigger).
Question: I would like to have class hiding to show when it hovers over itself also. Currently it goes back to display:none when you are no longer hovering over class trigger.
You are using + which is an adjacent element selector, what I would suggest you is wrap the element .hiding inside another element say class .test and than alter your selectors like
.test .hiding {
display: none;
}
.test:hover .hiding {
display: table-row;
}
.trigger:hover + .test .hiding {
display:table-row;
}
So what we are doing here is we are hiding the element nested inside the .test which in this case is .hiding and than we use the second selector with :hover to reveal the .hiding when element with .test is hovered(As it is present, but empty as .hiding is display: none;) and last but not the least we add .test after + in 3rd declaration, just to be sure it doesn't break the rules as .hiding is no more adjacent to .trigger, we have .test as an adjacent element to .trigger
The only option I can think of is to wrap each group of .trigger and .hiding elements within a tbody, and base the show/hide behaviour on the the :hover of that tbody:
HTML:
<table>
<tbody>
<tr class="trigger">
<td>text</td>
</tr>
<tr class="hiding">
<td>hidden text</td>
</tr>
</tbody>
<!-- and so on... -->
</table>
CSS:
tbody .hiding {
display: none;
}
tbody:hover .hiding {
display: table-row;
}
JS Fiddle demo.
You cant do this with css only. You need jquery or javascript
try this
$(document).ready(function(){
$(".trigger").hover(function () {
$(this).css({"display" : "table-row"});
//or u can add class like this
//$(this).addClass("");
},function () {
//if you want return back, you can do here
});
});
If you do not return hover function, It will keep that hovering state.