Navigation flyout avec CSS Grid
Utilisation de CSS Grid au lieu de position: absolute pour positionner les éléments en plusieurs colonnes
by oilvier
HTML
<ul role="list" class="navigation">
<li class="navigation-item"><a href="#">Nos produits</a>
<ul class="navigation-flyout navigation-flyout--1" style="--nav-items-count: 4;">
<li class="navigation-item"><a href="#">Accès léger</a>
<ul class="navigation-flyout navigation-flyout--2" style="--nav-items-count: 5;">
<li class="navigation-item"><a href="#">Échelles</a></li>
<li class="navigation-item"><a href="#">Marchands</a>
<ul class="navigation-flyout navigation-flyout--3">
<li><a href="#">Accessoires</a></li>
<li><a href="#">Autres</a></li>
<li><a href="#">Lien 1</a></li>
<li><a href="#">Lien 2</a></li>
<li><a href="#">Lien 3</a></li>
<li><a href="#">Lien 4</a></li>
<li><a href="#">Lien 5</a></li>
<li><a href="#">Lien 6</a></li>
<li><a href="#">Lien 7</a></li>
</ul>
</li>
<li class="navigation-item"><a href="#">Plateforme</a></li>
<li class="navigation-item"><a href="#">Échafaudage</a></li>
<li class="navigation-item"><a href="#">Test</a></li>
</ul>
</li>
<li class="navigation-item"><a href="#">Échaffaudage de façade</a></li>
<li class="navigation-item"><a href="#">EPI Antichute</a></li>
<li class="navigation-item"><a href="#">Modulaire circulation</a></li>
</ul>
</li>
<li class="navigation-item"><a href="#">Nos services</a></li>
<li class="navigation-item"><a href="#">Conseils</a></li>
<li class="navigation-item"><a href="#">Contact</a></li>
</ul>
CSS
.navigation {
position: relative;
list-style: none;
padding-left: 0;
margin: 0;
display: flex;
gap: 10px;
}
.navigation ul {
list-style: none;
padding-left: 0;
margin: 0;
}
.navigation-flyout {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 2;
background-color: beige;
display: none;
}
.navigation-flyout--1 {
grid-template-columns: 1fr 2fr;
}
/**
* 1. We use `display: contents;` on the `li` to make its children use the parent `.navigation-flyout` as the grid container
*/
.navigation-flyout > li {
position: relative;
display: contents; /* [1] */
}
.navigation-flyout > li > a {
grid-column: 1;
}
/**
* 1. To keep the alignment of elements in our grid, `grid-row-end` value must be "number of visible items + 1"
* Here, we need to add up the "number of `li` siblings" + "the `ul` of our flyout menu" + 1.
* In order to do that math, we use a custom property populated on the template side to find the number of `li` siblings and we add 1 for the `ul` and 1 more for the trick to work.
*/
.navigation-flyout--2,
.navigation-flyout--3 {
position: relative;
top: auto;
grid-column: 2;
grid-row-start: 1;
grid-row-end: calc(var(--nav-items-count) + 2); /* [1] */
grid-template-columns: 1fr 1fr;
}
.navigation-flyout--2 {
background-color: lightblue;
}
.navigation-flyout--3 {
background-color: lightpink;
grid-template-columns: 1fr;
}
.navigation-item:hover > .navigation-flyout {
display: grid;
}