skip to Main Content

I want an inline element to be easier to click. I can add padding, but I don’t want to impact other elements. I can undo that with negative margin, but it leads to odd results:

span {
  padding: 5px;
  margin: -5px;

  background-color: red;
  cursor: pointer;
}
ab<span>c</span>def

If you try to hover over it, the pointer does not show up in the whole red area but goes away to the right of the c (where the d is). An onClick callback would work the same. Why does this happen, and how do I prevent it?

4

Answers


  1. A quick fix would be to add an anchor tag around both your inline element and some surrounding elements as well.

    document.querySelector('a').addEventListener('click', evt => {
      alert('clicked')
    })
    body {
      font-size: 3em;
    }
    span {
      background: pink;
    }
    a {
      color: inherit;
      text-decoration: none;
    }
    a:hover {
      background: lime;
      cursor: pointer;
    }
    a:hover>span {
      background: none;
    }
    a<a>b<span>c</span>d</a>ef

    Otherwise you could dynamically insert an absolutely-positioned element to be your click target.

    document.querySelectorAll('.s1').forEach(sc => {
      const s = '<span class="s2"></span>'
      sc.insertAdjacentHTML('beforeend', s)
    })
    document.addEventListener('click', evt => {
      if (evt.target.classList.contains('s2')) alert('clicked')
    })
    body {
      font-size: 3em;
    }
    .s1 {
      position: relative;
    }
    .s2 {
      position: absolute;
      top: 0;
      left: -1rem;
      right: -1rem;
      bottom: 0;
      background-color: pink;
      opacity: 0.5;
    }
    .s2:hover {
      background-color: lime;
      cursor: pointer;
    }
    ab<span class="s1">c</span>def
    Login or Signup to reply.
  2. I would not recommend this.

    Imagine you have a text with several clickable words. And know imagine they are neighbours, vertically and/or horizontally.
    The clickable areas will overlap each other.

    This will not end good for UXP.

    Login or Signup to reply.
  3. You can use a CSS class that’ll define a pseudo element ::before which expands the clickable area without affecting the layout:

    .clickable {
      display: inline-block;
      cursor: pointer;
      position: relative;
      text-decoration: underline;
      transition: background-color 0.2s ease;
      &::before {
        content: "";
        left: -5px;
        top: -5px;
        right: -5px;
        bottom: -5px;
        position: absolute;
      }
      &:hover {
        background: orange;
      }  
    }
    ab<span class="clickable" onclick="console.log('clicked')">c</span>def
    Login or Signup to reply.
  4. You can expand the clickable area by adding before and after pseudo elements to the span.

    This snippet adds a 5px transparent clickable area before and after. That way the adjacent characters are not disturbed, and it is clear which character is clickable.

    span {
      background-color: red;
      cursor: pointer;
      position: relative;
      display: inline-block;
    }
    
    span::before,
    span::after {
      content: '';
      position: absolute;
      background-color: transparent;
      width: 5px;
      height: 100%;
    }
    
    span::before {
      margin-left: -5px;
    }
    ab<span>c</span>def
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search