Search code examples
javascripthtmldomeventsclick

Return node on node margin click


Having this code, where each P tag is separated by margin:

document.addEventListener("click", function(e) {
  console.log(e.target);
});
* {
  box-sizing: border-box; 
}
div {
  height: 100px;
  border: 1px solid blue;
}
p {
  margin: 20px;
  border: 1px solid red;
}
<div>
  <p>
    Lorem
  </p>
  <p>
    Lorem 2
  </p>
</div>

When I capture the click event in between the P tags, the returned node is DIV. How can I return P tag when P tag margin is clicked? I'm not allowed to change margins to paddings, which would be an easy solution.


Solution

  • You can take advantage of pseudo-elements, such as – in the example below – the ::before, positioned with a negative inset:

    document.addEventListener("click", function(e) {
      console.log(e.target);
    });
    * {
      box-sizing: border-box;
    }
    
    div {
      height: 100px;
      border: 1px solid blue;
    }
    
    p {
      margin: 20px;
      border: 1px solid red;
      isolation: isolate;
      position: relative;
    }
    
    p::before {
      background-color: transparent;
      content: '';
      inset: -10px;
      position: absolute;
      z-index: -1;
    }
    <div>
      <p>
        Lorem
      </p>
      <p>
        Lorem 2
      </p>
    </div>

    There is still a (small) gap between the two elements' ::before, but that can be adjusted by expanding the pseudo-elements.