2

I have css class which have are both sibling: flex-align and nav-dropdown It works fine when I hover the flex-align, the nav-dropdown changes.

.flex-align:hover ~ .nav-dropdown {
   display: block !important;
}

Problem: what I want is it only changes when I hoveror focus the icon which is a child of flex-align, that is the only time the nav-dropdown changes

Thank you

.flex-align {
    display: flex;
    justify-content: start;
    align-items: center;
}

.nav-dropdown {
    display: none;
    width: auto;
}
.flex-align i:hover ~ .nav-dropdown {
    display: block;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">


<div class="flex-align">
    <i class="fa fa-arrow-right dropdown-icon">&nbsp;</i>
    <p>Main test</p>
</div>
<ul class="nav-dropdown">
    <li><a href="#">test 1</a></li>
    <li><a href="#">test 2</a></li>
    <li><a href="#">test 3</a></li>
</ul>
Charles Lavalard
  • 2,061
  • 6
  • 26
Stacks Queue
  • 848
  • 7
  • 18
  • 2
    CSS can not select parent class, so you should move `.nav-dropdown` inside `.flex-align` – Justinas May 21 '21 at 08:13
  • 1
    _OR_ use js, on hover add class to `.flex-align`, and by that you then can select `.nav-dropdown` – Justinas May 21 '21 at 08:14
  • That's my idea. I was just asking if there is a way I could change css class which is not a sibling or child of the hovered class. – Stacks Queue May 21 '21 at 08:18
  • 1
    It cannot be done. Have a look here https://stackoverflow.com/questions/30808392/how-to-select-parents-sibling-with-css? – Tushar Shahi May 21 '21 at 08:18
  • 1
    Move the `

    ` outside the `.flex-align` using positioning and set `pointer-events: none`. That'll ensure that it does not send hover event to its parent... then set `.flex-align:hover ~ ... {}` rule.

    – Salman A May 21 '21 at 08:27

2 Answers2

2

You can use pointer-events CSS property to ensure that the icon sends hover event to its parent but the text does not:

.flex-align {
  display: flex;
  justify-content: start;
  pointer-events: none;
}
.flex-align i {
  pointer-events: auto;
}
.nav-dropdown {
  display: none;
}
.flex-align:hover ~ .nav-dropdown {
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<div class="flex-align">
  <i class="fa fa-arrow-right dropdown-icon">&nbsp;</i>
  <span>Main test</span>
</div>
<ul class="nav-dropdown">
  <li><a href="#">test 1</a></li>
  <li><a href="#">test 2</a></li>
  <li><a href="#">test 3</a></li>
</ul>
Salman A
  • 262,204
  • 82
  • 430
  • 521
0

Since you can't select parent elements inside CSS (wait for possible CSSv4 solution), use JS for that. On hover add class to parent element

$(document).ready(function () {
  $('.flex-align i').hover(
    function () {
      $(this).closest('.parent-wrapper').addClass('hover');
    },
    function () {
      $(this).closest('.parent-wrapper').removeClass('hover');
    }
  )
});
.flex-align {
    display: flex;
    justify-content: start;
    align-items: center;
}

.nav-dropdown {
    display: none !important;
    width: auto !important;
}
.hover .nav-dropdown {
    display: block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">


<div class="parent-wrapper">
  <div class="flex-align">
      <i class="fa fa-arrow-right dropdown-icon"></i>
      <p>Main test</p>
  </div>
  <ul class="nav-dropdown">
      <li><a href="#">test 1</a></li>
      <li><a href="#">test 2</a></li>
      <li><a href="#">test 3</a></li>
  </ul>
</div>
Justinas
  • 41,402
  • 5
  • 66
  • 96
  • Thanks mate. I was just asking if there is a possible way without JS. I understand now there's no way. JS it is. – Stacks Queue May 21 '21 at 08:23
  • @StacksQueue With current html - no. But I think you can think of clever HTML structure that allows you to select elements – Justinas May 21 '21 at 08:26