Dock
A macOS-style magnifying dock. Built entirely with CSS :has() for buttery-smooth performance. Zero JavaScript calculations, zero Framer Motion.
Playground Controls
Installation
1. Copy the React component into your project:
tsx
import * as React from "react";
export interface DockProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
position?: "bottom" | "top" | "left" | "right";
}
export function Dock({
children,
className = "",
position = "bottom",
...props
}: DockProps) {
return (
<div className={`bare-dock bare-dock-${position} ${className}`} {...props}>
{children}
</div>
);
}
export interface DockItemProps extends React.HTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
onClick?: () => void;
}
export function DockItem({
children,
className = "",
onClick,
...props
}: DockItemProps) {
return (
<button
className={`bare-dock-item ${className}`}
onClick={onClick}
{...props}
>
{children}
</button>
);
}
2. Add the required CSS to your global stylesheet:
css
/* Bare Dock */
.bare-dock {
display: flex;
align-items: flex-end;
gap: 0.5rem;
padding: 0.5rem;
border-radius: 1.5rem;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
width: fit-content;
margin: 0 auto;
}
.bare-dock-bottom { align-items: flex-end; }
.bare-dock-top { align-items: flex-start; }
.bare-dock-item {
width: 3rem;
height: 3rem;
border-radius: 1rem;
background: var(--bg-primary);
border: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.25, 1, 0.5, 1);
transform-origin: bottom;
color: var(--text-primary);
flex-shrink: 0;
}
.bare-dock-top .bare-dock-item { transform-origin: top; }
.bare-dock-item:hover {
width: 5rem;
height: 5rem;
margin: 0 0.5rem;
background: var(--bg-secondary);
color: var(--accent);
}
.bare-dock-item:has(+ .bare-dock-item:hover),
.bare-dock-item:hover + .bare-dock-item {
width: 4rem;
height: 4rem;
margin: 0 0.25rem;
}
.bare-dock-item:has(+ .bare-dock-item + .bare-dock-item:hover),
.bare-dock-item:hover + .bare-dock-item + .bare-dock-item {
width: 3.5rem;
height: 3.5rem;
margin: 0 0.125rem;
}Usage
tsx
import { Dock, DockItem } from '@/components/ui/dock';
export default function App() {
return (
<Dock>
<DockItem onClick={() => console.log('Home')}>🏠</DockItem>
<DockItem onClick={() => console.log('Search')}>🔍</DockItem>
<DockItem onClick={() => console.log('Messages')}>💬</DockItem>
<DockItem onClick={() => console.log('Settings')}>⚙️</DockItem>
<DockItem onClick={() => console.log('Profile')}>👤</DockItem>
</Dock>
);
}