skip to Main Content

I have a tooltip that appears on hover. The problem is that in order to remove focus/hover state in mobile, you have to click outside of the .explanation div. I want to mak it so that you can also close it my

<div class="main">
  <div>
    <h5>h5 text</h5>
      <div class="explanation">
        <div>
          <p>An explanatory paragraph <a>x</a>
          </p>
        </div>
      </div>
  </div>
</div>

css looks like this:

.main {
  .explanation {
    &::before {
      content: "[hover to show]";
    }

    p {
      background: #edf6ff;
      display: none;
      margin: 0;
      padding: 12px;
      position: relative;
      width: 200px;
      
      a {
        
          content: '[close]';
          outline: 5px solid blue;
          position: absolute;
          top: -5px;
          right: -20px;
        }
    }

    &:hover p {
      display: block;
    }
  }
}

jsfiddle here

This works perfectly on desktop, but ON MOBILE I want to be able to remove the focus on the element by clicking on the [x] a tag. You can already close it by clicking anywhere else, but I want to be able to click the X (which is inside) to close as well.

I figure it will be something like:

const closeButton = document.querySelector(
    '.main .explanation p a'
);

const main = document.querySelector('.main');

closeButton.addEventListener('click', removeFocus, false);

function removeFocus(event) {
    main.blur();
    event.preventDefault();
}

But this doesn’t do anything, at least not in Chrome. How can I toggle off the hover state on mobile?

2

Answers


  1. Instead of css hover use mouseenter and mouseleave.
    On mouseenter or touchstart add active class and on mouseleave remove it.
    When we click on close button remove the class

    const closeButton = document.querySelector('.main .explanation p a');
    const explanation = document.querySelector('.main .explanation');
    const addActiveClass = (e) => {
        explanation.classList.add('active');
    }
    const removeActiveClass = (e) => {
        explanation.classList.remove('active');
    }
    
    closeButton.addEventListener('click', toggleExplanation, false);
    explanation.addEventListener('mouseenter', addActiveClass);
    explanation.addEventListener('mouseleave', removeActiveClass);
    explanation.addEventListener('touchstart', addActiveClass);
    
    function toggleExplanation(event) {
      explanation.classList.toggle('active');
      event.preventDefault();
    }
    
    document.addEventListener('click', function(e) {
    
      // Check if the clicked element is outside the target element
      if (!explanation.contains(e.target)) {
        removeActiveClass(e)
      }
    });
    .main {
      .explanation {
        &::before {
          content: "[hover to show]";
        }
    
        p {
          background: #edf6ff;
          display: none;
          margin: 0;
          padding: 12px;
          position: relative;
          width: 200px;
    
          a {
            content: '[close]';
            outline: 5px solid blue;
            position: absolute;
            top: -5px;
            right: -20px;
          }
        }
    
        &.active p {
          display: block;
        }
      }
    }
    <div class="main">
      <div>
        <h5>h5 text</h5>
          <div class="explanation">
            <div>
              <p>An explanatory paragraph <a>x</a>
              </p>
            </div>
          </div>
      </div>
    </div>
    Login or Signup to reply.
  2. Need to make some modification in css and js with extra class in html and your code will working fine

    HTML

    <div class="main">
      <div>
        <h5>h5 text</h5>
          <div class="explanation show-tooltip">
            <div>
              <p>An explanatory paragraph <a class="close-tooltip">x</a>
              </p>
            </div>
           </div>
          </div>
        </div>
    

    CSS

    .main {
      .explanation {
        &::before {
          content: "[___]";
        }
    
        p {
          background: #edf6ff;
          display: none;
          margin: 0;
          padding: 12px;
          position: relative;
          width: 200px;
    
          a {
            content: '[close]';
            outline: 5px solid blue;
            position: absolute;
            top: -5px;
            right: -20px;
          }
        }
    
        
      }
      .explanation.show-tooltip {
        &:hover p {
          display: block;
        }
      }
    }
    

    JS

    document.addEventListener('DOMContentLoaded', function () {
      // Get all close-tooltip elements
      var closeButtons = document.querySelectorAll('.close-tooltip');
    
      // Add click event listeners to close-tooltip elements
      closeButtons.forEach(function (button) {
        button.addEventListener('click', function (event) {
          // Prevent the default behavior of the anchor tag
          event.preventDefault();
    
          // Find the closest parent with class 'explanation' and remove 'show-tooltip' class
          var explanation = button.closest('.explanation');
          if (explanation) {
            explanation.classList.remove('show-tooltip');
            setTimeout(() => {
                explanation.classList.add('show-tooltip');
            }, 1000)
          }
        });
      });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search