Bonjour,
J'essaye de faire un menu avec des sous menu en utilisant le moins possible du jQuery.
Après plusieurs tentatives, je revois ma manière de faire en plus simple
Contexte
Je veux utiliser les flexbox pour cela. J'ai donc fait un menu avec des sous-menus à plusieurs niveaux
Il a deux nav, un pour le menu et un nav pour le hamburger qui est pour le moment pas caché
Voici la structure de base:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
| <section class="e-panel">
<nav id="menu" class="e-panel-row" aria-label="Main navigation">
<ul class="e-justify-content-space-beween bg-black">
<li class="hasChildren">
<div>
<a href="#">A propo</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">Nous</a>
</div>
</li>
<li class="hasChildren">
<div>
<a href="#">Histoire</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">Création</a>
</div>
</li>
<li class="hasChildren">
<div>
<a href="#">Nos investisseurs</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu">
<li>
<div>
<a href="#">Entreprise SA</a>
</div>
</li>
<li>
<div>
<a href="#">Association</a>
</div>
</li>
<li>
<div>
<a href="#">Fundation</a>
</div>
</li>
</ul>
</li>
<li>
<div>
<a href="#">Développement</a>
</div>
</li>
</ul>
</li>
<li>
<div>
<a href="#">Situation</a>
</div>
</li>
</ul>
</li>
<li class="hasChildren">
<div>
<a href="#">Team</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">Direction</a>
</div>
</li>
<li>
<div>
<a href="#">Secrétaires</a>
</div>
</li>
<li>
<div>
<a href="#">Collaborateurs</a>
</div>
</li>
<li>
<div>
<a href="#">Partenaires</a>
</div>
</li>
</ul>
</li>
<li class="hasChildren">
<div>
<a href="#">Contact</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">Adresse</a>
</div>
</li>
<li>
<div>
<a href="#">Téléphone</a>
</div>
</li>
<li>
<div>
<a href="#">e-mail</a>
</div>
</li>
</ul>
</li>
<li>
<div>
<a href="#">New item 1</a>
</div>
</li>
<li>
<div>
<a href="#">New item 2</a>
</div>
</li>
<li>
<div>
<a href="#">New item 3</a>
</div>
</li>
<li>
<div>
<a href="#">Contact</a>
</div>
</li>
<li class="hasChildren">
<div>
<a href="#">Nous cours</a>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<i class="fa fa-angle-down"></i>
</a>
</div>
<ul class="sub-menu" role="group">
<li>
<div>
<a href="#">CSS Flex</a>
</div>
</li>
<li>
<div>
<a href="#">Boostrap</a>
</div>
</li>
<li>
<div>
<a href="#">Django</a>
</div>
</li>
<li>
<div>
<a href="#">React</a>
</div>
</li>
<li>
<div>
<a href="#">jQuery</a>
</div>
</li>
</ul>
</li>
</ul>
</nav>
<nav id="hamburger" class="e-panel-row bg-black">
<ul>
<li class="hamburger hasChildren">
<div>
<a href="#" class="dropdown-toggle" aria-expanded="false">
<span class="fa fa-navicon"></span>
</a>
</div>
</li>
</ul>
</nav>
</section> |
<section class="e-panel">
est le container des deux nav
<nav id="menu" class="e-panel-row" aria-label="Main navigation">
Permet de dire si le menu est horizontale ou verticale (vertical, ça sera pour plus tard
Voici le code flex qui me permet de structure mes éléments flex
1 2 3 4 5 6 7 8 9 10 11
| section.e-panel, section.e-panel{
display: flex;
flex-direction: row;
justify-content: space-between;
}
section.e-panel nav#menu{
flex: 1 1 auto;
}
section.e-panel nav#hamburger{
flex: 0 0 40px;
} |
<ul class="e-justify-content-space-beween bg-black">
est le container de menu qui me cause problème.
Voici le code CSS qui me permet de définir mes éléments flex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| /* First level */
nav.e-panel-row ul{
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
margin: 0 auto;
list-style: none;
box-sizing: border-box;
padding: 0px;
}
nav.e-panel-row ul li{
font-size: 1em;
position: relative;
flex: 1 0 auto;
text-align: center;
box-sizing: border-box;
}
nav.e-panel-row ul li a{
border: solid 0px yellow !important;
}
nav.e-panel-row ul li div{
padding: 10px;
}
/* hasChildren */
nav.e-panel-row ul li.hasChildren ul.sub-menu{
display: none;
position: absolute;
z-index: 1000;
background-color: #666;
width: 100%;
}
nav.e-panel-row ul li.hasChildren ul.sub-menu.toggled-on{
display: flex;
flex-wrap: wrap;
flex-direction: column;
box-sizing: border-box;
}
nav.e-panel-row ul li.hasChildren ul.sub-menu.toggled-on li{
flex: 1 1 auto;
}
nav.e-panel-row ul li.hasChildren ul.sub-menu.toggled-on li.hasChildren ul.sub-menu{
position: relative;
} |
Problématique
Si vous essayé le menu dans l'état actuel
https://www.eco-sensors.ch/temp/e-panel/, en diminuant le navigateur, vous avez
1. le hamburger qui apparait
2. les éléments du menu qui passe en ligne 2, au fure et à mesure que la navigateur diminue, et ceci grâce au flexbox
Jusqu'à la, tout est bon
Mon objectif est que les éléments qui passent en ligne 2, n'apparaisse pas et que le container. Puis en cliquant sur le hamburger, les éléments de la deuxièmes lignes apparaissent, là ou les flex les a positionné, soit sur la deuxième ligne, avec un petit effet, gende fadeOut/fadeIn. Pour cela, ca se fera avec du jQuery.
<nav id="menu" class="e-panel-row" aria-label="Main navigation">
ou plus tôt le container direct
<ul class="e-justify-content-space-beween bg-black">
Étant donnée que la taille des caractères peut variés en fonction d'un navigateur ou d'un écran, je ne veux pas utiliser des hauteurs fixes.
Voici ce que j'ai essayé de faire. Pour l'essai, j'ai utiliser une hauteur fix et un hoverflow
Sur le container principal, j'ai défini une hauteur impliquent les deux nav.
J'ai ajouté un overflow pour caché ce qui dépasse, soit la deuxième ligne
Je l'ai caché à moitié volontairement pour mon explication.
1 2 3 4 5 6 7
| div.e-panel, section.e-panel {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 60px;
overflow: hidden;
} |
Mes questions
- Est-ce qu'en CSS, je peux calculer la hauteur du container principale en fonction des hauteurs des li, sans passer par du javascript? calc(), ne peut pas aider?
- Est-ce qu'en CSS, je peux caché des éléments du deuxième niveaux, de manière à ce que la hauteur des containers ne se modifie pas. En jQuery, je peux ajouter une class à ces éléments, si la position top ($('meselements').position().top), n'est pas la même que le tout premier li du menu?
- Est-ce qu'en flex box, je peux "déclancher" un événement lorsque que les éléments flex passent sur la deuxième ligne?
Le problème que j'ai rencontré avec jQuery, est que lorsque je cache en élément de la deuxième ligne, son offset.top est 0, donc en dessus du premier élément li de mon menu
C'est pourquoi, je me penche sur une solution de hauteur du container principal avec un overflow, mais je ne sais pas si c'est la solution optimal.
Et vu que je privilège le CSS/Flexbox avant l'usage du jQuery, je me retourne vers vous.
Merci pour vos lumières
Partager