Is this lengthy pseudo class combination a valid statement? - html

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.

Related

Possibility to trigger only child for 2 div's where one div is hidden

Is it possible to have the only-child css property trigger. When there are two children for a div but one of them is hidden using css?
So I tried
<div class"hide-if-one-child">
<div>Hi, am I the only one?</div>
<div class="hide"></div>
</div>
With css
.hide:empty {
display: none;
}
.hide-if-one-child:only-child {
display: none;
}
So I supposed that because the second div was hidden, it might hide the top most div, as there is only one child "displayed". I suppose, that it the display:none does not do this though. Is there a way to do this using only css?
As #niorad pointed out you could use has pseudo-class but be aware that the current browser support is not that great
.hide-if-one-child:has(div:empty) {
border: solid 2px black;
/*display: none*/
}
<div class="hide-if-one-child">
<div>Hi, am I the only one?</div>
<div class="hide"></div>
</div>
<div class="hide-if-one-child">
<div>Hi, am I the only one?</div>
<div class="hide">No you're not</div>
</div>

Displaying div on hover in a different place

I know how to display one div when you hover over another using the CSS:
.showme {
display: none;
}
.showhim:hover .showme {
display: block;
}
<div class="showhim">HOVER ME
<div class="showme">hai</div>
</div>
But the new div is displayed underneath the hover div.
How can i have a div that when you hover it, displays another div that may be somewhere else on the page e.g above the hover one.
Rather than it displaying under the hover div.
If your HTML still looks like
<div class="showhim">HOVER ME
<div class="showme">hai</div>
</div>
In that case, you can just assign an absolute or fixed position to the div with class showme and still use the same CSS.
If the showme div cannot be a child of the showhim div, then you can try placing it as a sibling.
<div class="showhim">HOVER ME</div>
<div class="showme">hai</div>
Once that is done, you can modify your CSS in the following manner
.showme {
display: none;
}
.showhim:hover ~ .showme {
display: block;
}
The ~ can be used to select sibling elements that appear after the current element.
You can do something like this:
.showhim{
margin-top:50px;
}
.showme {
display: none;
}
.showhim:hover .showme {
display:block;
border:1px solid red;
position:absolute;
top:0;
left:0;
font-size:25px;
}
<div class="showhim">HOVER ME
<div class="showme">hai</div>
</div>
If Javascript is an option, you can easily toggle the display property like this:
var showmeElement = document.getElementsByClassName('showme')[0];
function toggleSibling(shouldShow) {
if(shouldShow) {
showmeElement.style.display = 'block';
} else {
showmeElement.style.display = 'none';
}
}
.showme {
display: none;
}
<div class="showme" onmouseover="toggleSibling(true)" onmouseout="toggleSibling(false)">B</div>
<div class="showhim" onmouseover="toggleSibling(true)" onmouseout="toggleSibling(false)">A</div>
Otherwise, with CSS, the only way to target showme using showhim is by sibling / children selectors, with showhim being higher in hierarchy (children) or simply higher in DOM (as siblings).
Keep in mind that CSS can not go upwards in DOM in order to style elements conditionally, but only downwards.
Basically you want to shift the child div above its parent when the parent is hovered. If you know about positioning then you can use it. If you don't know then follow this code snippet.
div{
height: 30px;
}
.parent:hover .child{
position: relative;
bottom: 30px;
}
.parent:hover + .brother{
position: relative;
left: 30px;
}
<div class="parent">
hoverme
<div class="child">hi</div>
</div>
<div class="brother">brother</div>
Here I assigned the child a relative position which allows you to move it relative to its current position and bottom property pushes it above 30px. Here if you don't want any overlapping then you will have to keep account for the height of parent or in this case parent div. relative position will be better then absolute. Also sibling movement is possible and is shown in the css.

Is there an un-adjacent selector in CSS?

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 +.

Why can't I select the first div with the class 'offer'?

I'm trying to set the background color of the first div with the class offer. I thought .offer:first-child would do the trick, but that isn't working.
I've also tried using :nth-child(1), but that's not working either.
Any suggestions is greatly appreciated.
My fiddle: http://jsfiddle.net/MNQar/
CSS
.offer:first-child { background-color: indianred; }
.special-offers .title,
.special-offers .offer,
.special-offers .more {
height: 200px;
}
[class*="column"] {
display: inline;
float: left;
margin: 0;
}
.column2 { width: 190px;}
.column3 { width: 285px;}
HTML
<div class="row row-spacer special-offers">
<div class="column2 title">
<h2>Offers</h2>
</div>
<div class="column3 offer padding">
<div class="date">10. June</div>
<h3>Høyer tømmer lageret!</h3>
</div>
<div class="column3 offer padding">
<div class="date">10. June</div>
<h3>Super salg hos Vivikes</h3>
</div>
<div class="column1 more">
<div class="caret"></div>
More offers
</div>
</div>
.offer:first-child means "An element With the class 'offer' that is the first child beneath its parent", not "the first child with class 'offer'".
I believe you have to re-think how you do this. For example, stick a separate class to the first child or something, then use a selector like .offer.highlight.
CSS Only
This should work:
.offer { background-color: #ccc; }
.offer ~ .offer {background-color: transparent; }
It first sets all .offer elements to have a background color, then uses the sibling selector (~) to undo it for all subsequent .offer elements. Kind of a hack but it should be okay if you're not willing to use javascript. See here for a much more complete explanation: CSS selector for first element with class
And here's a fiddle: http://jsfiddle.net/MNQar/4/
JS
Alternatively, this is really easy to do with Javascript: $(".offer").eq(0).css("background-color","#ccc");
Fiddle: http://jsfiddle.net/MNQar/6/
The problem is that there is a div that precedes the first offer, making it the second element, not the first. The best solution is to give the first offer a different class, offer-first and use that. If that's not possible and the first offer is always the second child, you can use :nth-child(2)
Using :nth-child(2)
http://jsfiddle.net/MNQar/3/

change color of div and its siblings on hover w/o javascript

I have two divs floated next to one another:
<div id="parent">
<div id="child_1" style="float:left"> content </div>
<div id="child_2" style="float:left"> content </div>
<div style="clear:both"></div>
</div>
When either div is hovered over, I'd like to change the colors of both divs (to something different). Say, one yellow, the other red. Is there a way to do this? I put the div id="parent" in there thinking that I could do something when that is hovered over; change the divs with this id (or class) to this color within the parent. But I don't really know if this is possible. Also, jquery hover events always seem very delayed with respect to css, so I am trying to avoid using a script. Thanks much!
div#parent:hover div#child_1 {
color: red;
}
div#parent:hover div#child_2 {
color: yellow;
}
Add a class to child_1 and child_2, call it "children" or whatever you want. Then use this CSS:
.children:hover #child_1 { color: red; }
.children:hover #child_2 { color: yellow; }