【问题标题】:Absolute positioning and its parent element绝对定位及其父元素
【发布时间】:2012-08-05 10:24:51
【问题描述】:

我一直听说,当您使用绝对定位时,您想要充当其父元素的元素需要具有 positionrelative

我正在尝试构建一个 CSS 下拉菜单,当我希望它的父元素设置为 relative 时,我正在努力让下拉菜单项超出主菜单项的宽度;下拉菜单项中的文本只会换行。

所以我查看了其他示例菜单,看看他们是如何做到的,我发现其中一个甚至没有使用任何带有 positionrelative 的父元素,即使他们像我一样使用绝对定位。

这个例子在这里:http://purecssmenu.com/

所以我尝试删除我的relative 定位和宾果游戏 - 我的问题消失了。但是现在我使用绝对定位,它的父母都没有使用relative 定位,它们都设置为static

所以我想知道这有什么意义 - 如果没有 relative 父母,它不会退回到浏览器窗口吗?

如果需要,这是我的 HTML:

    <div class="navWrapper">
        <div class="left"></div>
        <div class="nav">
            <ul>
                <li class="home"><a href="/">Home</a></li>
                <li class="spacer"></li>
                <li class="about"><a href="about_us/">About Us</a></li>
                <li class="spacer"></li>
                <li class="trademark"><a href="freetrademarksearch/">Free Trademark Search</a></li>
                <li class="spacer"></li>
                <li class="services">
                    <a href="services/">Services</a>
                    <ul class="sub">
                        <li><a href="">Trademark Search</a></li>
                        <li><a href="">Prepare &amp; File Trademark</a></li>
                        <li><a href="">Trademark Infringement</a></li>
                    </ul>
                </li>
                <li class="spacer"></li>
                <li class="testimonials"><a href="testimonials/">Testimonials</a></li>
                <li class="spacer"></li>
                <li class="more"><a href="javascript:void(0);">More Information</a></li>
                <li class="spacer"></li>
                <li class="contact"><a href="contact-us/">Contact Us</a></li>                 
            </ul>
            <div class="contentClear"></div>
        </div>
        <!-- Nav Ends -->
        <div class="right"></div>
    </div>
    <!-- Nav Wrapper Ends -->

CSS:

#header .navWrapper {
    width: 1004px;
}

#header .navWrapper .left {
    float: left;
    width: 4px;
    min-width: 4px;
    height: 47px;
    min-height: 47px;
    background: url('../images/nav-left-bg.png') left top no-repeat;
}

#header .navWrapper .nav {
    float: left;
    width: 994px;
    border-top: 1px solid #e0d0b4;
    border-left: 1px solid #e0d0b4;
    border-right: 1px solid #e0d0b4;
    border-bottom: 1px solid #e8dcc8;
    background: url('../images/nav-button-bg.png') left top repeat-x;
}

#header .navWrapper .nav ul {
    margin: 0 1px;
    display: block;
}

#header .navWrapper .nav li {
    float: left;
    display: block;
    height: 45px;
    font-family: OpenSansBold, Arial;
    font-size: 16px;
    line-height: 2.9;
    text-align: center;
    color: #646464;
}

#header .navWrapper .nav li.spacer {
    width: 2px;
    min-width: 2px;
    height: 45px;
    min-height: 45px;
    background: url('../images/nav-button-spacer-bg.png') left top no-repeat;
}

#header .navWrapper .nav li a,
#header .navWrapper .nav li a:visited
{
    display: block;
    height: 45px;
    padding: 0 20px;
    color: #646464;
    text-decoration: none;
}

#header .navWrapper .nav li a:hover,
#header .navWrapper .nav li a:active,
#header .navWrapper .nav li a:focus
{
    color: #fff;
    background: url('../images/nav-button-bg.png') left bottom repeat-x;
}

#header .navWrapper .nav li.home {
    max-width: 86px;
    text-indent: -1px;
}

#header .navWrapper .nav li ul.sub {
    position: absolute;
}

#header .navWrapper .nav li ul.sub li {
    float: none;
    display: block;
    font-family: OpenSansSemibold, Arial;
    font-size: 14px;
    line-height: 2.3;
    height: auto;
    text-align: center;
    background-color: #f4771d;
    color: #fff;
}

#header .navWrapper .nav li ul.sub li a,
#header .navWrapper .nav li ul.sub li a
{
    color: #fff;
    height: auto;
}

#header .navWrapper .nav li ul.sub li a:hover,
#header .navWrapper .nav li ul.sub li a:focus,
#header .navWrapper .nav li ul.sub li a:active
{
    background: #d66627;
}

#header .navWrapper .right {
    float: right;
    width: 4px;
    min-width: 4px;
    height: 47px;
    min-height: 47px;    
    background: url('../images/nav-right-bg.png') left top no-repeat;
}

【问题讨论】:

  • 请查看我的最新更新,它显示了您如何看到purecssmenu.com position:relative 应用于&lt;ul&gt;:hover 上的父&lt;ul&gt;
  • 好的,我明白了,但我认为您的意思是父 &lt;li&gt;,而不是 &lt;ul&gt;。 :)
  • 我明白了。这对您有用,因为尽管您在列表中设置了position:absolute,但您还没有定义任何topleftbottomright 属性。这些属性默认为 0。当既没有指定 top 也没有指定 bottom 时,元素将垂直定位在它仍然是流的一部分的位置。 leftright 以及水平定位也是如此。尝试将这些属性中的任何一个设置为 0px,你就会明白我的意思了。
  • ...所以在您的情况下,需要设置position:absolute,因为它会从流程中删除子菜单,从而允许没有指定宽度的容器 li 保持由菜单顶部的文本计算的宽度。而如果您在子列表中有position:relative,它的宽度会迫使包含的 li 变宽,从而导致“联系我们”项目下降到下一行。
  • 好的,谢谢您的解释。 :)

标签: css position css-position


【解决方案1】:

它回退到最近的 ancestor 元素,该元素的位置定义为 relativeabsolutefixed——不仅是 relative,还包括除 @987654326 之外的任何值@(默认)。

通常,您希望根据其父项建立的网格绝对定位该项目。但是,有时将其定位到由更高元素建立的网格是有意义的。

例如:

HTML

<body>
    <div id="div1">
        <div id="div2-A">[some content]</div>
        <div id="div2-B">
            <div id="div3">[more content]</div>
        </div>
    </div>
</div>

CSS

#div1{
    width:1024px;margin:auto;
    position:relative
}
#div3{
    position:absolute;
    bottom:0px; left:0px;
}

在这种情况下,div3 将一直定位到 div1 的左侧和底部——它的祖父——因为它的直接父级 (div2) 具有默认的position:static,因此不会建立为绝对定位其子项的上下文/网格。但是 div3 将不会(必然)一直到视口或页面主体的左侧,因为下一个较高的元素 (div1) 的位置定义为相对。

更新
在您提供的情况下(http://purecssmenu.com/), position:relative 声明正在应用于 :hover 伪类,因此您不会立即在为 Google Developer Tools 或 Firebug 列出的样式中看到它.

您可以在 Google 开发者工具中通过检查父元素来检查它,然后在“样式”面板的右侧,单击“切换元素状态”按钮,(看起来像一个带有虚线边框和箭头指向它),然后选中 ":hover" 旁边的框。我确信 Firebug 也有类似的东西。

您会看到此声明已添加到列表中:

ul.cssMenu li:hover { position: relative; }

这是有效的,因为当您没有将鼠标悬停在父 &lt;li&gt; 上时,子菜单 &lt;ul&gt; 会被 display:none 隐藏,因此它的位置无关紧要。

【讨论】:

  • 谢谢,但即使在该页面上,您也可以看到绝对定位嵌套UL 的所有父元素都有static 定位。
  • 您错过了其父鼠标悬停ul.cssMenu li:hover { position: relative; } 上的声明
  • 好答案!但为什么不从一开始就设置位置:相对于 li 呢?为什么只是悬停?
  • @Niklas:实际上,没有理由这样做(或者可能只是为了让我们感到困惑!)。我只是在报告purecssmenu.com 的人是如何做到的。
  • @Faust haha​​,然后他们成功了 ;-)
【解决方案2】:

关于定位元素时最近的祖先的另一个说明。

在 OP 三年后,像 transform 这样的 CSS3 属性被更广泛地使用,它隐式创建了一个新的包含块,强制元素具有 position: relative/absolute;

所以要确保 intermediary 父元素对子元素的定位没有影响,您需要检查它是否设置了position: static 并且没有设置transforms

示例

    <div id="one">
      <div id="two">
        <div id="three"></div>
      </div>
    </div>
    #one {
      position: relative;
    }
    #two {
      position: static;
      transform: none;
    }
    #three {
      position:absolute;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 2018-07-09
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 2014-04-16
    相关资源
    最近更新 更多