skip to Main Content

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.

2

Answers


  1. 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>
    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search