Я пытаюсь сделать всплывающее меню со следующими требованиями:
Мой код доступен здесь: https://codesandbox.io/s/jvk8zzqvz9
Проблема в том, что при увеличении масштаба в браузере появляются уродливые артефакты. Может быть, мой подход неверен, и есть лучший способ, как это сделать. Вот артефакты, которые я имею в виду:
Мой код здесь:
HTML:
<ul class = "menu">
<li class = "menu-item has-dropdown">
<div class = "dropdown-trigger">
<div class = "menu-content">
<a href = "">Hover me!</a>
</div>
</div>
<div class = "dropdown-content">
<div>Zde je nějaký obsah.</div>
<div>Zde taktéž</div>
<div>Hola hola.</div>
</div>
</li>
<li class = "menu-item has-dropdown">
<div class = "dropdown-trigger">
<div class = "menu-content">
<a href = "">Hover me!</a>
</div>
</div>
<div class = "dropdown-content">
Zde je obsah dropdownu.
</div>
</li>
<li class = "menu-item has-dropdown">
<div class = "dropdown-trigger">
<div class = "menu-content">
<a href = "">Hover me!</a>
</div>
</div>
<div class = "dropdown-content">
<div>Zde je nějaký obsah.</div>
<div>Zde taktéž</div>
<div>Hola hola.</div>
</div>
</li>
</ul>СКСС:
.menu {
margin: 0;
padding: 0;
list-style: none;
width: 200px;
.menu-content {
padding: 1rem;
}
.menu-item {
&.has-dropdown {
position: relative;
&:hover {
.dropdown-content {
transition-delay: 0.25s;
visibility: visible;
opacity: 1;
}
.dropdown-trigger {
transition-delay: 0.25s;
border: 1px solid green;
&::after {
transition-delay: 0.25s;
visibility: visible;
opacity: 1;
}
}
}
}
&:not(:last-child) > .dropdown-trigger {
border-bottom: none;
}
.dropdown-trigger {
position: relative;
border: 1px solid red;
&::after {
content: '';
transition: all 0s linear;
visibility: hidden;
opacity: 0;
position: absolute;
top: 0;
left: 100%;
height: 100%;
width: 1px + 2px;
background-color: white;
margin-left: -1px;
z-index: 20;
}
}
.dropdown-content {
transition: all 0s linear;
visibility: hidden;
opacity: 0;
border: 1px solid green;
margin-left: -1px;
position: absolute;
top: 0;
right: auto;
left: 100%;
min-width: 25rem;
padding: 1rem;
z-index: 19;
}
}
}Не подскажете, как добиться результата без видимых артефактов?






Вместо того, чтобы использовать хак псевдоэлемента, я буду использовать границу и сделать правый элемент белым с более высоким z-index, чтобы закрыть ненужный из выпадающего списка. Я также добавлю еще одно правило, чтобы скрыть верхнюю границу следующего элемента.
Вы заметите использование градиента для имитации белой правой границы. Я использовал его, чтобы избежать плохого эффекта, который вы увидите при увеличении, если вы используете правильную границу.
body {
font-family: sans-serif;
}
.menu {
margin: 0;
padding: 0;
list-style: none;
width: 200px;
}
.menu .menu-content {
padding: 1rem;
}
.menu .menu-item.has-dropdown {
position: relative;
}
.menu .menu-item.has-dropdown:hover .dropdown-content {
visibility: visible;
opacity: 1;
transition:0s opacity 0.8s;
}
.menu .menu-item.has-dropdown:hover .dropdown-trigger {
border-color: green;
/**/
border-right-width:0;
/* try border-right-color:#fff and you will have the same effect
but a small glitch when zooming
*/
background-size:1px 100%;
transition:0s all 0.8s;
position:relative;
z-index:20;
}
.menu .menu-item.has-dropdown:hover + * .dropdown-trigger {
border-top-color:green;
transition:0s border-top-color 0.8s;
}
.menu .menu-item:not(:last-child) > .dropdown-trigger {
border-bottom: none;
}
.menu .menu-item .dropdown-trigger {
position: relative;
border: 1px solid red;
background:linear-gradient(#fff,#fff) right/0px 100% no-repeat;
}
.menu .menu-item .dropdown-content {
transition: all 0s linear;
visibility: hidden;
opacity: 0;
border: 1px solid green;
margin-left: -1px;
position: absolute;
top: 0;
right: auto;
left: 100%;
min-width: 25rem;
padding: 1rem;
z-index: 19;
}<div>
<ul class = "menu">
<li class = "menu-item has-dropdown">
<div class = "dropdown-trigger">
<div class = "menu-content"><a href = "">Hover me!</a></div>
</div>
<div class = "dropdown-content">
<div>Content 1</div>
<div>Content 2</div>
<div>Content 3</div>
</div>
</li>
<li class = "menu-item has-dropdown">
<div class = "dropdown-trigger">
<div class = "menu-content"><a href = "">Hover me!</a></div>
</div>
<div class = "dropdown-content">Zde je obsah dropdownu.</div>
</li>
<li class = "menu-item has-dropdown">
<div class = "dropdown-trigger">
<div class = "menu-content"><a href = "">Hover me!</a></div>
</div>
<div class = "dropdown-content">
<div>Content 1</div>
<div>Content 2</div>
<div>Content 3</div>
</div>
</li>
</ul>
</div>@jezikk, вы можете просто добавить их обратно, как в свой код. Я удалил их, чтобы упростить код и сфокусировать внимание на соответствующей части кода.
Да, но есть проблема с задержкой. Не могу синхронизировать все части разделов.
@jezikk, можешь показать мне код с добавленной задержкой? Я увижу проблему
@jezikk нет, не добавляйте в качестве ответа, например, поместите его в jsfiddle.net
Спасибо. Он отлично работает, но, к сожалению, не для более длительной задержки. :( codeandbox.io/s/jvk8zzqvz9
@jezikk это связано с сохранением перехода следующего элемента, потому что я использовал all .. проверьте обновление, я сохранил только цвет верхней границы, так должно быть лучше
Да, это почти сделано. И последняя вещь — зеленая рамка сверху вниз, которая отображается сразу же, если меню наведено. Я совершенно не знаю, как это исправить.
@jezikk да, потому что это верхняя граница следующего элемента, найду хитрость;)
Честно говоря, я не нашел решения, как решить проблему с верхней границей. :(
Спасибо за помощь. Этот подход решил мои потребности. Последнее, чего я не знаю, это как добавить в код задержку перехода.