能否将一个元素相对于其父元素的边框盒进行定位?

11

以下是参考jsfiddle:

http://jsfiddle.net/apmmw2ma/

<div class='outer'>
    <div class='inner'>
        Inner.
    </div>
    Outer.
</div>
div.outer {
    position: absolute;
    left: 10px;
    top: 10px;
    border: 5px solid green;
    padding: 10px;
}
div.inner {
    position: absolute;
    left: 0;
    top: 100%;
    border: 10px solid red;
    padding: 15px;
}

正如您所看到的,“内部”框(红色边框)相对于外部的 填充框 定位:left:0 将其定位在外部边框的右侧,top:100% 看起来意味着“内容加上填充区域的高度为100%,但不包括边框”。

不幸的是,在外部 div 中添加 box-sizing:border-box 似乎没有效果。

我想将子元素直接定位在其父元素的 边框框 下方,即使它们有多厚,两个边框也应紧贴在一起。这可行吗?


1
你能将这些 div 元素变成兄弟元素,只使用完全标准的流布局吗? - Roman Starkov
2
只是好奇,这个的用例是什么?为什么不在第一个div之后使用一个非子div? - Paulie_D
2
好的,感谢您所有的反馈。很遗憾这是不可能的。对我来说,这似乎是一个疏忽;top: x% 的含义应该取决于父元素的 box-sizing 值... - Timwi
@Timwi 我不同意;如果这是一个修复,告诉人们。如果他们不按需更新代码,责任在他们身上。毕竟这是一个活标准。 - TylerH
请查看下面我的解决方案。 - gopalraju
显示剩余8条评论
4个回答

5

不幸的是,如果不提前知道边框宽度,这是不可能的。如果您事先不知道边框宽度或者它们是动态的,那么您就没有办法了。1

元素所在包含块的区域确实被定义为形成包含块的元素的填充边缘。这在规范中明确说明,并且是经过设计的;除非容器具有overflow: visible并且不建立BFC(即使是这样,效果仅仅是视觉上的;它不影响布局),否则后代通常不应该溢出其容器的边框。否则,边框就不再是边框了。

一般来说,如果要布置元素以便它们通过其边框或外边缘进行交互,则不希望将它们布置为祖先和后代关系。至少您希望它们是兄弟关系2,否则它们应该完全无关。

对我来说,这似乎是一个疏忽;top: x%的含义应该真正取决于父元素的box-sizing值...

box-sizing 的目的是改变盒子大小的计算方式(即填充或边框是否应该增加到由 widthheight 指定的尺寸中);虽然您可以使用它来改变元素的填充框的大小,但如果元素生成一个包含块,则包含块的区域仍然由该填充框定义。

1 这个问题可以通过自定义属性解决,但前提是您必须将相同的自定义属性分配给父元素的边框宽度和子元素的各个偏移量,这基本上是另一种说法:“您必须预先知道边框宽度”或者至少要对其进行控制。

2 例如,浮动元素非常容易受到盒子的边框影响,以至于在通常不会发生的地方它们可能看起来会折叠边距


0

使用box-shadow

这样可以按照您的期望使用盒模型:

http://jsfiddle.net/apmmw2ma/6/

-webkit-box-shadow:inset 0px 0px 0px 5px green;
-moz-box-shadow:inset 0px 0px 0px 5px green;
box-shadow:inset 0px 0px 0px 5px green;

box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;

1
好主意,但不幸的是这个“边框”现在“侵入”了填充区 :) - Timwi
这是唯一的警告。它需要小于或等于填充量,以避免与块内容发生冲突。 - Alain Jacomet Forte

0

0

很遗憾,如果不重复父元素的边框宽度值,这是不可能实现的。

但是,如果可以接受重复边框宽度值,以下解决方案可行:

div.inner {
    top: <desired top value, e.g. 100%>;
    margin-top: <parent’s border-bottom-width>;
    left: <desired left value, e.g. 0>;
    margin-left: -<parent’s border-left-width>;
}

在未来,使用calc()也将成为可能,但目前它的支持还不够广泛。
div.inner {
    top: calc(<desired top value, e.g. 100%> + <parent’s border-bottom-width>);
    left: calc(<desired left value, e.g. 0> - <parent’s border-left-width>);
}

如果我可以为未来梦想,我希望能够在calc()表达式中引用父元素/祖先的属性值。这样我就可以写出类似以下的代码:
/* Hypothetical code that will never work */
div.inner {
    top: calc(100% + parent.border-bottom-width);
    left: calc(0 - parent.border-left-width);
}

1
我不确定为什么现在calc()函数没有得到广泛支持。IE9+和其他主要浏览器都支持它,并且已经支持了一段时间。Caniuse网站甚至将其支持率列为超过75%(即使是未加前缀的用法)。如果您只是指移动设备上的支持(目前所有主要浏览器都支持它),那可能需要澄清一下。 - TylerH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接