【问题标题】:Is it possible to position an element relative to the border-box of its parent?是否可以相对于其父元素的边框定位元素?
【发布时间】:2014-08-18 15:45:28
【问题描述】:

请考虑以下 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;
}

如您所见,“内部”框(带有红色边框)相对于外部的 padding-box 定位:left:0 将其定位在外部边框的右侧,并且top:100% 似乎意味着“100% 的内容加上填充,但不包括边框”。

不幸的是,将box-sizing: border-box 添加到外部 div 似乎没有任何效果。

我想将一个子元素直接放置在其父元素的 border-box 下方,即无论它们有多粗,两个边框都应该紧靠在一起。这可能吗?

【问题讨论】:

  • 你可以抵消inner jsfiddle.net/apmmw2ma/1
  • @DavidAlsbright:谢谢,但是 1)边界仍然重叠;我希望内部的边界框完全低于外部的边界框; 2)这要求我知道外边框的厚度。
  • 你能制作 div 的兄弟姐妹并只使用completely standard flow吗?
  • 只是好奇,这是什么用例。为什么不在第一个 div 之后使用非子 div?
  • 好的,感谢您的所有反馈。很遗憾这是不可能的。这对我来说似乎是一个疏忽; top: x% 的含义实际上应该取决于父级的 box-sizing 值...

标签: html css css-position


【解决方案1】:

不幸的是,如果事先不知道边框宽度,这是不可能的。如果您事先不知道边框宽度,或者如果它们是动态的,那么您就不走运了。1

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

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

这对我来说似乎是一个疏忽; top: x% 的含义实际上应该取决于父级的box-sizing 值...

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


1这可以通过自定义属性来解决,但前提是您必须将相同的自定义属性分配给父级的边框宽度和子级各自的偏移量,这基本上是另一种说法“您必须提前知道边框宽度”,或者至少可以控制它们。

2例如,浮点数高度倾向于框的边缘,以至于they can appear to collapse margins 在你通常不会的地方'没想到会发生。

【讨论】:

    【解决方案2】:

    尝试使用display:table; 作为外部 div。

    小提琴:http://jsfiddle.net/apmmw2ma/9/

    【讨论】:

      【解决方案3】:

      不幸的是,如果不重复父边框宽度的值,就无法做到这一点。

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

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

      【讨论】:

      • 我不确定现在如何不广泛支持 calc()。 IE9+ 和所有其他主流浏览器都支持它并且已经支持了一段时间了。 Caniuse 甚至列出了超过 75% 的支持(即使是无前缀的使用)。如果您只是指移动支持(目前所有主要浏览器都支持),那么澄清一下可能是合适的。
      【解决方案4】:

      使用box-shadow

      这会以您期望的方式使用 box-sizing 模型:

      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;
      

      【讨论】:

      • 好主意,但不幸的是,这个“边框”现在“吞噬”了填充:)
      • 这是唯一的警告。它需要小于或等于填充,以免与块的内容发生冲突
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2012-06-13
      • 2012-12-16
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多