Skip to content

Instantly share code, notes, and snippets.

@jebbles
Last active August 28, 2024 22:36
Show Gist options
  • Save jebbles/22a419e8041df47d35fb182f944ca25d to your computer and use it in GitHub Desktop.
Save jebbles/22a419e8041df47d35fb182f944ca25d to your computer and use it in GitHub Desktop.
Attach tooltips to any HTML element, no classes or divs required! Uses data-attributes and pseudo-elements to minimize any additional markup or need to create a separate component. Can be used as a hover state or add your own custom logic! Made with Tailwind CSS.
/*
Copy this file to make this work:
<button data-tooltip="Hello!">Button</button>
No extra HTML tags or CSS classes needed!
Additional examples:
Stateless (always visible):
<button data-tooltip='Tooltip Text'>Button Text</button>
On hover (add data-hover attribute):
<button data-tooltip="Tooltip Text" data-hover>Button Text</button>
Custom logic (state ternary example):
<button data-tooltip={ state ? 'Tooltip Text' : null }>Button Text</button>
*/
/* Tooltips component */
[data-tooltip], [data-tooltip-top], [data-tooltip-bottom], [data-tooltip-left], [data-tooltip-right] {
@apply relative;
}
/* Tooltip text rendering */
:is([data-tooltip])::before {
content: attr(data-tooltip);
}
:is([data-tooltip-top])::before {
content: attr(data-tooltip-top);
}
:is([data-tooltip-bottom])::before {
content: attr(data-tooltip-bottom);
}
:is([data-tooltip-left])::before {
content: attr(data-tooltip-left);
}
:is([data-tooltip-right])::before {
content: attr(data-tooltip-right);
}
/* Tooltip styles */
:is([data-tooltip], [data-tooltip-top], [data-tooltip-bottom], [data-tooltip-left], [data-tooltip-right])::before {
@apply absolute block rounded-md py-1 px-2 bg-black/90 backdrop-blur-md whitespace-nowrap text-white text-xs text-center pointer-events-none z-20;
}
:is([data-tooltip], [data-tooltip-top], [data-tooltip-bottom], [data-tooltip-left], [data-tooltip-right])::after {
content: '';
@apply absolute block border-[8px] border-transparent pointer-events-none z-20;
}
/* Tooltip states & animations */
:is([data-tooltip], [data-tooltip-top], [data-tooltip-bottom], [data-tooltip-left], [data-tooltip-right])::before,
:is([data-tooltip], [data-tooltip-top], [data-tooltip-bottom], [data-tooltip-left], [data-tooltip-right])::after {
@apply visible;
}
:is([data-hover])::before,
:is([data-hover])::after {
@apply transition-all delay-[0] opacity-0 invisible !important;
}
:is([data-hover]):hover::before,
:is([data-hover]):hover::after {
@apply transition-all delay-[400ms] opacity-100 visible !important;
}
/* Tooltips positioning */
:is([data-tooltip], [data-tooltip-top])::before {
@apply bottom-[calc(100%-2px)] translate-y-[-50%] left-[50%] translate-x-[-50%];
}
:is([data-tooltip], [data-tooltip-top])::after {
@apply bottom-[calc(100%+2px)] translate-y-[50%] left-[50%] translate-x-[-50%] border-t-black/90;
}
[data-tooltip-bottom]::before {
@apply top-[calc(100%+10px)] left-[50%] translate-x-[-50%];
}
[data-tooltip-bottom]::after {
@apply top-[calc(100%+2px)] translate-y-[-50%] left-[50%] translate-x-[-50%] border-b-black/90;
}
[data-tooltip-left]::before {
@apply right-[calc(100%+8px)] top-[50%] translate-y-[-50%];
}
[data-tooltip-left]::after {
@apply right-[calc(100%+2px)] translate-x-[50%] top-[50%] translate-y-[-50%] border-l-black/90;
}
[data-tooltip-right]::before {
@apply left-[calc(100%+8px)] top-[50%] translate-y-[-50%];
}
[data-tooltip-right]::after {
@apply left-[calc(100%+2px)] translate-x-[-50%] top-[50%] translate-y-[-50%] border-r-black/90;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment