
This is a pure CSS approach to creating a responsive, animated, interactive navigation bar inspired by macOS dock interfaces.
It can be used to generate creative and user-friendly bottom navigation on your web app, where nav items (typically application icons) dynamically resize and reveal tooltips upon mouse interaction.
How to use it:
1. structure your HTML to include the dock and your app icons.
- Each
lielement represents an app icon in the dock. - Replace “app-1.png”, “app-2.png”, etc., with the paths to your app icons.
- Change the text within the
nav-item__tooltipdivs to the names of your apps.
<section class="docker">
<div class="nav-wrap">
<nav class="nav-bar">
<ul class="nav-list">
<li class="nav-item">
<a href="#" class="nav-item__link"><img src="app-1.png" loading="eager" alt="App icon" class="image"></a>
<div class="nav-item__tooltip">
<div>App 1</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="nav-item__link"><img src="app-2.png" loading="eager" alt="App icon" class="image"></a>
<div class="nav-item__tooltip">
<div>App 2</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="nav-item__link"><img src="app-3.png" loading="eager" alt="App icon" class="image"></a>
<div class="nav-item__tooltip">
<div>App 3</div>
</div>
</li>
... more app icons here ...
</ul>
</nav>
</div>
</section>2. Insert the necessary CSS styles to enable the dock’s functionality and appearance.
.docker {
padding: 2em;
justify-content: center;
align-items: center;
min-height: 100vh;
display: flex;
position: relative;
}
.nav-wrap {
z-index: 100;
pointer-events: none;
justify-content: center;
align-items: flex-end;
display: flex;
position: fixed;
inset: 0 0 10vh;
}
.nav-list {
flex-flow: row;
justify-content: center;
align-items: flex-end;
margin-bottom: 0;
padding-left: 0;
display: flex;
font-size: 1.4vw;
}
.nav-item {
justify-content: center;
align-items: center;
width: 5em;
transition: width .5s cubic-bezier(.16, 1, .3, 1);
display: flex;
position: relative;
}
.nav-item:hover {
width: 8em;
}
.nav-item:has(+ .nav-item:hover),
.nav-item:hover + .nav-item {
width: 7em;
}
.nav-item:has(+ .nav-item + .nav-item:hover),
.nav-item:hover + .nav-item + .nav-item {
width: 6em;
}
.nav-item__link {
z-index: 1;
pointer-events: auto;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
padding-left: .5em;
padding-right: .5em;
display: flex;
position: relative;
}
.image {
object-fit: contain;
width: 100%;
}
.nav-item__tooltip {
z-index: 0;
background-color: #ffffff;
opacity: 0;
white-space: nowrap;
border-radius: .25em;
padding: .4em .5em;
font-size: 1em;
transition: transform .5s cubic-bezier(.16, 1, .3, 1), opacity .5s cubic-bezier(.16, 1, .3, 1);
position: absolute;
top: 0;
transform: translate(0, -80%);
font-weight: 400;
}
.nav-item:hover .nav-item__tooltip{
opacity: 1;
transform:translate(0px, -140%);
}How It Works
The macOS inspired Dock Navigation Bar relies on the :has selector to create hover-based interactivity. When you hover over an icon, its size increases. Neighboring icons partially expand to maintain a smooth transition. This resizing is managed by cascading rules in CSS that check adjacent elements with :has.
Additionally, tooltips use opacity transitions for a fade-in effect, adding another layer of interactivity. The entire system is designed with efficiency in mind, keeping load times minimal.







