1

I want to add hover effect on specific part of the paragraph. but when mouse is positioned on the blank space between the lines mouseout / mouseleave getting fired (space is caused by line-height css). because of this the hover state keeps flickering. please refer the below image

On text hover on text hover

When mouse positioned over blank space between the lines enter image description here

What I have now:

const spans = document.querySelectorAll('span');
spans.forEach(span => {
  span.addEventListener('mouseover', ($event) => {
    span.setAttribute('hovered', 'true');
  });

  span.addEventListener('mouseout', ($event) => {
    span.setAttribute('hovered', 'false');
  });
});
span[hovered='true'] {
  background-color: red;
  color: white;
}
<p>
  Nevererr is this principleasd more pertinent than when dealingasd with type, the bread and butter of Web-borne communication. A well-set paragraph of text is not supposed to wow the reader;
  <span>
                the wowing should be left to the idea or observation for which the paragraph is a vehicle. In fact, the perfect paragraph is unassuming to the point of near invisibility. That is not to say that the appearance of your text should have no appeal at all.
            </span> On the contrary: well-balanced, comfortably read typography is a thing of beauty; it’s just not the arresting sort of beauty that might distract you from reading. asd.
</p>

EXAMPLE => stackblitz

please suggest some alternatives to make the hover state smooth.

2 Answers 2

1

This may be a bit overkill, but this is how it could be solved.

Determine the highest and lowest point of the span and check whether the mouse moves out of this area.

See the comments.

// rectangle of spans
let rect;

document.querySelectorAll('p').forEach(p => {
  // offset, for mouseout next to span text
  let lineHeight = parseInt(window.getComputedStyle(p).lineHeight);
  let fontSize = parseInt(window.getComputedStyle(p).fontSize);
  let offset = lineHeight - fontSize;
  
  // mouse event on all <p> tags
  p.addEventListener('mousemove', (e) => {
    // movement on span
    if (e.target.tagName === 'SPAN') {
      // get rect of current span
      rect = e.target.getBoundingClientRect();
      e.target.setAttribute('hovered', 'true');
    }
    // movement on p
    else if (e.target.tagName === 'P') {
      // set hover false if mouse is above or below the span rectangle (+- offset)
      if (!rect || (rect && (e.clientY < rect.top + offset  || e.clientY > rect.bottom - offset))) {
        p.querySelectorAll('span').forEach(span => {
          span.setAttribute('hovered', 'false');
          // reset rect
          rect = undefined;
        });
      }
    }
  });
});
p {
  line-height: 2;
}

span {
  background: yellow;
}

span[hovered='true'] {
    background-color: red;
    color: white;
}
<p>
        Nevererr is this principleasd more pertinent than when dealingasd with type, the bread and butter of Web-borne communication. A well-set paragraph of text is not supposed to wow the reader; 
        <span>
            the wowing should be left to the idea or observation for which the paragraph is a vehicle. In fact, the perfect paragraph is unassuming to the point of near invisibility. That is not to say that the appearance of your text should have no appeal at all.
        </span> 
        On the contrary: well-balanced, comfortably read typography is a thing of beauty; it’s just not the arresting sort of beauty that might distract you from reading. asd.
    </p>

Sign up to request clarification or add additional context in comments.

Comments

0

No need for the JavaScript so I commented it out as well as the related CSS. I then set up some CSS to remove the borders and padding by setting to 0 and made the line-height to just be one em.

Now if you really NEED the JavaScript as a part of some other functionality you can do that also - so I added a second example for that.

Example if you really need the JavaScript

const spans = document.querySelectorAll('span');
spans.forEach(span => {
  span.addEventListener('mouseover', ($event) => {
    span.setAttribute('hovered', 'true');
  });

  span.addEventListener('mouseout', ($event) => {
    span.setAttribute('hovered', 'false');
  });
});
body,
* {
  margin: 0;
  border: 0;
  padding: 0;
  box-sizing: border-box;
  line-height: 1em;
}

span[hovered='true'] {
  background-color: red;
  color: white;
}
<p>
  Nevererr is this principleasd more pertinent than when dealingasd with type, the bread and butter of Web-borne communication. A well-set paragraph of text is not supposed to wow the reader;
  <span>
                the wowing should be left to the idea or observation for which the paragraph is a vehicle. In fact, the perfect paragraph is unassuming to the point of near invisibility. That is not to say that the appearance of your text should have no appeal at all.
            </span> On the contrary: well-balanced, comfortably read typography is a thing of beauty; it’s just not the arresting sort of beauty that might distract you from reading. asd.
</p>

Just some CSS change:

/*
const spans = document.querySelectorAll('span');
spans.forEach(span => {
  span.addEventListener('mouseover', ($event) => {
    span.setAttribute('hovered', 'true');
  });

  span.addEventListener('mouseout', ($event) => {
    span.setAttribute('hovered', 'false');
  });
});
*/
/*span[hovered='true'] {
  background-color: red;
  color: white;
}
*/

body, * {
  margin: 0;
  border: 0;
  padding: 0;
  box-sizing: border-box;
  line-height: 1em;
}

span:hover {
  background-color: red;
  color: white;
}
<p>
  Nevererr is this principleasd more pertinent than when dealingasd with type, the bread and butter of Web-borne communication. A well-set paragraph of text is not supposed to wow the reader;
  <span>
                the wowing should be left to the idea or observation for which the paragraph is a vehicle. In fact, the perfect paragraph is unassuming to the point of near invisibility. That is not to say that the appearance of your text should have no appeal at all.
            </span> On the contrary: well-balanced, comfortably read typography is a thing of beauty; it’s just not the arresting sort of beauty that might distract you from reading. asd.
</p>

3 Comments

This does not work if the lineheight is set higher.
@ztom Yes, additional changes are needed if the line height changes but strictly speaking that as not part of the original question with a differing line height; this just works with the existing line height. I do like your answer also BTW.
@MarkSchultheiss working on a custom editor and highlighting specific section is a part of functionality that I need and I also want to keep line-height variable. but anyways thanks for help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.