CSS Flexbox 具有位置绝对混淆

Bas*_*Bas 4 css

我很困惑这是如何工作的,有人能告诉我到底发生了什么吗?

body,
html {
  padding: 0;
  margin: 0;
  height: 100vh;
  width: 100%;
}

.chat-break {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 20px;

}

.chat-break .line {
  border-bottom: 1px solid #ddd;
  width: 100%;
}

.chat-break .date {
  color: #B5B5B5;
  position: absolute;
  background-color: #fff;
  padding-left: 8px;
  padding-right: 8px;
  
}
Run Code Online (Sandbox Code Playgroud)
<div class="chat-break">
    <div class="line">
    </div>
    
    <p class="date">Today</p>
</div>
  
Run Code Online (Sandbox Code Playgroud)

我的理解:

  • .chat-breakflexbox 有两个元素.line.date
  • ...但是在弹性盒内使用position: absolute.date不再是它自己的元素之后?
  • 那为什么“今天”会在线居中呢?

Dai*_*Dai 6

前言:

  • top、和属性统称为“框插入”属性rightbottomleft
  • 请记住,所有未显式设置的 CSS 属性都将具有默认值,即“ initial”值或继承值。
    • 因此,除非另有明确指定,否则每个元素都有position: static;.
    • initial所有 box-inset 属性的值为,auto无论元素positiondisplay属性如何。
      • 但值的行为auto确实取决于元素position和/或格式化上下文
  • CSS 有很多令人惊讶和违反直觉的行为。

为什么<div class="line">要填充页面的宽度:

  • <div class="chat-break">has display: flex;,这使其成为flex-parent
    • All immediate child elements (with certain exceptions) of a flex-parent, that have position: static, are flex-items.

    • Therefore<div class="line"> is a flex-item.

    • Therefore<p class="date"> is not a flex-item because it has position: absolute;.

      • (Generally speaking) elements with position: absolute; are not subject to their layout-container's layout rules and are re-positioned with absolute-coordinates where the origin is in their-closet-ancestor-element-without-position: static; (yes, that's a mouthful).
        • This is why position: relative; is being applied to <div class="chat-break">.
  • Therefore <div class="chat-break"> is a flex-parent with only one flex-item, despite having two element children.
    • And because it has justify-content: center; it means that its single flex-item (<div class="line">) will be centered.
  • Also, because <div class="chat-break"> has display: flex; (rather than display: inline-flex) it means that <div class="chat-break"> is a block-level element, so it fills the width of its container, which is <body>, which fills the width of the viewport.
    • And because <div class="line"> also has width: 100%; (which becomes flex-basis: 100%;) it means the <div class="line"> will fill the width of <div class="chat-break">.
    • Therefore <body>, <div class="chat-break">, and <div class="line"> (in that order) will fill the width of the viewport.

为什么<p class="date">居中:

  • As<p class="date">用于auto其所有框插入属性(即topright等),position: absolute;然后这些属性的计算值 <p class="date">was相同position: static;
    • 然而,如果 <p class="date">是的position: static;话,那么它将是一个弹性项目,并且将与 共享其弹性行<div class="line">- 这意味着它将位于该行右侧的某个位置(由于justify-content: center;)。
      • 但它实际上是居中的,因为这是规范中专门指定的特殊情况......

        https://www.w3.org/TR/css-flexbox-1/#abspos-items

        4.1. 绝对定位的 Flex 子项

        由于它是外流的,因此 Flex 容器的绝对定位子级不参与 Flex 布局。

        容器staticabsolute已定位子项的位置被确定为使得子项被定位为就好像它是 Flex 容器中唯一的 Flex 项目一样,假设子项和 Flex 容器都是其使用大小的固定大小的盒子。为此,自动边距被视为零。flex

本节的其余部分非常值得阅读,因为它还涵盖了其他令人费脑筋的场景,例如“如果align-self: center;使用的话会怎样”?