JS: not able to understand behaviour of hover css selector - html

When I hover the element with class top_bottom_b1, the element with class top_bottom_b2 have to hide. I need to achieve this using css selector. I'm not sure why below code doesn't work.
.top_bottom_b1{
display: block;
width:50px;
height:50px;
background-color:red;
}
.top_bottom_b2{
display: block;
width:50px;
height:50px;
background-color:yellow;
top: 8px;
}
.top_bottom_b1:hover .top_bottom_b2{
display: none;
}
<body>
<div class="top_bottom_b1"></div>
<div class="top_bottom_b2"></div>
</body>
EDIT:
Even if there are multiple elements(as shown below) between and , the css selector (hover) should work.
<div class="top_bottom_b1"></div>
<div></div>
<div></div>
<div></div>
... <!-- N number of divs -->
<div class="top_bottom_b2"></div>

Use the adjacent sibling selector + or if their not director siblings use the general sibling selectors - ~:
.top_bottom_b1 {
display: block;
width: 50px;
height: 50px;
background-color: red;
}
.top_bottom_b2 {
display: block;
width: 50px;
height: 50px;
background-color: yellow;
top: 8px;
}
div > .top_bottom_b2 {
background: blue;
}
.top_bottom_b1:hover ~ .top_bottom_b2 {
display: none;
}
.top_bottom_b1:hover ~ div > .top_bottom_b2 {
display: none;
}
<div class="top_bottom_b1"></div>
<div>I'm in the middle</div>
<div class="top_bottom_b2"></div>
<div>
<div class="top_bottom_b2"></div>
</div>

Related

Changing adjacent elements on hover css

Please tell me why when you hover over the third div, the size of the second div does not change, as when you hover over the first div.
#block {
width: 50%;
white-space: nowrap;
}
.div {
display: inline-block;
text-align: center;
}
div:nth-child(1) {
width: 10%;
background: red;
}
div:nth-child(2) {
width: 80%;
background: blue;
}
div:nth-child(3) {
width: 10%;
background: green;
}
div:nth-child(1):hover {
width: 80%;
}
div:nth-child(1):hover + div:nth-child(2) {
width: 10%;
}
div:nth-child(3):hover {
width: 80%;
}
div:nth-child(3):hover + div:nth-child(2) {
width: 10%;
}
<div id="block">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
</div>
Quoting from Mozilla Developers Website For More info Check the link at the bottom
The adjacent sibling combinator (+) separates two selectors and
matches the second element only if it immediately follows the first
element, and both are children of the same parent element.
This means it will try to find a sibling of the same parent that is after the current selecting element not the sibling before the current One.
https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator

Toggle Div in other css Container

what goes wrong with my code? can anyone help me a bit?
want to show a div onclick other div.
nav div#showdiv {
width: 100px;
height: 100px;
background-color: #999;
outline: none;
cursor: pointer;
}
#hiddendiv {
display: none;
height: 200px;
background-color: #666;
color: #FFF;
}
nav div#showdiv:focus+section#hiddendiv {
display: block;
}
<nav>
<div id="showdiv">Click me</div>
</nav>
<section id="hiddendiv">
<div>Text</div>
</section>
I think I have some wrong selector code in the css. or is it not possible
to toggle a div in other container / div / section etc.
You cannot with just CSS.
This selector
nav div#showdiv:focus+section#hiddendiv
will not work because #hiddendiv is not a sibling of #showdiv, so you cannot target it with a +.
Also, clicking will not focus the element (unless it is an interactive element, like a button, or a input)
You can accomplish what you want by adding some Javascript that, as an example, add/remove a class after the click event.
document
.getElementById('showdiv')
.addEventListener('click', function() {
const hidden = document.getElementById('hiddendiv')
if (hidden.classList.contains('show')) {
hidden.classList.remove('show');
} else {
hidden.classList.add('show');
}
})
nav div#showdiv {
width: 100px;
height: 100px;
background-color: #999;
outline: none;
cursor: pointer;
}
#hiddendiv {
display: none;
height: 200px;
background-color: #666;
color: #FFF;
}
#hiddendiv.show {
display: block;
}
<nav>
<div id="showdiv">Click me</div>
</nav>
<section id="hiddendiv">
<div>Text</div>
</section>
You can use the jQuery toggle() method to toggle div on click.
$("#showdiv").click(function(){
$("#hiddendiv").toggle();
});
nav div#showdiv {
width: 100px;
height: 100px;
background-color: #999;
outline: none;
cursor: pointer;
}
#hiddendiv {
display: none;
height: 200px;
background-color: #666;
color: #FFF;
}
nav div#showdiv:focus+section#hiddendiv {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<div id="showdiv">Click me</div>
</nav>
<section id="hiddendiv">
<div>Text</div>
</section>
You can't use :focus ond div elements. Focus can only be used on elements that accept keyboard events or other user inputs.
You may want to try using javascript (jQuery) to do that:
$('#showdiv').click(function(e) {
$('#hiddendiv').show();
})
You can use .toggle() instead of .show() to switch between display: block; and display: none;

css active state for many elements

I have a div and inside this div there is an icon with background and text.
when clicking on this div I want to change 3 things:
the div background, the icon background and the text color.
how can I do it with CSS only?
http://jsfiddle.net/g1nrye8e/
<div class="click">
<div class="icon"></div>
<div class="text">text</div>
</div>
.click{
width: 200px;
height: 100px;
background: blue;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
Preserve clicked state using pure CSS
The best way to preserve the clicked state, without JavaScript is to
wrap your elements inside a <label>
immediately before the element you want to target place an invisible input checkbox
when the input becomes :checked target any first next sibling element using +* and change styles accordingly
Repeat the same rule for +*'s inner elements:
/* DEFAULT STYLES */
.div{
width: 200px;
height: 100px;
background: blue;
margin:10px;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
/* HIDE CHECKBOX HELPER */
label.click > input{ /* hide the input checkbox */
position:absolute;
visibility:hidden;
}
/* ACTIVE STYLES */
label.click > input:checked +* { /* (the next .div) */
background: #000;
}
label.click > input:checked +* .icon{
background: #c0ffee;
}
label.click > input:checked +* .text{
color: #f00ba4;
}
<label class="click">
<input type="checkbox"> <!-- :checked state changes +div styles -->
<div class="div">
<div class="icon"></div>
<div class="text">text</div>
</div>
</label>
<label class="click">
<input type="checkbox">
<div class="div">
<div class="icon"></div>
<div class="text">text</div>
</div>
</label>
Just add a class to the parent when it is clicked, then write more specific CS for that class.
Here's a running example.
document.querySelector(".click").addEventListener("click", function() {
this.classList.toggle("clicked");
});
.click{
width: 200px;
height: 100px;
background: blue;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
.clicked.click{
background: green;
}
.clicked .icon{
background: red;
}
.clicked .text{
color: blue;
}
<div class="click">
<div class="icon"></div>
<div class="text">text</div>
</div>
This is a different solution with only css, but you have to click to every element:
.click{
width: 200px;
height: 100px;
background: blue;
}
.icon{
width: 50px;
height:50px;
background: yellow;
display: inline-block;
}
.text{
color: #fff;
display: inline-block;
}
.click:focus{
background: red;
}
.icon:focus{
background: grey;
}
.text:focus{
background: black;
}
<div class="click" tabindex="1">
<div class="icon" tabindex="2"></div>
<div class="text" tabindex="3">text</div>
</div>
There is a great explanations about the tabindex and :focus without using JS. Check it out impressivewebs

CSS Only: Apply style only on non-hovered siblings

I have 3 boxes which look like the one in the example. I want to apply a certain style on the non-hovered boxes when a user hovers over a certain box (The boxes are always siblings).
Here is how it should work -
Hover over Box 1 - Box 2 and Box 3 should be greyed
Hover over Box 2 - Box 1 and 3 should be greyed
Hover over Box 3 - Box 1 and 2 should be greyed
.test {
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
.test:hover ~ .test {
width: 100px;
background-color: #ddd;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
<div class="test">
Box 1
</div>
<div class="test">
Box 2
</div>
<div class="test">
Box 3
</div>
I can get it working for Box 1. Can somebody help me how I can do it elegantly for Box 2 and 3.
Note: No jQuery or Javascript should be used (which would be a cakewalk in this case).
You can not select “upwards” with current CSS selectors, so 2 and 3 are not possible – not directly. You could put all elements into a common container element, and when that is hovered make all boxes gray, and then the actual box hovered blue again:
.test {
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
.container:hover .test {
background:#ddd;
}
.container .test:hover {
background-color: #009AFD;
}
<div class="container">
<div class="test">Box 1</div>
<div class="test">Box 2</div>
<div class="test">Box 3</div>
</div>
(No need btw. to repeat all those properties that stay the same in the hovered state.)
This however will also apply the hover effect when you are not directly hovering one of the boxes, but also when the container element is hovered in the margin between the boxes – so when in between the boxes, all three of them will become gray.
To fight that effect, you need to get a little creative: By not having the boxes laid out in normal flow, but positioning them absolutely instead, you can make the container element take up no space at all, so it won’t be hovered in the “margins” between the boxes. Hovering the boxes themselves however still triggers :hover for the container element, since the boxes are its children and therefor hovering them means hovering the parent element as well, even if the parent element is not “present” in that space where the mouse cursor is hovering over.
.container {
position: relative;
}
.test {
position: absolute;
top: 0;
left: 0;
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
text-align: center;
}
#box2 {
left: 110px;
}
#box3 {
left: 220px;
}
.container:hover .test {
background: #ddd;
}
.container .test:hover {
background-color: #009AFD;
}
<div class="container">
<div class="test" id="box1">Box 1</div>
<div class="test" id="box2">Box 2</div>
<div class="test" id="box3">Box 3</div>
</div>
Of course then you might have to use some additional trickery to keep following elements in normal flow at the same positions they would take, had the absolute positioning not taken the boxes out of flow (like giving the next element a margin-top or something).
And of course the whole thing only works this “simple”, because you want the color for the siblings of the hovered boxes to be the same. Would you wish for different colors for them, then additional trickery of sorts might be needed.
This will do it:
.test {
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
.parent:hover > div {
width: 100px;
background-color: #ddd;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
.parent:hover > div:hover {
background-color: #009AFD;
}
<div class="parent">
<div class="test">Box 1</div>
<div class="test">Box 2</div>
<div class="test">Box 3</div>
</div>
Enclose the divs in a parent div. Use this selector to change all the children: .parent:hover > div. And this selector to exempt the child that is being hovered: .parent:hover > div:hover.
.test:hover ~ .test selects .test elements which are following siblings of a hovered .test element.
Instead, you can try :not(). The selector below will match all .test elements which are not hovered:
.test:not(:hover)
.test {
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
.test:not(:hover) {
background-color: #ddd;
}
<div class="test">
Box 1
</div>
<div class="test">
Box 2
</div>
<div class="test">
Box 3
</div>
If you only want to match the non-hovered elements when one is hovered, you can use
:hover > .test:not(:hover)
.test {
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
:hover > .test:not(:hover) {
background-color: #ddd;
}
<div class="test">
Box 1
</div>
<div class="test">
Box 2
</div>
<div class="test">
Box 3
</div>
Alternatively, if you want it to work on old browsers that don't support :not(), you can apply the style to all elements, and reset in in the hovered element.
.test {
/* Set styles for non-hovered */
}
.test:hover {
/* Set styles for hovered */
}
.test {
width: 100px;
background-color: #ddd;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
.test:hover {
background-color: #009AFD;
}
<div class="test">
Box 1
</div>
<div class="test">
Box 2
</div>
<div class="test">
Box 3
</div>
.test {
/* Set styles for non-hovered */
}
:hover > .test:hover {
/* Set styles for non-hovered when another is hovered */
}
.test:hover {
/* Set styles for hovered */
}
.test {
width: 100px;
background-color: #009AFD;
height: 100px;
display: inline-block;
margin-right: 5px;
text-align: center;
}
:hover > .test {
background-color: #ddd;
}
.test:hover {
background-color: #009AFD;
}
<div class="test">
Box 1
</div>
<div class="test">
Box 2
</div>
<div class="test">
Box 3
</div>

How can I make two boxes turn one color when you hover over either? [duplicate]

This question already has answers here:
Is there any way to hover over one element and affect a different element? [duplicate]
(2 answers)
How to affect other elements when one element is hovered
(9 answers)
Closed 8 years ago.
Currently, when you hover over the blue box both turn yellow, but when you hover over the red box, only it turns yellow.
I need both of them to turn yellow when you hover over either the blue, or the red.
This is as far as I have gotten:
<!DOCTYPE html>
<html>
<head>
<style>
#one {
background-color: blue;
width: 50px;
height: 50px;
float: left;
}
#two {
background-color: red;
width: 50px;
height: 50px;
float: left;
margin-left: 100px;
}
#two:hover {
background-color: yellow;
}
#two:hover ~ #one {
background-color: yellow;
}
#one:hover {
background-color: yellow;
}
#one:hover ~ #two {
background-color: yellow;
}
</style>
</head>
<body>
<div id="one"></div>
<div id="two"></div>
</body>
</html>
here is solution without js
<div class="container">
<div class="one"></div>
<div class="two"></div>
</div>
JSFIDDLE
Demo
just this
.container:hover div {
background: yellow;
}
Using :before to simulate a hovered div #one...
HTML stays the same
DEMO
CSS
#one {
background-color: blue;
width: 50px;
height: 50px;
float: left;
}
#two {
background-color: red;
width: 50px;
height: 50px;
float: left;
margin-left: 100px;
}
#one:hover, #one:hover ~ #two, #two:hover {
background-color: yellow;
}
#two:before {
content:'';
display:none;
width:50px;
height:50px;
margin-left:-150px;
background-color: yellow;
}
#two:hover:before {
display:block;
}
If you want hover to applied only when child are hovered, then pointer-events can be a way to do this: DEMO
your CSS turns to be more like :
#one {
background-color: blue;
width: 50px;
height: 50px;
float: left;
}
#two {
background-color: red;
width: 50px;
height: 50px;
float: left;
margin-left: 100px;
}
.parent {
pointer-events:none;
overflow:hidden;/* for float , for DEMO purpose to extend body or parent as there would be more content behind childs in real situation. */
}
.parent div {
pointer-events:auto;
cursor:pointer
}
.parent:hover div#one,
.parent:hover div#two
{
background-color:yellow;
}
How does this works ?
pointer-events:none , kills mouse events on parent. Reset to normal to childs.
If you hover a child, then the parent is hovered and the CSS rules parent:hover can be applied.