Is there an un-adjacent selector in CSS? - html

I'm building a website where I want to hover on certain images and have them display other divs.
I found this JSfiddle which worked well. http://jsfiddle.net/ZSZQK/
<div id="image"><img src="image.png"/></div>
<div id="hover">Test message</div>
#hover {
display: none;
}
#image:hover + #hover {
display: block;
}
Only I need to split my divs up, meaning they are no longer adjacent, like this. http://jsfiddle.net/Z2H66/
<div class="first-container">
<div class="image"><img src="image.png"/></div>
</div>
<div class="second-container">
<div class="hover">Test message</div>
</div>
.hover {
display: none;
}
.image:hover + .hover {
display: block;
}
What tools are at my disposal that are able to do what I'm asking?
Also note I changed my code to classes rather than ids, but that doesn't stop it working. My code doesn't work because the div hover and image are not adjacent.

Please see the modified version of your JSFiddle which uses Javascript and jQuery:
http://jsfiddle.net/scorchio/ZSZQK/288/
jQuery will let you handle hover events like this easily, the key is the following:
$(document).ready(function() {
// Hide on start
$("#hover").hide();
// Handle mouse over for image
$("#image").hover(function() {
// This one is when the mouse enters
$("#hover").show();
},
function() {
// ...and when it hides.
$("#hover").hide();
});
});

Well, ~ is a little less strict, but that's not going to help you here :(
With pure css, I think this is the best you can do:
.hover {
display: none;
}
.first-container:hover ~ .second-container .hover {
display: block;
}
See this post about css parent selectors (not implemented), and this link from one of the answers that has a javascript shim for it.
By the way, the ~ is adjacent, but not immediately adjacent, unlike the +.

Related

Is this lengthy pseudo class combination a valid statement?

This is my code:
.fontmenu .fontlist{
position: absolute;
bottom:30px;
display:none;
}
.fontbutton button:hover .fontmenu .fontlist{
display:block;
}
<div class="fontmenu">
<div class="fontbutton">
<button>fonts</button>
</div>
<div class="fontlist">
<div onclick="font(1)">Arial</div>
<div onclick="font(2)">Courier</div>
<div onclick="font(3)">Verdana</div>
<div onclick="font(4)">sans</div>
</div>
</div>
The CSS is not working. The list is not visible when I hover the button. I want to know whether the .fontbutton button:hover .fontmenu .fontlist{} is valid or not.
This is what you have used:
.fontbutton button:hover .fontmenu .fontlist{ }
This won't work
Why it won't work? Read on. I will explain. But first, lets see what will work.
Lets try using some selectors:
.fontbutton:hover + .fontlist {}
This WILL work
Let's see it in action:
.fontmenu .fontlist {
bottom: 30px;
display: none;
}
.fontbutton:hover + .fontlist {
display: block;
}
/* No need to include the wrapper fontmenu div,
just target the siblings, ie, fontbutton and fontlist.
The + selector must be used, otherwise, the browser will
think fontlist is the child of fontbutton */
<div class="fontmenu">
<div class="fontbutton">
<button>fonts</button>
</div>
<div class="fontlist">
<div onclick="font(1)">Arial</div>
<div onclick="font(2)">Courier</div>
<div onclick="font(3)">Verdana</div>
<div onclick="font(4)">sans</div>
</div>
</div>
Notice that the list becomes visible even if we hover to the right of the button. This is happening since we are targeting the div fontbutton and not the <button> element. So, the browser makes the list visible when we hover the div and not the button.
How to fix?
We need to change the html a little.
.fontmenu .fontlist {
display: none;
}
button:hover + .fontlist {
display: block;
}
<div class="fontmenu">
<button>fonts</button>
<div class="fontlist">
<div onclick="font(1)">Arial</div>
<div onclick="font(2)">Courier</div>
<div onclick="font(3)">Verdana</div>
<div onclick="font(4)">sans</div>
</div>
</div>
Look that I removed the .fontbutton class and made the <button> a sibling of .fontlist. So, now, you can see that the list is visible only when we hover the button.
Now you would say I could just add some selectors to your css. But I didn't because there's no way you could target <button> and then move down to .fontlist which is in a separate div.
.fontbutton > button:hover ? .fontmenu > .fontlist{ }
We will have a problem at the place of ?.
First, we need to go down to .button.
Move up to .fontbutton.
Add a + selector and switch to .fontmenu.
Move down to .fontlist.
After we move down to .button, we can't go up again to .fontbutton.
CSS doesn't have something like parent selector.
So, clearly, we can't use it that way.

How to apply css to three different classes hovering one of them

Here is my code.
<div class="start">start</div>
<div>middle-1</div>
<div>middle-2</div>
<div>middle-3</div>
...................
...................
<div>middle-n</div>
<div class="end">end</div>
I want to apply css to all div's when mouse hover the first div with class start.
With the current HTML structure you can use couple of sibling selectors for this.
.start:hover ~ div {
color: red; /* styles you want to apply */
}
/* reset styles back for all other divs after .end */
.start:hover ~ .end ~ div {
color: inherit;
}
Demo: http://jsfiddle.net/3c6V6/1/
However I would recommend to change HTML structure if you can. For example:
<div class="start">start</div>
<div class="middles">
<div>middle-1</div>
<div>middle-2</div>
<div>middle-3</div>
<div>middle-n</div>
<div class="end">end</div>
</div>
<div>after-1</div>
<div>after-2</div>
and CSS:
.start:hover + .middles > div {
color: red;
}
You would just have much more flexibility.
Demo: http://jsfiddle.net/3c6V6/2/
Could it be as simple as putting a parent container around it, and putting the hover on that, or do you wish to single out some of the siblings directly?
In this case, try putting :hover on the parent container like this:
.parent:hover div {/*style*/}
This is for your second version found in the comments: JSFiddle DEMO
div.start:hover~div.middles div:not(.end) {
font-weight: bold;
}
(This is for your original question):
div.start:hover~div:not(.end) {
font-weight: bold;
}
JSFiddle DEMO
This is where I found the information to do it. Didn't know there were so many CSS selectors.

Active page on a website?

I'm wanting to basically make it so that on my website when the user clicks on a navigation bar button it changes the image. Of which on the image I have set the text on the button to display in a different colour.
So far I've developed the following css:
#HomeOver
{
width: 188px;
height: 54px;
background: url("Images/Navbar_01.gif");
}
#HomeOver:active
{
background: url("Images/NavbarOver_01.gif");
}
#HomeOver:hover
{
background: url("Images/NavbarOver_01.gif");
}
The HTML then links the ID to the CSS to display the correct image.. But my problem is, on the "active", it doesn't seem to work, Can anyone suggest what is wrong with the coding? The hover works fine
:active pseudo only works when an element is kept clicked, as soon as you leave the click, the effect goes, you can achieve the active tabs, by either using client side scripting such as JavaScript/jQuery and assign a class to the intended element, or assign it by using server side scripting such as PHP.
Demo (How actually :active pseudo works)
Achieving this with jQuery...
Demo
var active_menu = $('nav a').click(function(){ //onclick of a nested inside nav
active_menu.removeClass('active'); //Remove all the classes first
$(this).addClass('active'); //Assign the class to the a which is clicked
});
#HomeOver.active {
background: url("Images/NavbarOver_01.gif");
}
Then just add the "active" class to the navigation button either through JavaScript or directly in the html for the corresponding page.
As Mr. Alien stated the pseude class :active does only work as long as you keep the mousebutton clicked. To achieve a permanent active state you will have to use jquery to change the class on click.
jsfiddle
js
$('div').click(function() {
$(this).toggleClass('active');
});
css
div:active,
div.active {
color: #f00;
}
or you have to give the acitve element the .active class when generating it serverside with php or so:
print '<div' . (active ? ' class="active"' : '') . '></div>'
If you don't wish to use JavaScript you can instead use input:radio instead.
HTML
<div id="links">
<label><input type="radio" name="links" /><div class="image"></div></label>
<label><input type="radio" name="links" /><div class="image"></div></label>
<label><input type="radio" name="links" /><div class="image"></div></label>
</div>
CSS
#links input {
display: none;
}
#links .image {
background: url("Images/Navbar_01.gif");
}
#links label:hover .image,
#links input:checked ~ .image {
background: url("Images/NavbarOver_01.gif");
}
See test case on jsFiddle.
Use .addClass and .removeClass on click using jquery

CSS: Show div using hover

I want to see 2nd div when mouse Over.
HTML
<a>Hover over me!</a>
<div class="ab">Some content</div>
<div class="abc">Some text here</div>
CSS
.abc {
display: none;
}
a:hover + .abc{
display: block;
}
The adjacent sibling combinator is not exactly what you want. It can only select the div with the class .ab, because it's directly following the anchor.
What you want is this:
a:hover ~ .abc {
/*...*/
}
This selects every .abc which is following a hovered anchor element, but it don't has to be directly before it.
Had some delay reaching SO so this is late. Here a fiddle for my answer: http://jsfiddle.net/digitalextremist/F5k4L/
The main issue here uses #kleinfreud's suggestion about an adjacent div but weaves in another approach to showing and hiding a div:
.abc {
opacity: 0;
}
a:hover ~ .abc{
opacity: 100;
}
This makes sure the space that div will take up is reserved to begin with, then showing it when needed.

How to change one element while hovering over another

I have looked at several other questions but I can't seem to figure any of them out, so here is my problem: I would like to have a div or a span, when you hover over it an area would appear and would be like a drop down.
Such as I have an div, and I want to hover over it and have it show some info about the item I hovered over
<html>
<head>
<title>Question1</title>
<styles type="css/text">
#cheetah {
background-color: red;
color: yellow;
text-align: center;
}
a {
color: blue;
}
#hidden {
background-color: black;
}
a:hover > #hidden {
background-color: orange;
color: orange;
}
</styles>
</head>
<body>
<div id="cheetah">
<p>Cheetah</p>
</div>
<div id="hidden">
<p>A cheetah is a land mammal that can run up 2 60mph!!!</p>
</div>
</body>
</html>
But this ^ doesn't seem to work, I don't know why... and if there is a way to do that in CSS, I would like to know, but I want any and all suggestions.
You can achieve this in CSS only if the hidden div is a child of the element you use for hovering:
http://jsfiddle.net/LgKkU/
You cannot affect a non-child element using :hover from within CSS2, which is supported by all common browsers.
You can affect a sibling element using CSS2.1 selectors, like so:
a:hover + .sibling { ... }
However, this only works for direct siblings. This means you could have HTML like this:
<p>Cheetah <span class="sibling">Blah Blah Blah</span></p>
Notice that the a and the span are direct siblings.
Here's a fiddle showing the siblings working: http://jsfiddle.net/vUUxp/
However, not all browsers support the CSS2.1 sibling selectors, so you need to decide based on your target audience if you can use this or not.
Edit: Corrected my mistake on the CSS version for the + selector: it's 2.1 that defines it, not CSS3. I also added a link showing browser support. Otherwise, the answer is the same.
Or, if you're open to it, use jQuery.
Something like this would work:
$("#element") // select your element (supports CSS selectors)
.hover(function(){ // trigger the mouseover event
$("#otherElement") // select the element to show (can be anywhere)
.show(); // show the element
}, function(){ // trigger the mouseout event
$("#otherElement") // select the same element
.hide(); // hide it
});
And remember to wrap this in a DOM ready function ($(function(){...}); or $(document).ready(function(){...});).
You can absolutely do this in CSS3 now using the ~ adjacent sibling selector.
triggerSelector:hover ~ targetSelector {
display: block;
}
For example, if you want a tooltip to appear when hovering over an adjacent button:
.button:hover ~ .tooltip {
display: block;
}