Add delay to a hover:display property in native tailwindcss - tailwind-css

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?

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.

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: [],
}

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>

Related

[Tailwind CSS]Empty div don't show in browser

I am using Tailwind CSS with Next.js, and want to show progress bar in below url.
https://www.tailwind-kit.com/components/progress
The code is below:
<div>
<div class="bg-white rounded-lg w-72 shadow block p-4 m-auto">
<div class="w-full h-2 bg-gray-400 rounded-full mt-3">
<div class="w-3/4 h-full text-center text-xs text-white bg-green-500 rounded-full">
</div>
</div>
</div>
</div>
However, If I check browser, the bar is not displayed and the height of the div element is 0.
I checked in Chrome and Safari, and the result was the same in both.
I want to know how to show the empty div element in browser.
--Update:
I have solved the above problem by removing the height customize from tailwind.config.js.
module.exports = {
purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
// removed this
height: {
main: '681px'
},
},
variants: {
extend: {},
},
plugins: [],
}
However, I don't know why the height customize caused this problem, does anyone know about it?
you could use grow Property:
<div class="grow w-3/4 h-full ....">

Tailwindcss group-hover not working on border color

When I hover over a navigation item, I want a span border color to be changed. The group-hover does nothing...
Is this just not implemented in Tailwindcss yet?
<a class="group px-4 py-2 hover:bg-white
hover:text-primary transition-colors duration-300
rounded-sm"
:href="route">
<span class="pb-1 border-b border-white group-hover:border-black">
<slot/>
</span>
</a>
I obviously can do this by writing css like this, but tailwind should be able to do this, right?
a:hover span {
border-color: black;
}
you need to enable group-hover in tailwind config file.
You can control whether group-hover variants are enabled for a utility in the variants section of your tailwind.config.js file:
module.exports = {
variants: {
textColor: ['responsive', 'hover', 'focus', 'group-hover'],
},
}

Blazor Animation - set div to display: none after animation ends

Recently I have implemented some animations but I am having some problems when the animation ends. I have a div structure for responsiveness, that shows a menu button when the screen size is smaller than X.
When someone clicks on the menu button a left side bar, which is default set to display:none, is being shown by removing the display: none property immediately and then adding an animation class, this all works fine.
However, when the sidebar is collapsed again (by clicking on a close button), a new animation (for removing the menu) is being added, when this animation ends I need to set the display back to display:none (I don't want the sidebar take up any space).
In the current situation I accomplished this by setting some boolean variables that add display:none on false and removes it on true. My animation takes up to 300MS so I added a Task.Delay of 300MS to set the boolean. Sadly this doesn't create a perfect 'flow', you can see the screen hiccup because the setting of the display:none happens just a few MS to late. Of course I can decrease the Task.Delay to 290MS~ but this isn't a great solution.
Any ideas how I can accomplish this using Blazor?
Below the code:
HTML:
<!-- The mobile side bar, display: none default on screen sizes > X -->
<div class="md:hidden" style=#mobileSideBarDisplay>
<div class="fixed inset-0 flex z-40">
<! this sets the opacity of tyhe space to the right (grayed out) -->
<div class="fixed inset-0 #sidebarOverlayAnimation">
<div class="absolute inset-0 bg-gray-600 opacity-75"></div>
</div>
<!-- the actual side bar with it's buttons -->
<div class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4 bg-gray-800 #sidebarMenuAnimation">
<!-- Close button with which the sidebar menu can be closed -->
<button class=".." aria-label="Close sidebar" #onclick="ToggleSidebar"></button>
... Left out for readability
</div>
</div>
</div>
<!-- Static sidebar for desktop -->
<div class="hidden md:flex md:flex-shrink-0">
.. Left out for readability
</div>
<!-- menu button div which becomes visible at screensize < X
<div class="flex flex-col w-0 flex-1 overflow-hidden">
<!-- Menu button with which the sidebar menu can be opened -->
<button class=".. md:hidden" aria-label="Open sidebar" #onclick="ToggleSidebar">
.. Left out for readability
</div>
C# backend code:
#code {
// used to set display: none; (or empty)
private bool showMobileSideBar = false;
// Used to show / toggle animations
private bool showMobileSideBarAnimation = false;
// toggle animation and display classes
private string mobileSideBarDisplay => showMobileSideBar ? "" : "display: none;";
private string sidebarOverlayAnimation => showMobileSideBarAnimation ? "sidebar-overlay-animation-entering" : "sidebar-overlay-animation-leaving";
private string sidebarMenuAnimation => showMobileSideBarAnimation ? "sidebar-menu-animation-entering" : "sidebar-menu-animation-leaving";
// Function to display entering or leaving animation depending on the boolean value)
private async Task ToggleSidebar()
{
showMobileSideBarAnimation = !showMobileSideBarAnimation;
if (showMobileSideBar == true) // only delay when we need to set div to display: none;
{
await Task.Delay(300); // this works kinda clunky now
}
showMobileSideBar = !showMobileSideBar;
}
}
The CSS / animations:
/*
Animations for setting the right-space opacity (when the sidebar is shown / hidden)
*/
.sidebar-overlay-animation-entering {
animation-name: sidebar-overlay-entering;
animation-duration: 300ms;
animation-timing-function: linear;
}
#keyframes sidebar-overlay-entering {
from { opacity: 0; }
to { opacity: 1; }
}
.sidebar-overlay-animation-leaving {
animation-name: sidebar-overlay-leaving;
animation-duration: 300ms;
animation-timing-function: linear;
}
#keyframes sidebar-overlay-leaving {
from { opacity: 1; }
to { opacity: 0; }
}
/*
Animations for displaying the sidebar (in- and out)
*/
.sidebar-menu-animation-entering {
animation-name: sidebar-menu-entering;
animation-duration: 300ms;
animation-timing-function: ease-in-out;
}
#keyframes sidebar-menu-entering {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
.sidebar-menu-animation-leaving {
animation-name: sidebar-menu-leaving;
animation-duration: 300ms;
animation-timing-function: ease-in-out;
}
#keyframes sidebar-menu-leaving {
from { transform: translateX(0); }
to { transform: translateX(-100%); }
}
P.S. I tried using https://github.com/dazinator/BlazorDeferredRemove but I cant get it this to work. There is also not an example using animations (only transition with visibility) or using display: none; (But perhaps the library can work if someone could give a few pointers)

How to smooth horizontal collapse transition with React-Bootstrap?

Edit: CodeSandbox link: https://codesandbox.io/s/strange-dawn-q9zow
I'm creating a React app that I want to have a collapsible sidebar. I'm using the transition collapse utility from React-Bootstrap. Since this is for a sidebar, I'm using dimension="width". I've tried adding a transition to a few elements including the .width class as it says in the React-Bootstrap documentation, but the animation is still really choppy/not smooth. Am I missing a class, or is there something additional I need to do with the CSS?
JSX:
import React, {useState} from 'react';
import Button from 'react-bootstrap/Button';
import Collapse from 'react-bootstrap/Collapse';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Redirect,
useHistory,
useLocation
} from "react-router-dom";
import '../../custom_styles/sidebar.css';
function Visualizer() {
const [open, setOpen] = useState(false);
return (
<Router>
<div className="container-fluid h-100 p-0">
<div className="row h-100 no-gutters">
<Collapse id="sidebar" dimension="width" in={open}>
<div className="col-4 bg-dark text-white" id="example-collapse-text">
<h2>Palette</h2>
</div>
</Collapse>
<div className="col-8">
<Button
className="float-left ml-n1"
variant="dark"
onClick={() => setOpen(!open)}
aria-controls="example-collapse-text"
aria-expanded={open}
>
<div id="collapse-btn-text">Toggle Sidebar</div>
</Button>
</div>
</div>
</div>
</Router>
)
}
export default Visualizer;
CSS:
#sidebar {
transition: width 2s;
}
.width {
transition: width 2s;
}
.show {
transition: width 2s;
}
You can try to use this css
#sidebar {
transition: width 2s ease;
display: block;
width: 0;
}
#sidebar.yourActiveClass {
width: auto;
}
But first when you click on
<div id="collapse-btn-text">Toggle Sidebar</div>
button you shoule add "yourActiveClass" in
<Collapse id="sidebar" dimension="width" className={true ? "collapse width yourActiveClass" : "collapse width"} in={open}>
true means your Click function if true
using this you can more smooth your section.

hover effect with vuetify cards (nuxt)

I have a vuetify card like this :
<v-card class="news__card">
<v-card-media
:src="ip.images[0].url"
height="150px"
#click="onLoadNews(ip.id)"
/>
<v-card-title primary-title #click="onLoadNews(ip.id)">
<div class="news__card__down">
<h3 class="subheading font-weight-medium">{{ ip.headline }}</h3>
<div class="published">{{ ip.date }}</span> </div>
</div>
</v-card-title>
</v-card>
And i want to give an effect hover the card that apply a transform on the background image. It works when i hover .v-card__media__background with this :
.v-card__media__background:hover {
position: relative;
animation: scaleMe 500ms ease-in-out 0s forwards;
}
#keyframes scaleMe {
100% {
transform: scale(1.2);
}
}
but i would like to have this effect when hovering everywhere in the card.
You can use the following solution to solve your problem:
.news__card:hover .v-card__media__background {
// your animation...
}

Resources