Grid Flyouts
Flyout Menu with Descriptions
A flyout menu with detailed descriptions for each item. Perfect for feature-rich navigation with explanatory text.
<div
class="relative h-24"
x-data="{
uid: Math.random().toString(36).slice(2),
// Set to true to show the flyout open by default. Change to false to have it closed by default.
open: true,
style: '',
gap: 8,
align() {
const r = this.$refs.btn.getBoundingClientRect();
const left = r.left + r.width / 2; // center under button
const top = r.bottom + this.gap; // just below
this.style = `position:fixed; left:${left}px; top:${top}px; transform:translateX(-50%);`;
},
toggle() {
if (this.open) { this.open = false; return; }
window.dispatchEvent(new CustomEvent('close-all-flyouts', { detail: this.uid }));
this.align();
requestAnimationFrame(() => { this.open = true; });
},
close() { this.open = false; }
}"
x-init="
// Close when another flyout opens
window.addEventListener('close-all-flyouts', (e) => { if (e.detail !== uid) open = false });
// Keep position synced while open
const realign = () => { if (open) align() };
window.addEventListener('resize', realign);
window.addEventListener('scroll', realign, { passive: true });
// If open by default, align immediately
if (open) align();
"
>
<button
class="relative flex items-center justify-center text-center font-medium transition-colors duration-200 ease-in-out select-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:z-10 rounded-md text-zinc-600 bg-zinc-50 outline outline-zinc-100 hover:bg-zinc-200 focus-visible:outline-zinc-600 dark:text-zinc-100 dark:bg-zinc-800 dark:outline-zinc-800 dark:hover:bg-zinc-700 dark:focus-visible:outline-zinc-700 h-9 px-4 text-sm gap-2.5"
x-ref="btn"
aria-expanded="false"
@click.stop="toggle"
>
<span>Button</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="icon icon-tabler-chevron-down size-4"
slot="right-icon"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M6 9l6 6l6 -6"></path>
</svg>
</button>
<!-- Backdrop for click-outside -->
<div
x-show="open"
x-transition.opacity
class="fixed inset-0 z-(--z-overlay-backdrop)"
@click="close"
style="display: none"
></div>
<div
x-show="open"
:style="style"
class="z-(--z-overlay-panel)"
style="display: none"
@keydown.escape.window="close"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 translate-y-1"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-1"
>
<div
class="flex-auto w-screen max-w-md overflow-hidden bg-white shadow-lg dark:bg-zinc-800 rounded-xl outline outline-zinc-900/5 dark:outline-white/10 lg:max-w-3xl"
>
<div class="p-4 grid grid-cols-1 gap-x-0 gap-y-1 lg:grid-cols-2">
<div class="p-4" role="none">
<div class="text-xs font-medium text-zinc-900 dark:text-white">
Benefits
</div>
<div class="flex flex-col mt-2 gap-4">
<a class="text-sm flex items-center w-full group gap-2" href="#_">
<div
class="flex items-center justify-center flex-none rounded-lg duration-300 size-11 bg-zinc-50 dark:bg-white/5 group-hover:bg-white dark:group-hover:bg-white/10"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="icon icon-tabler-arrow-refresh size-5 group-hover:text-zinc-500 dark:group-hover:text-zinc-400 text-zinc-500 dark:text-zinc-400"
slot="left-icon"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4"></path>
<path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4"></path>
</svg>
</div>
<div>
<div
class="text-base flex items-center w-full font-medium text-zinc-900 dark:text-white group-hover:text-zinc-500 dark:group-hover:text-zinc-400 gap-2"
>
Sync across devices
</div>
<p
class="text-sm font-medium text-zinc-500 dark:text-zinc-400"
>
Enable syncing across devices
</p>
</div>
</a>
<a class="text-sm flex items-center w-full group gap-2" href="#_">
<div
class="flex items-center justify-center flex-none rounded-lg duration-300 size-11 bg-zinc-50 dark:bg-white/5 group-hover:bg-white dark:group-hover:bg-white/10"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="icon icon-tabler-external-file-dots size-5 group-hover:text-zinc-500 dark:group-hover:text-zinc-400 text-zinc-500 dark:text-zinc-400"
slot="left-icon"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
<path
d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"
></path>
<path d="M9 14v.01"></path>
<path d="M12 14v.01"></path>
<path d="M15 14v.01"></path>
</svg>
</div>
<div>
<div
class="text-base flex items-center w-full font-medium text-zinc-900 dark:text-white group-hover:text-zinc-500 dark:group-hover:text-zinc-400 gap-2"
>
Create custom documents
</div>
<p
class="text-sm font-medium text-zinc-500 dark:text-zinc-400"
>
Style your documents with ease
</p>
</div>
</a>
<a class="text-sm flex items-center w-full group gap-2" href="#_">
<div
class="flex items-center justify-center flex-none rounded-lg duration-300 size-11 bg-zinc-50 dark:bg-white/5 group-hover:bg-white dark:group-hover:bg-white/10"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="icon icon-tabler-external-edit size-5 group-hover:text-zinc-500 dark:group-hover:text-zinc-400 text-zinc-500 dark:text-zinc-400"
slot="left-icon"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path
d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"
></path>
<path
d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"
></path>
<path d="M16 5l3 3"></path>
</svg>
</div>
<div>
<div
class="text-base flex items-center w-full font-medium text-zinc-900 dark:text-white group-hover:text-zinc-500 dark:group-hover:text-zinc-400 gap-2"
>
Edit your files
</div>
<p
class="text-sm font-medium text-zinc-500 dark:text-zinc-400"
>
Endless possibilities
</p>
</div>
</a>
</div>
</div>
<div class="p-4">
<div class="text-base font-medium text-zinc-900 dark:text-white">
Browse by feature
</div>
<div
class="pt-4 mt-4 border-t border-zinc-200 dark:border-zinc-700 space-y-2"
role="none"
>
<a
class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400"
href="#"
>
Formatted text and markdown </a
><a
class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400"
href="#"
>
Themes for your documentation </a
><a
class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400"
href="#"
>
Convert and export to PDF </a
><a
class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400"
href="#"
>
Samsung pen support </a
><a
class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400"
href="#"
>
Flowcharts and diagrams </a
><a
class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400"
href="#"
>
Quick translations
</a>
</div>
</div>
</div>
<div class="p-4 pt-0">
<div
class="items-end p-8 shadow grid grid-cols-1 md:grid-cols-3 bg-linear-to-b outline outline-zinc-100 dark:outline-zinc-800 from-zinc-50 to-zinc-100 dark:from-zinc-800 dark:to-zinc-900 rounded-xl"
>
<div class="md:col-span-2">
<h2
class="text-lg md:text-xl font-semibold text-zinc-900 dark:text-white"
>
Ready to get started?
</h2>
<p
class="text-base mt-2 font-medium text-zinc-500 dark:text-zinc-400 lg:text-balance"
>
Take your markup to the next level with Oxbow
</p>
</div>
<button
class="relative flex items-center justify-center text-center font-medium transition-colors duration-200 ease-in-out select-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:z-10 rounded-md text-white bg-zinc-900 outline outline-zinc-900 hover:bg-zinc-950 focus-visible:outline-zinc-950 dark:bg-zinc-100 dark:text-zinc-900 dark:outline-zinc-100 dark:hover:bg-zinc-200 dark:focus-visible:outline-zinc-200 h-9 px-4 text-sm mt-4 lg:justify-self-end"
>
Get started
</button>
</div>
</div>
</div>
</div>
</div>
Features
- Multi-column grid layout - Organized content in responsive grids
- Item descriptions - Detailed text for each menu item
- Call-to-action sections - Prominent CTAs with descriptions
- Responsive design - Adapts from single to multi-column on larger screens
- Enhanced hover states - Interactive feedback on all elements
- Mixed content types - Icons, text, links, and buttons
Usage
---
import GridFlyout from '/src/components/flyouts/GridFlyout.astro'
---
<!-- Basic usage -->
<GridFlyout />
<!-- With initial state -->
<GridFlyout open={true} />
Customization
Grid Layout
Modify the grid classes to change column structure:
<!-- 3 columns on large screens -->
<div class="p-4 grid grid-cols-1 lg:grid-cols-3 gap-4">
<!-- Content -->
</div>
<!-- Different gap sizes -->
<div class="p-4 grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Content -->
</div>
Content Sections
Add or remove sections as needed:
<div class="p-4">
<h3 class="text-base font-medium text-zinc-900 dark:text-white">
Your Section Title
</h3>
<div class="pt-4 mt-4 border-t border-zinc-200 dark:border-zinc-700 space-y-2">
<a href="#" class="text-base block font-medium hover:text-zinc-600 dark:hover:text-zinc-300 text-zinc-500 dark:text-zinc-400">
Your link item
</a>
</div>
</div>
Call-to-Action
Customize the CTA section:
<div class="p-4 pt-0">
<div class="items-end p-8 shadow grid grid-cols-1 md:grid-cols-2 bg-linear-to-r from-blue-50 to-indigo-100 dark:from-blue-900 dark:to-indigo-900 rounded-xl">
<div class="md:col-span-1">
<h2 class="text-lg font-semibold text-zinc-900 dark:text-white">
Your CTA Title
</h2>
<p class="text-base mt-2 font-medium text-zinc-500 dark:text-zinc-400">
Your CTA description
</p>
</div>
<button class="relative flex items-center justify-center text-center font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 h-9 px-4 text-sm mt-4">
Your CTA Button
</button>
</div>
</div>
Best Practices
- Content organization - Group related items together
- Visual hierarchy - Use clear headings and descriptions
- Mobile optimization - Ensure single-column layout works well on mobile
- Action clarity - Make CTAs prominent and descriptive
- Accessibility - Maintain proper focus order and ARIA labels