Event listener on a CSS pseudo-element, such as ::after and ::before?

JavascriptCssPseudo Element

Javascript Problem Overview


I have a div element with a CSS pseudo-element ::before used as a close button (instead of using an actual button). How do I apply an event listener to only the pseudo-element?

HTML

<div id="box"></div>

CSS

#box:before
{
 background-image: url(close.png);
 content: '';
 display: block; 
 height: 20px;
 position: absolute;
 top: -10px;
 right: -10px; 
 width: 20px;
}

#box
{
 height: 100px;
 width: 100px;
}

Javascript Solutions


Solution 1 - Javascript

Was looking for a solution and found this thread. Now want to share my workaround:

CSS

element { pointer-events: none; }
element::after { pointer-events: all; }

JS

element.addEventListener('click', function() { ... });

This works if you don't need any pointer events on element. Check it in action.

Solution 2 - Javascript

No. The pseudo-element does not exist in the DOM so it has no HTMLElementNode object representing it.

Solution 3 - Javascript

There is no :before and :after selector in jQuery. However as an alternative, you can check the location of the click event and check if it is on your pseudo-element:

(I haven't tested this)

style:

#mything {
    width: 100px;
    height: 100px;
    position: relative;
    background: blue;
}
#mything:after {
    content: "x";
    font-size: 10px;
    position: absolute;
    top: 0;
    right: 0;
    background: red;
    width: 10px;
    height: 10px;
}

javascript:

$('#mything').click(function(e) {
    if (e.clientX > $(this).offset().left + 90 &&
        e.clientY < $(this).offset().top + 10) {
        // do something
    }
});

html:

<div id="mything">Foo</div>

Solution 4 - Javascript

If the position and dimensions of the generated content are known, you can add a click handler on the element itself and check the relative mouse position before handling it.

This is perverse, but possible.

Solution 5 - Javascript

Generally speaking no as indicated by others. But in case your tag with pseudo-element is empty, such as glyphicon in bootstrap.

You can wrap a div or span or whatever tag suitable in your case. Glyphicons in bootstrap uses :before but on the page you can see that it has hover event caught.

Example:

<span>
  <span class="glyphicon glyphicon-asterisk" aria-hidden="true"></span>
</span>

Suppose you want to add event to the above glyphicon, you can use jquery parent selector

$('glyphicon').parent('span').click(function() { 
  // awesome things
});

Just a small trick in case your tag is empty.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjenswirfView Question on Stackoverflow
Solution 1 - Javascriptp.boikoView Answer on Stackoverflow
Solution 2 - JavascriptQuentinView Answer on Stackoverflow
Solution 3 - JavascriptBenjamin IntalView Answer on Stackoverflow
Solution 4 - JavascriptYuri SulymaView Answer on Stackoverflow
Solution 5 - JavascriptgongzhitaaoView Answer on Stackoverflow