Home > front end >  CSS Flexbox with position absolute confusion
CSS Flexbox with position absolute confusion

Time:03-05

I'm confused how this works could someone walk me through what exactly happened?

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;
  
}
<div >
    <div >
    </div>
    
    <p >Today</p>
</div>
  

My understanding:

  • .chat-break flexbox has two elements .line and .date.
  • ...but after using position: absolute on .date its no longer its own element inside the flexbox?
  • Then why is "Today" being centered on the line?

CodePudding user response:

Preface:

  • The top, right, bottom, and left properties are collectively referred to as "box inset" properties.
  • Keep in mind that all CSS properties that aren't explicitly set will have default values that are either "initial" values or inherited values.
    • So unless explicitly specified otherwise, every element has position: static;.
    • The initial value for all of the box-inset properties is auto, regardless of their element's position and display property.
      • But the behaviour of the auto value does depend on the element's position and/or formatting context.
  • CSS has a lot of surprising and counter-intuitive behaviour.

Why <div > fills the width of the page:

  • <div > has display: flex;, which makes it a flex-parent.
    • All immediate child elements (with certain exceptions) of a flex-parent, that have position: static, are flex-items.

    • Therefore<div > is a flex-item.

    • Therefore<p > 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 >.
  • Therefore <div > 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 >) will be centered.
  • Also, because <div > has display: flex; (rather than display: inline-flex) it means that <div > 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 > also has width: 100%; (which becomes flex-basis: 100%;) it means the <div > will fill the width of <div >.
    • Therefore <body>, <div >, and <div > (in that order) will fill the width of the viewport.

Why <p > is centered:

  • As <p > uses auto for all its box inset properties (i.e. top, right, etc) with position: absolute; then the computed value of those properties is the same as if <p > was position: static;.
    • However, if <p > was position: static; then it would be a flex-item and would share its flex row with <div > - which would mean it would be located somewhere off to the right of the line (due to justify-content: center;).
      • But it's actually centered, because this is a special-case scenario that's specifically specified in the specification...

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

        4.1. Absolutely-Positioned Flex Children

        As it is out-of-flow, an absolutely-positioned child of a flex container does not participate in flex layout.

        The static position of an absolutely-positioned child of a flex container is determined such that the child is positioned as if it were the sole flex item in the flex container, assuming both the child and the flex container were fixed-size boxes of their used size. For this purpose, auto margins are treated as zero.

It's well-worth reading the rest of the section as it also covers other brain-stretching scenarios, like "what if align-self: center; is used"?

  •  Tags:  
  • css
  • Related