kenshuri
kenshuri

Reputation: 532

Add delay to a hover:display property in native tailwindcss

I have a sidebar that gets bigger on hover. In that sidebar, I have divs that contains extra-content which is only displayed when the sidebar is hovered. The code below works well:

HTML file

    <!--Sidebar-->
    <div class="group w-16 bg-blue-700 hover:w-44">Sidebar
        <div>Item 1
            <span class="hidden group-hover:inline">Item 1: Details</span>
        </div>
        <div>Item 2
            <span class="hidden group-hover:inline">Item 2: Details</span>
        </div>
    </div>

CSS file

@tailwind base;
@tailwind components;
@tailwind utilities;

tailwind.config.js

module.exports = {
    purge: [],
    darkMode: false, // or 'media' or 'class'
    theme: {},
    extend: {},
    variants: {
        extend: {
            width: ['hover'],
            display: ['group-hover'],
        },
    },
    plugins: [],
}

However, I would like to create a nice transition when the sidebar is hovered so that it gets bigger smoothly. I do this by changing the HTML file to -->

New HTML file

    <!--Sidebar-->
    <div class="group w-16 bg-blue-700 hover:w-44 transition-all">Sidebar
        <div>Item 1
            <span class="hidden group-hover:inline">Item 1: Details</span>
        </div>
        <div>Item 2
            <span class="hidden group-hover:inline">Item 2: Details</span>
        </div>
    </div>

Doing so, now, there is small bug when the sidebar is hovered: the extra content is displayed before the sidebar reaches its full-size. I need to add a delay to the display of the extra content. Ideally, the sidebar would first gets bigger smoothly and reach its full-size, and only then the extra-content would appear. Is there a way to do so in native tailwind css?

Upvotes: 2

Views: 6110

Answers (3)

ccrsxx
ccrsxx

Reputation: 493

Here's my implementation without using custom animation. You just need to add a delay when the parent is hovered, and reset the delay back to zero when the parent is not hovered.

<script src="https://cdn.tailwindcss.com"></script>
<style type="text/tailwindcss">
  @layer components {
    #container {
      @apply flex flex-col items-center gap-2 mt-4;
    };

    #button {
      @apply bg-blue-400 text-white p-1 rounded;
    };

    #tooltips {
      @apply bg-green-400 p-0.5 w-24 left-1/2 -translate-x-1/2 
             translate-y-10 transition-opacity rounded;
    };
  };
</style>

<!-- Ignore previous code block, it's just for styling -->

<div id='container'>
  <h1>Hover with delay tailwindcss<h1>
  <button id='button' class='relative group'
  >Hover me
    <span id='tooltips' class='absolute 
                               opacity-0 
                               delay-0 
                               group-hover:opacity-100 
                               group-hover:delay-300'
    >I'm here 👋</span>
  </button>
</div>

Upvotes: 0

kenshuri
kenshuri

Reputation: 532

Thanks to Ali javanmardi hints, I managed to achieve what I wanted. The main findings are:

  • Need to use Absolute positioning for Items Details in the sidebar
  • Adding a delay on a transition such as group-hover:visible delay-150 does not work in this specific case because this would lead the details to disappear after the sidebar is closed (because delay is applied at Start and End)

Instead, I created a custom animation of 1s, where the first "transition" keyframes happens at 15%, thus creating effectively a delay from 0% to 15%, combined with animation-fill-mode: forwards; Below is my code.

HTML file

    <!--Sidebar-->
    <div class="group w-16 bg-blue-700 hover:w-44 transition-all">Sidebar
        <div class="relative">Item 1
            <span class="absolute opacity-0 invisible group-hover:animate-tooltip_show ml-2">Item 1: Details</span>
        </div>
        <div class="relative">Item 2
            <span class="absolute opacity-0 invisible group-hover:animate-tooltip_show ml-2">Item 2: Details</span>
        </div>
    </div>

tailwind.config.js

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {
      keyframes: {
        tooltip_show: {
          '0%' : { visibility: 'hidden', opacity: '0'},
          '15%' : { visibility: 'hidden', opacity: '0'},
          '100%' : { visibility: 'visible', opacity: '100'},
        }
      },
      animation: {
        tooltip_show: 'tooltip_show 1s ease forwards',
      }
    },
  },
  variants: {
    extend: {
      width: ['hover'],
      animation: ['group-hover'],
    },
  },
  plugins: [],
}

Upvotes: 1

Ali javanmardi
Ali javanmardi

Reputation: 69

To achieve this I did a simple hack for it.

As you may find yourself, tailwindcss-> group-hover:visible class represents:

.group:hover .group-hover\:visible {
    visibility: visible;
}

So I changed group-hover:visible to xgroup-hover:visible and added some animation instead of original tailwindcss:

@keyframes tooltip-show {
  0%   {opacity: 0;}
  5%   {visibility: visible;}
  25%  {opacity: 50;}
  50%  {opacity: 75;}
  100% {opacity: 100;}
}
.group:hover .xgroup-hover\:visible {
  animation-delay: 0.7s;
  animation-name: tooltip-show;
  animation-duration: 2s;
}

this simple hack worked for me :)

So you can follow same way for your desired group-hover:inline class and add your own animation keyframes as you like.

Upvotes: 2

Related Questions