1

I'm trying to make the border-bottom disappear on ".option 1" when you hover ".option 2".

I have read some of the questions on this matter and even tried an example by Nicholas King (http://jsfiddle.net/2NEgt/3/) which was an answer on this topic: CSS :hover on other element?

After changing his code I noticed that I can do this if I do it on the ".option1" to remove the border on ".option2" but the same cannot be seen if it is the other way around. Is there an explanation for this? Since they are both inside the same div they should be sibling elements or am I thinking wrong?

Would really appreciate an explanation on this matter and if possible a solution that doesn't require JS.

Thank you in advance.

https://jsfiddle.net/jhcv1462/1/

#nav_bar {
  margin-left: auto;
  margin-right: auto;
  position: relative;
  color: black;
  display: flex;
  flex-direction: row;
}

.nav {
  width: 100%;
  height: 50px;
  transition: 0.33s;
  text-align: center;
  cursor: pointer;
}

.option1 {
  border-bottom: 2px solid #4387ff;
}

.option2:hover {
  border-bottom: 2px solid #4387ff;
}

.option2:hover+.option1 {
  border: none;
}
<div id="nav_bar">
  <div class="nav option1">
    <h2>Option 1</h2>
  </div>
  <div class="nav option2">
    <h2>Option 2</h2>
  </div>
</div>
Håken Lid
  • 22,318
  • 9
  • 52
  • 67
Markarove
  • 17
  • 5

3 Answers3

3

The answer of Luze is correct.. siblings ~ address only the following siblings... not the previous.

Hopefully, when siblings are fighting : you can address yourself to their parents...

Here is some working code :

#nav_bar{
    margin-left: auto;
    margin-right:auto;
    position:relative;
    color:black;
    display:flex;
    flex-direction: row;
}

.nav{
    width:100%;
    height:50px;
    transition:0.33s;
    text-align: center;
    cursor:pointer;
}

#nav_bar .option1 {
    border-bottom:2px solid #4387ff;
}

#nav_bar:hover .option1 {
    border-bottom: none;
}

#nav_bar .option1:hover {
    border-bottom:2px solid #4387ff;
}

#nav_bar .option2:hover,
#nav_bar .option2:hover ~ .option1 {
    border-bottom:2px solid #4387ff;
}

/* #nav_bar .option */
Nicolas HERMET
  • 138
  • 2
  • 10
1

siblings are considered only the elements following your element.

So Option 2 is a sibling of Option 1, because it has the same parent and comes behind Option 1.

But Option 1 isn't a sibling of Option 2, because Option 1 comes before Option 2.

You can select all siblings (all siblings that come after your element) using the ~ CSS-selector

Or you can select the first sibling which comes immediately after your element using the + CSS-selector like you have currently done.

But sadly it's currently not possible in CSS to select a sibling before an element. You could try to do something like this though. This person did find a workaround for this problem which might be useful for your case.

Luïs
  • 2,671
  • 1
  • 20
  • 33
0

You can accomplish this by targeting the parent. This works even with more than two children.

JSFiddle

#nav_bar {
    margin-left: auto;
    margin-right: auto;
    position: relative;
    color: black;
    display: flex;
    flex-direction: row;
}

.nav {
    width: 100%;
    height: 50px;
    text-align: center;
    cursor: pointer;
}

/* option1 is selected by default */
.option1 {
    border-bottom: 2px solid #4387ff;
}

/* remove all borders when the parent is hovered */
#nav_bar:hover .nav {
    border-bottom: none;
}

/* add border to the hovered child */
#nav_bar .nav:hover {
    border-bottom: 2px solid #4387ff;
}
<div id="nav_bar">
    <div class="nav option1">
        <h2>Option 1</h2>
    </div>
    <div class="nav option2">
        <h2>Option 2</h2>
    </div>
    <div class="nav option3">
        <h2>Option 3</h2>
    </div>
</div>
akinuri
  • 10,690
  • 10
  • 65
  • 102