Je suis en train de créer un menu déroulant et je l'ai obtenu à peu près comme je le souhaite, mais la façon dont j'ai réalisé la mise en page rend la zone de survol un peu trop grande sur le côté droit, illustrée ici par la boîte grise. Je veux que le survol de la boîte grise (l'élément .dropdown) soit traité comme la zone blanche et que je ferme la liste déroulante.
Comment puis-je faire disparaître le menu lorsque je survole la zone grise .dropdown?
démo de travail ici: https://codepen.io/anon/pen/BMarBb? éditeurs = 1100
<nav role="navigation">
<ul>
<li><a href="#">One</a>
<ul class="dropdown dropdown1">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-A</a></li>
<li><a href="#">Sub-B</a></li>
<li><a href="#">Sub-C</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Two</a>
<ul class="dropdown dropdown2">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-1</a></li>
<li><a href="#">Sub-2</a></li>
<li><a href="#">Sub-3</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Three</a></li>
</ul>
</nav>
a {
text-decoration: none;
}
nav {
font-family: monospace;
margin-left: 300px;
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
}
li {
color: #fff;
background: darkorange;
display: block;
float: left;
padding: 1rem;
position: relative;
text-decoration: none;
transition-duration: 0.5s;
}
li a {
color: #fff;
}
li:hover {
cursor: pointer;
}
.dropdown {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
margin-top: 1rem;
left: 0;
display: none;
margin-left: 50%;
background: silver;
}
li:hover .dropdown,
.dropdown:hover {
visibility: visible;
opacity: 1;
display: block;
}
.dropdown li {
clear: both;
white-space: nowrap;
background: none;
}
.wrapper {
/* background: green; */
display: inline-block;
margin-left: -50%;
padding-top: 30px;
}
.inner {
background: darkorange;
display: inline-block;
box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
border-radius: 4px;
}
.inner:before,
.inner:after,
.inner li:first-child:after {
display: block;
content: "";
width: 0;
height: 0;
position: absolute;
left: -12px;
border: 12px outset transparent;
margin-top: 29px;
}
.inner:after {
border-bottom: 12px solid darkorange;
top: -23px;
}
3 Réponses :
Mon interprétation de votre question est que vous voulez que la liste déroulante se masque lorsque vous arrêtez de survoler la section orange.
Ce que j'ai fait à votre code ci-dessous est position: absolue les éléments avec gauche: 50% et transform: translate (-50%) . Cela alignera les éléments horizontalement au centre de manière à ce que les liens orange soient sur la zone grise.
<nav role="navigation">
<ul>
<li><a href="#">One</a>
<ul class="dropdown dropdown1">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-A</a></li>
<li><a href="#">Sub-B</a></li>
<li><a href="#">Sub-C</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Two</a>
<ul class="dropdown dropdown2">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-1</a></li>
<li><a href="#">Sub-2</a></li>
<li><a href="#">Sub-3</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Three</a></li>
</ul>
</nav>
a {
text-decoration: none;
}
nav {
font-family: monospace;
margin-left: 300px;
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
}
li {
color: #fff;
background: darkorange;
display: block;
float: left;
padding: 1rem;
position: relative;
text-decoration: none;
transition-duration: 0.5s;
}
li a {
color: #fff;
}
li:hover {
cursor: pointer;
}
.dropdown {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
margin-top: 1rem;
left: 50%;
display: none;
transform: translate(-50%);
background: silver;
}
li:hover .dropdown,
.dropdown:hover {
visibility: visible;
opacity: 1;
display: block;
}
.dropdown li {
clear: both;
white-space: nowrap;
background: none;
}
.wrapper {
/* background: green; */
display: inline-block;
padding-top: 30px;
}
.inner {
background: darkorange;
display: inline-block;
box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
border-radius: 4px;
}
.inner:before,
.inner:after,
.inner li:first-child:after {
display: block;
content: "";
width: 0;
height: 0;
position: absolute;
left: 50%;
transform: translate(-50%);
border: 12px outset transparent;
margin-top: 29px;
}
.inner:after {
border-bottom: 12px solid darkorange;
top: -23px;
}
Voir les commentaires en ligne sur le CSS pour savoir comment je contrôle les événements de survol pour des éléments spécifiques. Cette approche laisse la zone grise directement au-dessus de la liste déroulante active, ce qui, à mon avis, est un bon comportement.
Remarque: cela peut ne pas fonctionner dans Safari. Voir https://caniuse.com/#feat=pointer .
<nav role="navigation">
<ul>
<li><a href="#">One</a>
<ul class="dropdown dropdown1">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-A</a></li>
<li><a href="#">Sub-B</a></li>
<li><a href="#">Sub-C</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Two</a>
<ul class="dropdown dropdown2">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-1</a></li>
<li><a href="#">Sub-2</a></li>
<li><a href="#">Sub-3</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Three</a></li>
</ul>
</nav>
a {
text-decoration: none;
}
nav {
font-family: monospace;
margin-left: 300px;
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
}
li {
color: #fff;
background: darkorange;
display: block;
float: left;
padding: 1rem;
position: relative;
text-decoration: none;
transition-duration: 0.5s;
}
li a {
color: #fff;
}
li:hover {
cursor: pointer;
}
.dropdown {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
margin-top: 1rem;
left: 0;
display: none;
margin-left: 50%;
background: silver;
pointer-events: none; /* <-- disable hover events */
}
li:hover .dropdown,
.dropdown:hover {
visibility: visible;
opacity: 1;
display: block;
}
.dropdown li {
clear: both;
white-space: nowrap;
background: none;
}
.wrapper {
/* background: green; */
display: inline-block;
margin-left: -50%;
padding-top: 30px;
pointer-events: all; /* <-- enable hover events */
}
.inner {
background: darkorange;
display: inline-block;
box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
border-radius: 4px;
}
.inner:before,
.inner:after,
.inner li:first-child:after {
display: block;
content: "";
width: 0;
height: 0;
position: absolute;
left: -12px;
border: 12px outset transparent;
margin-top: 29px;
}
.inner:after {
border-bottom: 12px solid darkorange;
top: -23px;
}
Une autre façon de résoudre votre problème est de supprimer margin-left sur .dropdown et .wrapper , puis centrez la flèche avec:
<nav role="navigation">
<ul>
<li><a href="#">One</a>
<ul class="dropdown">
<li><a href="#">Sub-A</a></li>
<li><a href="#">Sub-B</a></li>
<li><a href="#">Sub-C</a></li>
</ul>
</li>
<li><a href="#">Two</a>
<ul class="dropdown">
<li><a href="#">Sub-1</a></li>
<li><a href="#">Sub-2</a></li>
<li><a href="#">Sub-3</a></li>
</ul>
</li>
<li><a href="#">Three</a></li>
</ul>
</nav> Puisqu'il y a aussi un margin-top sur cet élément, vous pouvez écrire margin: 29px auto 0; au lieu de margin-left et margin-right.
a { text-decoration: none; }
nav {
font-family: monospace;
margin-left: 300px;
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
}
li {
color: #fff;
background: darkorange;
display: block;
float: left;
padding: 1rem;
position: relative;
text-decoration: none;
transition-duration: 0.5s;
}
li a { color: #fff; }
li:hover { cursor: pointer; }
.dropdown {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
margin-top: 1rem;
left: 0;
display: none;
}
li:hover .dropdown {
visibility: visible;
opacity: 1;
display: block;
}
.dropdown { padding-top: 30px; }
.dropdown li {
clear: both;
white-space: nowrap;
position: relative;
}
.dropdown li:first-child { border-radius: 4px 4px 0 0; }
.dropdown li:last-child { border-radius: 0 0 4px 4px; }
.dropdown li:first-child:before {
content: "";
bottom: 100%;
left: 50%;
border: solid transparent;
height: 0;
width: 0;
position: absolute;
border-bottom-color: darkorange;
border-width: 12px;
margin-left: -12px;
}
<nav role="navigation">
<ul>
<li><a href="#">One</a>
<ul class="dropdown dropdown1">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-A</a></li>
<li><a href="#">Sub-B</a></li>
<li><a href="#">Sub-C</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Two</a>
<ul class="dropdown dropdown2">
<section class="wrapper">
<section class="inner">
<li><a href="#">Sub-1</a></li>
<li><a href="#">Sub-2</a></li>
<li><a href="#">Sub-3</a></li>
</section>
</section>
</ul>
</li>
<li><a href="#">Three</a></li>
</ul>
</nav>
Edit: comme Chiller et Temani Afif l'ont dit dans la section commentaires, la structure de votre code n'est pas valide. J'ai fait un nettoyage rapide de votre exemple afin que vous puissiez voir ce que vous pouvez faire avec des éléments moins encapsulés.
a {
text-decoration: none;
}
nav {
font-family: monospace;
margin-left: 300px;
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
}
li {
color: #fff;
background: darkorange;
display: block;
float: left;
padding: 1rem;
position: relative;
text-decoration: none;
transition-duration: 0.5s;
}
li a {
color: #fff;
}
li:hover {
cursor: pointer;
}
.dropdown {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
margin-top: 1rem;
left: 0;
display: none;
background: silver;
}
li:hover .dropdown,
.dropdown:hover {
visibility: visible;
opacity: 1;
display: block;
}
.dropdown li {
clear: both;
white-space: nowrap;
background: none;
}
.wrapper {
/* background: green; */
display: inline-block;
padding-top: 30px;
}
.inner {
background: darkorange;
display: inline-block;
box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
border-radius: 4px;
}
.inner:before,
.inner:after,
.inner li:first-child:after {
display: block;
content: "";
width: 0;
height: 0;
position: absolute;
border: 12px outset transparent;
left: 0;
right: 0;
margin: 29px auto 0;
}
.inner:after {
border-bottom: 12px solid darkorange;
top: -23px;
}
margin-right: auto; margin-left: auto; left: 0; right: 0;
Est-il acceptable d'utiliser autre chose que
???
@Chiller non, ce n'est pas ok et ça devrait être corrigé. c'est invalide
C'est un excellent point. Billy, je déplacerais vos éléments de style dans les éléments de la liste (et utiliserais plutôt des pseudo-éléments là où vous le pouvez).
@TemaniAf si c'est ce que je pensais ... peut-être qu'il devrait utiliser
- ...
à la place