Search code examples
csstooltipcss-transforms

custom tooltip broken when add transform scale transition


If I remove scale in transform from line 18 and 48 (leave translateY only), the code works, but not decent. I want to add scale transition to make the transition smoother, but leads to the rectangle and the tooltip not going well along together. How to fix this?

.tooltip {
  display: block;
  background: #F24B5B;
  color: white;
  margin: 5em auto;
  padding: 1em 0;
  text-align: center;
  width: 13em;
  position: relative;

  --rec-size: .3em;
  --half-rec-size: calc( var(--rec-size) / 2 )
}
.tooltip::before,
.tooltip::after {
  position: absolute;
  opacity: 0;
  transform: scale(.5) translateY(1em);
  transform-origin: center bottom;
  transition: 
    opacity .3s ease-out, 
    transform .15s ease-out
    ;
}
.tooltip::after {
  content: '';
  border: var(--rec-size) solid #0000;
}
.tooltip::before {
  content: attr(title);
  width: 80%;
  line-height: 2em;
  border-radius: .2em;
  background: #000b;
}
.tooltip.top::before {
  bottom: calc( 100% + var(--rec-size) );
  left: 10%;  
}
.tooltip.top::after {
  border-top: var(--rec-size) solid #000b;
  bottom: calc( 100% - var(--rec-size) );
  left: calc( 50% - var(--half-rec-size) );
}
.tooltip:hover::before,
.tooltip:hover::after {
  opacity: 1;
  transform: scale(1) translateY(0);
}
<div class="tooltip top" title="Tooltip on top!">
  Hover over me
</div>


Solution

  • .tooltip {
      display: block;
      background: #F24B5B;
      color: white;
      margin: 5em auto;
      padding: 1em 0;
      text-align: center;
      width: 13em;
      position: relative;
    
      --rec-size: .3em;
      --half-rec-size: calc( var(--rec-size) / 2 )
    }
    .tooltip::before,
    .tooltip::after {
      position: absolute;
      opacity: 0;
      transform: scale(.5) translateY(1em);
      transform-origin: center bottom;
      transition: 
        opacity .3s ease-out, 
        transform .15s ease-out
        ;
    }
    
    .tooltip::after {
      transform: translateY(0.5em);
    }
    
    .tooltip::after {
      content: '';
      border: var(--rec-size) solid #0000;
    }
    .tooltip::before {
      content: attr(title);
      width: 80%;
      line-height: 2em;
      border-radius: .2em;
      background: #000b;
    }
    .tooltip.top::before {
      bottom: calc( 100% + var(--rec-size) );
      left: 10%;  
    }
    .tooltip.top::after {
      border-top: var(--rec-size) solid #000b;
      bottom: calc( 100% - var(--rec-size) );
      left: calc( 50% - var(--half-rec-size) );
    }
    .tooltip:hover::before,
    .tooltip:hover::after {
      opacity: 1;
      transform: scale(1) translateY(0);
    }
    <div class="tooltip top" title="Tooltip on top!">
      Hover over me
    </div>

    ::after and ::before set a different translateY

    .tooltip::after {
      transform: translateY(0.5em);
    }
    

    Or like the one above

    .tooltip::after,.tooltip::before {
      transform-origin: center 140%;
    }