Home > Mobile >  Make hovered tooltip disappear when clicking button
Make hovered tooltip disappear when clicking button

Time:02-19

I am trying to create a tooltip for whatever that needs it on my website, e.g. a button, text, etc. So far I have something like this:

https://jsfiddle.net/f06q3cLg/

.content {
  display: grid;
  width: 100vw;
  height: 100vh;
  place-content: center;
}

.content .parent {
  border: 1px red solid;
  padding: 10px;
  position: relative;
}

.content .parent:hover .tooltip-wrapper {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:hover:before {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:active .tooltip-wrapper {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:active:before {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:before {
  content: "";
  display: block;
  width: 0;
  height: 0;
  position: absolute;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
}

.content .parent .tooltip-wrapper {
  position: absolute;
  display: grid;
  left: 0;
  width: 300px;
  height: 100%;
  opacity: 0;
  pointer-events: none;
}

.content .parent .tooltip-wrapper.bottom {
  top: calc(100%   8px);
}

.content .parent .tooltip-wrapper .tooltip {
  max-width: 300px;
  width: fit-content;
  padding: 8px;
  position: absolute;
  display: inline-block;
  background: blue;
  border-radius: 5px;
  padding: 8px;
  color: white;
  font-size: 11px;
  box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
  line-height: 1.3;
  text-align: left;
}


/* Keyframes */

@keyframes fadeInTooltip {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOutTooltip {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
<div >
  <div >
    Hover me
    <div >
      <span >This is my tooltip</span>
    </div>
  </div>
</div>

As such, it works somewhat fine. My issue is that I would like the tooltip to disappear when I click the button. Now it vanishes, and then comes back with a 0.4s delay as the hover effect actually has. Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.

I'm not sure if this is even achievable with pure CSS, but any JS would also do.

CodePudding user response:

HTML

<div >
   <div  onClick="myFunction()">
      Hover me
      <div >
       <span  id="tooltip">This is mytooltip</span>
      </div>
   </div>
</div>

Javascript

function myFunction(){
  var tooltip=document.getElementById("tooltip");
  if (tooltip.style.display=="none") {        
 document.getElementById("tooltip").style.display="block";
  } else {
  document.getElementById("tooltip").style.display="none";
  }
}

CodePudding user response:

Manipulating 'display' property.

const parent = document.querySelector('.parent');
const toolTip = document.querySelector('.tooltip');

parent.addEventListener('click', () => {
if(toolTip.style.display !== 'none') {
    toolTip.style.display = 'none';
}else {
  toolTip.style.display = 'grid';
}
    
});

CodePudding user response:

The problem is that :active is only applied as long as the mouse is down.

mdn: :active:

The :active CSS pseudo-class represents an element (such as a button) that is being activated by the user. When using a mouse, "activation" typically starts when the user presses down the primary mouse button.

What you could do (if you want to stay CSS only) is to use tabindex="0" on the <div > and :focus instead of :active. But you need to verify that using tabindex="0" here won't hurt usability.

Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.

That won't work with :focus either. I'm pretty sure that this behavior can only be achieved with JS. If it is possible with CSS only it likely would be a pretty hacky solution.

But from the perspective of a user, this seems to be counterintuitive that the tooltip won't appear after clicked.

A JavaScript solution that does what you want could look like this. It is a simplified version of the tooltip to only show the relevant parts. Every element having a tooltip has an attribute data-has-tooltip.

// event delegation for all mouse down event:
// this ensures that the code also works for elements that have been added to the DOM after that script was executed.
document.addEventListener('mousedown', (evt) => {
  // check if the mousedown happened in an element with a tooltip
  const element = evt.target.closest('[data-has-tooltip]');
  if (element) {
    // if the user already clicked on the element ignore the click
    if (!element.classList.contains('active')) {
      // add the active class to the element so that hover won't show the toolip
      element.classList.add('active');

      function removeActiveOnLeave() {
        // remove the active class
        element.classList.remove('active');

        // remove the mouseleave event listener again
        element.removeEventListener('mouseleave', removeActiveOnLeave)
      }

      // add an event listener for mouseleave to remove the active class
      element.addEventListener('mouseleave', removeActiveOnLeave)
    }
  }

});
.parent {
   display: inline-block;
   border: 1px solid red;
   padding: 0.5rem;
   margin: 0.5rem;
}

.tooltip-wrapper {
  display: none;
}

.parent:hover .tooltip-wrapper {
  display: block;
}

.parent.active:hover .tooltip-wrapper {
  display: none;
}
<div >
  <div  data-has-tooltip>
    Hover me A
    <div >
      <span >This is my tooltip A </span>
    </div>
  </div>
</div>

<div >
  <div  data-has-tooltip>
    Hover me B
    <div >
      <span >This is my tooltip B</span>
    </div>
  </div>
</div>

CodePudding user response:

A solution using jQuery 3.4.1:

$(".parent").click(function () {
    $(".tooltip-wrapper").css("display", "none");
});

The only downfall with that solution is once you click and re-hover in the same session, the SCSS :hover doesn't work properly.

No need to stress, just add the following if you want that functionality:

$(".parent").hover(function () {
    $(".tooltip-wrapper").css("display", "block");
});

Try it out in the attached snippet:

$(".parent").click(function () {
    $(".tooltip-wrapper").css("display", "none");
});

$(".parent").hover(function () {
    $(".tooltip-wrapper").css("display", "block");
});
.content {
  display: grid;
  width: 100vw;
  height: 100vh;
  place-content: center;
}

.content .parent {
  border: 1px red solid;
  padding: 10px;
  position: relative;
}

.content .parent:hover .tooltip-wrapper {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:hover:before {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:active .tooltip-wrapper {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:active:before {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:before {
  content: "";
  display: block;
  width: 0;
  height: 0;
  position: absolute;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
}

.content .parent .tooltip-wrapper {
  position: absolute;
  display: grid;
  left: 0;
  width: 300px;
  height: 100%;
  opacity: 0;
  pointer-events: none;
}

.content .parent .tooltip-wrapper.bottom {
  top: calc(100%   8px);
}

.content .parent .tooltip-wrapper .tooltip {
  max-width: 300px;
  width: fit-content;
  padding: 8px;
  position: absolute;
  display: inline-block;
  background: blue;
  border-radius: 5px;
  padding: 8px;
  color: white;
  font-size: 11px;
  box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
  line-height: 1.3;
  text-align: left;
}


/* Keyframes */

@keyframes fadeInTooltip {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOutTooltip {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div >
  <div >
    Hover me
    <div >
      <span >This is my tooltip</span>
    </div>
  </div>
</div>

OR, you can see it working in this Fiddle. with your initial SCSS.

You can uncomment the second function to see the hover working again after clicking.

  • Related