如何格式化悬停下拉菜单,使其始终位于顶层?

how to format on-hover dropdown so that it's always top-layer?

我有一个悬停下拉元素和一个点击下拉元素,它们紧挨着。我为下拉显示 div 提供了 "position: relative;" 属性。但是,这会导致图层视觉效果和光标指向出现问题。我将首先尝试描述,然后我将向代码笔提供图片和 link。

问题一:
我的悬停下拉菜单 div 超出了我的点击下拉元素,并且由于我认为 "position: relative;" 属性我必须为隐藏的下拉菜单提供,点击元素中的 span 元素显示在悬停下拉菜单的顶部。
inactive hover (for reference)
active hover

问题二:
假设问题 1 不是问题,并且视觉效果很好。如果我将光标放在悬停下拉菜单上,然后将光标向下移至悬停下拉菜单 div 中的最后一个选项,则光标认为它悬停在单击下拉菜单元素上,使浏览器相信悬停下拉菜单不再是悬停在什么地方然后变为非活动状态,即所有悬停 div 选项都被隐藏。由于问题的性质,我无法真正展示这张照片。

问题三:
我认为这是与问题 1 类似的问题,只是元素不同。假设您点击点击下拉菜单,让您看到它的所有选项。然后移动光标,使其悬停在悬停下拉元素上,这样您也可以看到所有这些选项。它分层以便单击选项显示在悬停选项之上,反之亦然。
inactive hover (for reference)
active hover

我知道我可以简单地移动这些元素,这样我就不必处理它了,但我觉得这更像是一个创可贴解决方案,我想要一个修复。同样,我觉得这似乎与位置属性设置为 relative 的两个元素有关,但如果我摆脱它,那么它们都会因多种不同原因而变得不稳定。

here's the codepen page, 抱歉,如果 css 中有一些内容引用了 html 中不存在的内容,我已尽我所能将其全部清理干净尽可能少的代码障碍。

谢谢!如果您需要更多说明,请告诉我。

...因为它不会让我 post 没有代码的代码笔 post,这里是代码:

for (const dropdown of document.querySelectorAll(".dropSelectWrap")) {
  dropdown.addEventListener('click', function() {
    this.querySelector('.dropSelect').classList.toggle('open');
  })
}

for (const option of document.querySelectorAll(".dropSelectOption")) {
  option.addEventListener('click', function() {
    if (!this.classList.contains('dropSelectChosen')) {
      this.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
      this.classList.add('dropSelectChosen');
      this.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = this.textContent;
    }
  })
}

window.addEventListener('click', function(e) {
  for (const select of document.querySelectorAll('.dropSelect')) {
    if (!select.contains(e.target)) {
      select.classList.remove('open');
    }
  }
});

function selectOption(index) {
  var optionOnIdx = document.querySelector('.dropSelectOption:nth-child(' + index + ')');
  var optionSelected = document.querySelector('.dropSelectOption.dropSelectChosen');
  if (optionOnIdx !== optionSelected) {
    optionSelected.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
    optionOnIdx.classList.add('dropSelectChosen');
    optionOnIdx.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = optionOnIdx.textContent;
  }
}
:root {
  font-size: 62.5%;
}

body {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
}


/* anything smaller */

@media only screen and (min-width: 0px) {
  .top-nav .dropdwn>.spanItem {
    display: none;
  }
}


/* desktop */

@media only screen and (min-width: 1500px) {
  .top-nav .dropdwn>.spanItem {
    display: block;
  }
  .top-nav .dropdwn>.buttItem {
    display: none;
  }
}

#outmostBox {
  width: 80rem;
}

header {
  margin-top: 4rem;
}

.bottomTopLinks .text,
header nav a {
  font-size: 1.45rem;
}


/* #region NAVBAR_HOVER */

#outmostBox {
  margin: 0;
  padding: 0;
  justify-items: center;
  display: grid;
}

header {
  justify-items: center;
  display: grid;
}

.dropNav * {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
}

nav,
.dropNav {
  width: 100%;
}

.dropNav .top-nav {
  display: flex;
  justify-content: center;
  padding: 0;
  font-size: 0;
  /* eliminates whitespace from inline-block*/
}

.top-nav div {
  display: inline-block;
  /* blocks just line up without floats */
  position: relative;
  /* sets positioning context for 2nd level menu */
  width: inherit;
}

.top-nav button {
  border: none;
}

.top-nav button:focus {
  outline: 0;
}

.top-nav .text,
.top-nav .sub-nav a {
  text-align: center;
  /* centeres the text horizontally */
  display: block;
  /* links now fill the block*/
  padding: 10px 20px;
}

.top-nav .text {
  text-decoration: underline;
}

.top-nav .text:hover,
.top-nav .sub-nav span>a:hover {
  background-color: rgba(228, 228, 228, 0.39);
}

.top-nav .sub-nav {
  /* positions the menu UNDER the list item*/
  position: absolute;
  width: 100%;
  /* hides the menu until needed */
  visibility: hidden;
  padding: 0;
}

.top-nav div:hover .sub-nav {
  /* shows the submenu when the list item is hovered */
  visibility: visible;
  box-shadow: 0 5px 4px rgba(0, 0, 0, 0.2), 0 11px 10px rgba(0, 0, 0, 0.19);
  border-bottom-right-radius: 5px;
  border-bottom-left-radius: 5px;
}

.top-nav .sub-nav div {
  background-color: white;
  width: 100%;
}

.top-nav .bottomItem {
  border-bottom-right-radius: 5px;
  border-bottom-left-radius: 5px;
}


/* #endregion */

#searchAndGenre {
  margin-top: 2rem;
  width: 100%;
  display: flex;
  justify-content: space-around;
}


/* everything below here is for the select drop-down */

.searchBar .searchTerm,
.selectDropCont {
  font-size: 1.45rem;
}

.searchCont,
.selectDropCont,
.selectDropCont .dropSelectWrap {
  width: 20rem;
}

.searchCont,
.selectDropCont,
.selectDropCont .dropSelectWrap,
.selectDropCont .dropSelectWrap .dropSelect span {
  height: 3.5rem;
}


/* #region SELECTDROP-INNARDS */

.selectDropCont *,
.selectDropCont *:after,
.selectDropCont *:before {
  box-sizing: border-box;
}

.selectDropCont,
.selectDropCont .dropSelectWrap {
  display: flex;
  align-items: center;
}

.selectDropCont {
  justify-content: center;
  align-items: center;
  background: rgba(250, 250, 250, 1);
}

.selectDropCont .dropSelectWrap {
  text-align: center;
}

.selectDropCont .dropSelectWrap .selectNameCont .selectName {
  width: 100%;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  user-select: none;
  border-width: 3px;
  border-color: rgba(151, 151, 151, 1);
  border-style: none solid none none;
}

.selectDropCont .dropSelectWrap .selectNameCont {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 35%;
}

.selectDropCont .dropSelectWrap {
  user-select: none;
}

.selectDropCont .dropSelectWrap .dropSelect {
  display: flex;
  flex-direction: column;
  border-width: 0;
  width: 65%;
}

.selectDropCont .dropSelectWrap>div {
  display: inline-block;
  /* blocks just line up without floats */
  height: 35px;
}

.selectDropCont .dropSelectWrap .dropSelect {
  position: relative;
  /* sets positioning context for 2nd level menu */
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  height: 35px;
  cursor: pointer;
  border-width: 0;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .centCont {
  width: 100%;
}

.selectDropCont .dropSelectWrap .dropSelectOptions {
  position: absolute;
  display: block;
  top: 100%;
  left: 0;
  right: 0;
  border: none;
  background: white;
  transition: all 0.5s;
  opacity: 0;
  visibility: hidden;
}

.selectDropCont .dropSelectWrap .dropSelect.open .dropSelectOptions {
  opacity: 1;
  visibility: visible;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption {
  width: 100%;
  justify-content: center;
  display: inline-flex;
  align-items: center;
  padding: 0 22px 0 22px;
  color: rgba(83, 83, 83, 1);
  line-height: 30px;
  cursor: pointer;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption:hover {
  cursor: pointer;
  background-color: rgba(228, 228, 228, 0.39);
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow {
  position: relative;
  height: 10px;
  width: 10px;
  padding: 5px 5px;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::before,
.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::after {
  content: "";
  position: absolute;
  bottom: 0px;
  width: 0.15rem;
  height: 100%;
  transition: all 0.5s;
}

.selectDropCont .arrow::before {
  left: -3px;
  transform: rotate(45deg);
  background-color: #394a6d;
}

.selectDropCont .arrow::after {
  left: 3px;
  transform: rotate(-45deg);
  background-color: #394a6d;
}

.selectDropCont .open .arrow::before {
  left: -3px;
  transform: rotate(-45deg);
}

.selectDropCont .open .arrow::after {
  left: 3px;
  transform: rotate(45deg);
}


/* #endregion */
<div id="outmostBox">

  <header>

    <nav class="bottomTopLinks">
      <div class="dropNav">
        <div class="top-nav">

          <div class="dropdwn"><span class="text spanItem">creative</span><button class="text buttItem">creative</button>
            <div class="sub-nav">
              <div><span><a href="?">photos</a></span></div>
              <div class="bottomItem"><span><a class="bottomItem" href="?">music</a></span></div>
            </div>
          </div>

        </div>
      </div>
    </nav>

  </header>
  <!-- new code below this line -->

  <div id="searchAndGenre">

    <div class="selectDropCont">
      <div class="dropSelectWrap">

        <div class="selectNameCont">
          <div class="selectName"><span>type</span></div>
        </div>

        <div class="dropSelect">
          <div class="dropSelectTrig">
            <div class="centCont"><span>all</span></div>
            <div class="arrow"></div>
          </div>
          <div class="dropSelectOptions">
            <span class="dropSelectOption dropSelectChosen" data-value="all">all</span>
            <span class="dropSelectOption" data-value="expository">expository</span>
            <span class="dropSelectOption" data-value="persuasive">persuasive</span>
            <span class="dropSelectOption" data-value="research">research</span>
            <span class="dropSelectOption" data-value="descriptive">descriptive</span>
          </div>
        </div>

      </div>
    </div>

  </div>
  <!-- new code above this line -->


</div>

好吧伙计们,看起来没有人会回答这个问题,所以对于任何看到这个问题并像我一样想知道 wtf 的人,这是我最好的回应。请随时提供更好的替代解决方案lmao。

在我让它工作之前,我对代码进行了很多修改,这是我的代码:

for (const dropdown of document.querySelectorAll(".dropSelectWrap")) {
        dropdown.addEventListener('click', function () {
            this.querySelector('.dropSelect').classList.toggle('open');
        })
    }

    for (const option of document.querySelectorAll(".dropSelectOption")) {
        option.addEventListener('click', function () {
            if (!this.classList.contains('dropSelectChosen')) {
                this.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
                this.classList.add('dropSelectChosen');
                this.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = this.textContent;
            }
        })
    }

    window.addEventListener('click', function (e) {
        for (const select of document.querySelectorAll('.dropSelect')) {
            if (!select.contains(e.target)) {
                select.classList.remove('open');
            }
        }
    });

    function selectOption(index) {
        var optionOnIdx = document.querySelector('.dropSelectOption:nth-child('+index+')');
      var optionSelected = document.querySelector('.dropSelectOption.dropSelectChosen');
      if (optionOnIdx !== optionSelected) {
        optionSelected.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
                optionOnIdx.classList.add('dropSelectChosen');
                optionOnIdx.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = optionOnIdx.textContent;
            }
    }
:root{ font-size: 62.5%; }

body{
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center; }

/* anything smaller */
@media only screen and (min-width: 0px){
  .top-nav .dropdwn > .spanItem { display: none; }
}

/* desktop */
@media only screen and (min-width: 1500px){
        .top-nav .dropdwn > .spanItem { display: block; }
        .top-nav .dropdwn > .buttItem { display: none; }
}

#outmostBox { width: 80rem; }
  header { margin-top: 4rem; }
  .bottomTopLinks .text, header nav a { font-size: 1.45rem; }


/* #region NAVBAR_HOVER */
#outmostBox {
    margin: 0;
    padding: 0;
    justify-items: center;
    display: grid; }

    header {
        justify-items: center;
        display: grid; }

        .dropNav * { 
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box; }

          nav, .dropNav { 
            width: 100%;
            position: relative;
            z-index: 4;}

              .dropNav .top-nav {
                  display: flex;
                  justify-content: center;
                  padding: 0;
                  font-size: 0; /* eliminates whitespace from inline-block*/ }

                  .top-nav div {
                      display: inline-block; /* blocks just line up without floats */
                      position: relative; /* sets positioning context for 2nd level menu */
                      width: inherit; }

                  .top-nav button { border: none; }

                  .top-nav button:focus { outline: 0; }

                      .top-nav .text, .top-nav .sub-nav a {
                          text-align: center; /* centeres the text horizontally */
                          display: block; /* links now fill the block*/
                          padding: 10px 20px; }

                      .top-nav .text { text-decoration: underline; }

                      .top-nav .text:hover,
                      .top-nav .sub-nav span > a:hover { background-color: rgba(228, 228, 228, 0.39); }

                      .top-nav .sub-nav {
                          /* positions the menu UNDER the list item*/
                          position: absolute;
                          width: 100%;
                          /* hides the menu until needed */
                          visibility: hidden; 
                          padding: 0; }

                  .top-nav div:hover .sub-nav{
                      /* shows the submenu when the list item is hovered */
                      visibility: visible; 
                      box-shadow: 0 5px 4px rgba(0, 0, 0, 0.2), 0 11px 10px rgba(0, 0, 0, 0.19);
                      border-bottom-right-radius:5px;
                      border-bottom-left-radius:5px; }

                          .top-nav .sub-nav div {
                              background-color: white; 
                              width: 100%; }

                          .top-nav .bottomItem {
                              border-bottom-right-radius:5px;
                              border-bottom-left-radius:5px; }
/* #endregion */

#searchAndGenre { 
  margin-top: 2rem;
  width: 100%;
  display: flex;
  justify-content: space-around;
}

/* everything below here is for the select drop-down */

.searchBar .searchTerm, .selectDropCont { font-size: 1.45rem; }
.searchCont, 
.selectDropCont, 
.selectDropCont .dropSelectWrap {
  width: 20rem;
}
.searchCont, .selectDropCont, .selectDropCont .dropSelectWrap, .selectDropCont .dropSelectWrap .dropSelect span { height: 3.5rem; }


/* #region SELECTDROP-INNARDS */

.selectDropCont *,
.selectDropCont *:after,
.selectDropCont *:before {
  box-sizing: border-box;
}

.selectDropCont, .selectDropCont .dropSelectWrap {
  display: flex;
  width:200px;
  height: 35px;
}

.selectDropCont {
  position: relative;
  justify-content: center;
  align-items: center;
  background: grey; 
}

.selectDropCont .dropSelectWrap .selectNameCont .selectName {
  width: 100%;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  user-select: none;
  border-width: 3px;
  border-color: rgba(151, 151, 151, 1);
  border-style: none solid none none;
}

.selectDropCont .dropSelectWrap .selectNameCont {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 35%;
}

.selectDropCont .dropSelectWrap {
  position: relative;
  user-select: none;
  align-items: center;
  text-align: center;
}

.selectDropCont .dropSelectWrap .dropSelect {
  position: relative;
  display: flex;
  flex-direction: column;
  border-width: 0;
  width: 65%;
}

.selectDropCont .dropSelectWrap > div {
  display: inline-block; /* blocks just line up without floats */
  position: relative; /* sets positioning context for 2nd level menu */
  height: 35px;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  height: 35px;
  cursor: pointer;
  border-width: 0;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .centCont { width: 100%; }

.selectDropCont .dropSelectWrap .dropSelectOptions {
  position: absolute;
  display: block;
  top: 100%;
  left: 0;
  right: 0;
  border: none;
  background: white;
  transition: all 0.5s;
  opacity: 0;
  visibility: hidden;
}

.selectDropCont .dropSelectWrap .dropSelect.open .dropSelectOptions {
  opacity: 1;
  visibility: visible;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption {
  position: relative;
  display: block;
  padding: 0 22px 0 22px;

  color: rgba(83, 83, 83, 1);
  line-height: 30px;
  cursor: pointer;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption:hover {
  cursor: pointer;
  background-color: rgba(228, 228, 228, 0.39);
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow {
  position: relative;
  height: 10px;
  width: 10px;
  padding: 5px 5px;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::before,
.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::after {
  content: "";
  position: absolute;
  bottom: 0px;
  width: 0.15rem;
  height: 100%;
  transition: all 0.5s;
}

.selectDropCont .arrow::before {
  left: -3px;
  transform: rotate(45deg);
  background-color: #394a6d;
}

.selectDropCont .arrow::after {
  left: 3px;
  transform: rotate(-45deg);
  background-color: #394a6d;
}

.selectDropCont .open .arrow::before {
  left: -3px;
  transform: rotate(-45deg);
}

.selectDropCont .open .arrow::after {
  left: 3px;
  transform: rotate(45deg);
}

/* #endregion */
  <div id="outmostBox">

    <header>

      <nav class="bottomTopLinks">
        <div class="dropNav">
          <div class="top-nav">

            <div class="dropdwn"><span class="text spanItem">creative</span><button class="text buttItem">creative</button>
               <div class="sub-nav">
                 <div><span><a href="?">photos</a></span></div>
                 <div class="bottomItem"><span><a class="bottomItem" href="?">music</a></span></div>
               </div>
            </div>

          </div>
        </div>
      </nav>

    </header>
    <!-- new code below this line -->

    <div id="searchAndGenre">

      <div class="selectDropCont">
        <div class="dropSelectWrap">

          <div class="selectNameCont">
            <div class="selectName"><span>type</span></div>
          </div>

          <div class="dropSelect">

            <div class="dropSelectTrig"><div class="centCont"><span>all</span></div>
              <div class="arrow"></div>
            </div>

            <div class="dropSelectOptions">
              <span class="dropSelectOption dropSelectChosen" data-value="all">all</span>
              <span class="dropSelectOption" data-value="expository">expository</span>
              <span class="dropSelectOption" data-value="persuasive">persuasive</span>
              <span class="dropSelectOption" data-value="research">research</span>
              <span class="dropSelectOption" data-value="descriptive">descriptive</span>
            </div>

          </div>

        </div>
      </div>

    </div>
    <!-- new code above this line -->

    
  </div>

老实说,我知道我实际上做了什么。最后,我想我改变了位置属性和 z-index。这和我得到的一样好,祝你好运。 我刚刚了解了 z-index,这里有一个可靠的资源供需要它的人使用:freecodecamp.org