首页 > 解决方案 > 弹出菜单中的 CSS 绝对/相对定位:如何仅使用父母的部分属性(左、上、宽、垂直/水平对齐)?

问题描述

这是我最近在 CSS 中经常偶然发现的一个问题。假设我们在页面某处有一个弹出菜单,其中包含列表项。这些列表项具有悬停时显示的子菜单。因为我希望子菜单出现在我给position:relative;父项和position:absolute;top:0;子菜单的父列表项的正下方。到目前为止,这很好用。

但是,由于position:relative;现在我已经失去了使子菜单 100% 宽度的页面宽度的能力,并且在某种意义上使用子菜单与页面left:0;的最左侧而不是父元素对齐。

我想要的是以某种方式position:relative;在父级上进行垂直对齐,但position:inherit;关于水平对齐。

请参阅以下示例 - 子菜单在垂直方面正确对齐,但在水平方面应从最左侧开始:

.clearfix::after {
    content: "";
    clear: both;
    display: table;
}

#my-menu-inner > ul {
  width:100%;
  background-color:yellow;
  list-style-type:none;
}

#my-menu-inner > ul > li {
  float:left;
  position:relative;
  padding:20px;
  border:1px solid black;
  margin:20px;
}

#my-menu-inner > ul > li > div.sub {
   position:absolute;
   top:60px;
   background-color:red;
   padding:40px;
   display:none;
   left:0;
   width:100vw;
}

#my-menu-inner > ul > li:hover > div.sub, #my-menu-inner > ul > li:focus > div.sub {
    display:block;
}
<div id="whatever">Just something before ...</div>
<div id="my-menu">
  <div id="my-menu-inner">
    <ul class="clearfix">
      <li>
        <span>foo</span>
        <div class="sub">
          <ul>
            <li>hello</li>
            <li>world</li>
          </ul>
        </div>
      </li>
      <li>
        <span>foo</span>
        <div class="sub">
          <ul>
            <li>please</li>
            <li>alignme</li>
          </ul>
        </div>
      </li>
    </ul>
  </div>
</div>

我怎样才能达到我想要的(请只接受纯CSS,涉及JS的答案将不被接受)?

标签: htmlcssalignmentcss-position

解决方案


使菜单项相对于ul而不是li

.clearfix::after {
    content: "";
    clear: both;
    display: table;
}

#my-menu-inner > ul {
  margin:10px;
  width:100%;
  background-color:yellow;
  list-style-type:none;
  position:relative;
}

#my-menu-inner > ul > li {
  float:left;
  padding:20px;
  border:1px solid black;
  margin:20px;
}

#my-menu-inner > ul > li > div.sub {
   position:absolute;
   top:calc(100%  - 20px);
   background-color:red;
   padding:40px;
   display:none;
   left:0;
   width:100vw;
}

#my-menu-inner > ul > li:hover > div.sub, #my-menu-inner > ul > li:focus > div.sub {
    display:block;
}
<div id="whatever">Just something before ...</div>
<div id="my-menu">
  <div id="my-menu-inner">
    <ul class="clearfix">
      <li>
        <span>foo</span>
        <div class="sub">
          <ul>
            <li>hello</li>
            <li>world</li>
          </ul>
        </div>
      </li>
      <li>
        <span>foo</span>
        <div class="sub">
          <ul>
            <li>please</li>
            <li>alignme</li>
          </ul>
        </div>
      </li>
    </ul>
  </div>
</div>


推荐阅读