如何对齐CSS下拉菜单的包装器

时间:2019-01-22 14:17:43

标签: html css css3

我正在创建一个下拉菜单,并使其看上去几乎是我想要的样子,但是我实现布局的方式使鼠标悬停区域在右侧有点太大,如灰色框所示。我想将鼠标悬停在灰色框(.dropdown元素)上,将其视为白色区域并关闭该下拉菜单。

当悬停在灰色的.dropdown区域上方时,如何取消菜单?

此处的工作演示:https://codepen.io/anon/pen/BMarBb?editors=1100

enter image description here

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;
}
<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>

3 个答案:

答案 0 :(得分:2)

我对您的问题的解释是,当您停止将鼠标悬停在橙色部分上时,希望隐藏该下拉菜单。

我下面对您的代码所做的是position:absoluteleft:50%transform:translate(-50%)的元素。这将使元素水平居中对齐,以使橙色链接位于灰色区域上方。

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;
}
<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>

答案 1 :(得分:2)

有关如何控制特定元素的悬停事件,请参见CSS上的内联注释。这种方法会在下拉菜单活动上方直接保留灰色区域,我认为这是一个很好的行为。

注意:这可能不适用于Safari。参见https://caniuse.com/#feat=pointer

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;
}
<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>

答案 2 :(得分:1)

解决问题的另一种方法是删除margin-left.dropdown上的.wrapper,然后将箭头居中:

margin-right: auto;
margin-left: auto;
left: 0;
right: 0;

由于此元素上还有一个margin-top,因此您可以编写margin: 29px auto 0;而不是margin-leftmargin-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;
  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;
}
<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>

编辑:正如Chiller和Temani Afif在评论部分中所述,您的代码结构无效。我快速整理了您的示例,以便您可以看到使用较少包装元素可以做什么。

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">
        <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>