Search code examples
htmlcsstooltip

How to design below effect in a div without using any Images


enter image description here

How can we design tip in bottom just like above without using any images. Below is my trail code:

<div id="coverImageToolTip"><p><font color="white">TIP:</font> UPLOAD YOUR<br/> COVER IMAGE HERE
    <div id="tail1"></div>
    <div id="tail2"></div>

#coverImageToolTip {
    position: absolute;
    z-index: 10;
    padding: 0px 4px;
    background-color: gray;
    bottom: 100px;
    left: 20%;
    border-radius: 10px;
    font-weight: bold;
    border-bottom: 5px solid black;
}


/* #tail1 {
    position:absolute;
    bottom:100px;
    left:20px;
    width:0;height:0;
    border-color:#a0c7ff transparent transparent transparent;
    border-width:10px;
    border-style:solid;
} */

#tail2 {
    position:absolute;
    bottom:-18px;
    left:20px;
    width:0;height:0;
    border-color: red transparent transparent  red  ;
    border-width:10px;
    border-style:solid;
    transform:rotate(90deg);
    -ms-transform:rotate(90deg); /* IE 9 */
    -moz-transform:rotate(90deg); /* Firefox */
    -webkit-transform:rotate(90deg); /* Safari and Chrome */
    -o-transform:rotate(90deg); /* Opera */
}

Solution

  • A minimal markup version:

    2024 answer

    We can create the tooltip tail with a conic-gradient() in the transparent border area underneath. We then use filter: drop-shadow() to create the shadow following the whole shape. We set these styles on an absolutely positioned pseudo behind the tooltip because we don't want the shadow to also be applied on the close button.

    Note that the little bit of JS included only serves to close the tooltip upon clicking the close button.

    /* just to close tooltip from button */
    addEventListener('click', e => {
      let _t = e.target;
        
      if(_t.getAttribute('aria-label') === 'close') {
        _t.parentNode.classList.add('closed')
      }
    });
    @import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500&display=swap');
    
    html, body, button { display: grid }
    
    html { height: 100% }
    
    body { background: radial-gradient(at 0 100%, #dedede, 85%, #165a9b) }
    
    .tooltip {
      --r: 5px; /* tooltip corner rounding */
      --h: 1.25em; /* arrow height */
      --c: #999; /* tooltip background */
      place-self: center;
      position: relative;
      margin-bottom: var(--h); /* reserve arrow space */
      padding: .25em;
      width: 8em;
      font: 700 2em/ 1.375 oswald, sans-serif;
      text-align: center;
      text-transform: uppercase;
        
      &::before {
        position: absolute;
        z-index: -1;
        inset: calc(-1*var(--h));
          /* increase background area with transparent border */
        border: solid var(--h) #0000;
        border-radius: calc(var(--h) + var(--r));
        background: 
          /* main box, restricted to padding-box */
          linear-gradient(var(--c) 0 0) padding-box, 
          /* tooltip tail, within all border-box */
          conic-gradient(
              from 20deg /* tail start angle */ 
              at 43% /* horizontal tail tip position */ 100%, 
              var(--c) 30deg /* angular size of tail */, #0000 0%) 
            0 100% /* place at the bottom *// 
            50% 50% no-repeat  /* limit size & repetition so no overflow */
            border-box;
        filter: drop-shadow(0 6px #434343);
        content: ''
      }
    }
    
    .closed { display: none }
    
    .highlight { color: #fff }
    
    /* prettify close button from here on */
    button {
      position: absolute;
      top: 0;
      right: 0;
      padding: 0;
      width: 1.125em;
      aspect-ratio: 1;
      border: solid 4px currentcolor;
      border-radius: 50%;
      translate: 50% -50%;
      background: #030303;
      color: var(--c);
      font: inherit;
        
      &::before, &::after {
        grid-area: 1/ 1;
        place-self: center;
        width: .625em; height: 4px;
        border-radius: 3px;
        rotate: -45deg;
        background: currentcolor;
        content: ''
      }
        
      &::after { rotate: 45deg }
    }
    <div class='tooltip'>
      <span class='highlight'>tip:</span> upload your cover image here
      <button aria-label='close'></button>
    <div>

    If the tail jaggedness is disturbing, we can smooth it out with a custom SVG filter before the drop-shadow() one.

    addEventListener('click', e => {
      let _t = e.target;
        
      if(_t.getAttribute('aria-label') === 'close') {
        _t.parentNode.classList.add('closed')
      }
    });
    @import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500&display=swap');
    
    html, body, button { display: grid }
    
    html { height: 100% }
    
    body { background: radial-gradient(at 0 100%, #dedede, 85%, #165a9b) }
    
    svg[height='0'] { position: fixed; }
    
    .tooltip {
      --r: 5px; /* tooltip corner rounding */
      --h: 1.25em; /* arrow height */
      --c: #999; /* tooltip background */
      place-self: center;
      position: relative;
      margin-bottom: var(--h); /* reserve arrow space */
      padding: .25em;
      width: 8em;
      font: 700 2em/ 1.375 oswald, sans-serif;
      text-align: center;
      text-transform: uppercase;
        
      &::before {
        position: absolute;
        z-index: -1;
        inset: calc(-1*var(--h));
          /* increase background area with transparent border */
        border: solid var(--h) #0000;
        border-radius: calc(var(--h) + var(--r));
        background: 
          /* main box, restricted to padding-box */
          linear-gradient(var(--c) 0 0) padding-box, 
          /* tooltip tail, within all border-box */
          conic-gradient(
              from 20deg /* tail start angle */ 
              at 50% /* horizontal tail tip position */ 100%, 
              var(--c) 35deg /* angular size of tail */, #0000 0%) 
            0 100% /* place at the bottom *// 
            100% 50% no-repeat  /* limit size & repetition so no overflow */
            border-box;
        filter: blur(2px) url(#smooth) drop-shadow(0 6px #434343);
        content: ''
      }
    }
    
    .closed { display: none }
    
    .highlight { color: #fff }
    
    /* prettify close button from here on */
    button {
      position: absolute;
      top: 0;
      right: 0;
      padding: 0;
      width: 1.125em;
      aspect-ratio: 1;
      border: solid 4px currentcolor;
      border-radius: 50%;
      translate: 50% -50%;
      background: #030303;
      color: var(--c);
      font: inherit;
        
      &::before, &::after {
        grid-area: 1/ 1;
        place-self: center;
        width: .625em; height: 4px;
        border-radius: 3px;
        rotate: -45deg;
        background: currentcolor;
        content: ''
      }
        
      &::after { rotate: 45deg }
    }
    <svg width='0' height='0'>
      <filter id='smooth' color-interpolation-filters='sRGB'>
        <feComponentTransfer>
          <feFuncA type='gamma' amplitude='4' exponent='3' offset='-.5'>
        </feComponentTransfer>
      </filter>
    </svg>
    
    <div class='tooltip'>
      <span class='highlight'>tip:</span> upload your cover image here
      <button aria-label='close'></button>
    <div>

    original answer, preserved for web history reasons:

    body { background: lightblue; }
    .tooltip {
      position: relative;
      margin: 1em auto;
      padding: .5em .2em;
      width: 10.5em; height: 3em;
      border-radius: .25em;
      box-shadow: 0 .2em 0 black;
      background: #999;
      font: 700 1.6em/1.5 sans-serif;
      text-align: center;
      text-transform: uppercase;
    }
    button {
      position: absolute;
      top: -.75em; right: -.75em;
      border: solid .2em;
      width: 1.5em; height: 1.5em;
      border-radius: 50%;
      background: black;
      color: #999;
      font: 900 .65em/1 sans-serif;
        text-align: center;
    }
    .tooltip:after {
      position: absolute;
      z-index: -1;
      right: 25%; bottom: -.75em;
      width: 2em; height: 2em;
      box-shadow: 0 .35em 0 black;
      transform: rotate(30deg) skewY(-60deg);
      background: inherit;
      content: '';
    }
    .highlight { color: white; }
    .highlight:after, .highlight:before {
      position: absolute;
      top: 100%; right: 31.025%;
      width: 1.725em; height: .2em;
      transform: skewX(-30deg);
      background: #999;
      content: '';
    }
    .highlight:after {
      right: 30.65%;
      transform: skewX(-60deg);
    }
    <div class='tooltip'>
      <span class='highlight'>tip:</span> upload your cover image here
      <button aria-label='close'>x</button>
    <div>