0

I wanted to make a button that would go in a U shape horizontally and to do that, I put a white pseudo element on top of the existing button but the problem is that the pseudo-element still is clickable in the parts where it is on top of the button.

At the start, there was a change in the cursor on hover as well but I got around it by putting the cursor to auto and so the cursor change does not happen on the pseudo-element but the click event is still triggered.

This is the css code and the Code Pen link: https://codepen.io/SawanSunar24/pen/KKxQvWm?editors=1111

.btn {
    border: none;
    height: 60px;
    background-color: #3b82f6;
    border-radius: 0 30px 30px 0;
    color: white;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 40px;
    padding-right: 20px;
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

.btn::before {
    background-color: white;
    border-radius: 0 100% 100% 0;
    bottom: 0px;
    left: -20px;
    content: "";
    display: block;
    height: 60px;
    cursor: auto;
    position: absolute;
    width: 40px;
}  

I put various other elements on top of the button but they are not clickable and this issue/condition only happens for pseudo elements.

I would appreciate it if someone would tell me a way of getting around this problem, or maybe I am just stupid and this is a bad practice, so a criticism about a better way of doing it would also be helpful.

Thank you.

Sown Leon
  • 41
  • 4

2 Answers2

0

In my original answer I said you only need to add pointer-events: none; to your before element. As pointed out in the other answer, this won't have your desired effect. Below is a snippet showing how you can use clip-path and a radial gradient instead.

Working snippet:

body {
  font-family: sans-serif;
  display: grid;
  place-content: center;
  min-height: 100vh;
  gap: 3rem;
}

.btn {
  border: none;
  border-radius: 0 30px 30px 0;
  background-color: #3b82f6;
  color: white;
  cursor: pointer;
  font: inherit;
  height: 60px;
  padding: 5px 20px 5px 40px;
  position: relative;
  overflow: hidden;
  width: 120px;
}

.btn:hover {
  background-color: red;
}

.btn.covered::before {
  aspect-ratio: 1;
  height: 100%;
  position: absolute;
  inset-block: 0;
  left: -30%;
  background-color: yellow;
  border-radius: 50%;
  content: "";
  /* ✨ Add this property ✨ */
  pointer-events: none;
}

.btn.clipped {
  clip-path: path("M120,60H0s15-10,15-30C15,10,0,0,0,0H120V60Z");
}

.btn.bg {
  padding-left: 20px;
  width: 100px;
  margin-left: 20px;
  overflow: visible;
}

.btn.bg::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  left: -35px;
  background-image: radial-gradient(
    circle at left,
    transparent 33%,
    #3b82f6 33%
  );
  background-repeat: no-repeat;
  z-index: -1;
}

.btn.bg:hover::before {
  background-image: radial-gradient(circle at left, transparent 33%, red 33%);
}
<button class="btn bg" type="button" onclick="console.log('gradient')">
  gradient
</button>

<button class="btn covered" type="button" onclick="console.log('covered')">
  covered
</button>

<button class="btn clipped" type="button" onclick="console.log('clipped')">
  clipped
</button>
jme11
  • 17,134
  • 2
  • 38
  • 48
0

This answer is for the opposite problem but, the same solution can be applied and have your event handler check the event.target; if it is the child element do nothing.

const btn = document.querySelector(".btn");

btn.addEventListener("click", (e) => {

  if (e.target.tagName === "SPAN") {
    e.preventDefault();
    e.stopPropagation();

    return false;
  }

  console.log("Data", e.target.tagName);

});
.main {
  padding: 100px;
}

.btn {
  border: none;
  height: 60px;
  background-color: #3b82f6;
  border-radius: 0 30px 30px 0;
  color: white;
  padding-top: 5px;
  padding-bottom: 5px;
  padding-left: 40px;
  padding-right: 20px;
  position: relative;
  overflow: hidden;
  cursor: pointer;
}

.btn>span {
  background-color: white;
  border-radius: 0 100% 100% 0;
  bottom: 0px;
  left: -20px;
  content: "";
  display: block;
  height: 60px;
  cursor: auto;
  position: absolute;
  width: 40px;
}
<div class="main">
  <button class="btn">
  <span></span>
  Submit
 </button>
</div>

CodePen

Arleigh Hix
  • 9,990
  • 1
  • 14
  • 31
  • Okay so from your answer, I would be correct to assume that the functionality I am trying to achieve is not possible with pseudo elements at all, and using a different approach is the only way. I just wanted that clarification, thank you very much. – Sown Leon Mar 13 '23 at 17:57