Reputation: 1433
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 class="chat-break">
<div class="line">
</div>
<p class="date">Today</p>
</div>
My understanding:
.chat-break
flexbox has two elements .line
and .date
.position: absolute
on .date
its no longer its own element inside the flexbox?Upvotes: 4
Views: 3879
Reputation: 155658
Preface:
top
, right
, bottom
, and left
properties are collectively referred to as "box inset" properties.initial
" values or inherited values.
position: static;
.initial
value for all of the box-inset properties is auto
, regardless of their element's position
and display
property.
auto
value does depend on the element's position
and/or formatting context.flex
, grid
, etc) weren't added (let alone supported by browsers) until well into the 2010s.
<div class="line">
fills the width of the page:<div class="chat-break">
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 class="line">
is a flex-item.
Therefore<p class="date">
is not a flex-item because it has position: absolute;
.
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).
position: relative;
is being applied to <div class="chat-break">
.<div class="chat-break">
is a flex-parent with only one flex-item, despite having two element children.
justify-content: center;
it means that its single flex-item (<div class="line">
) will be centered.<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.
<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">
.<body>
, <div class="chat-break">
, and <div class="line">
(in that order) will fill the width of the viewport.<p class="date">
is centered:<p class="date">
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 class="date">
was position: static;
.
<p class="date">
was position: static;
then it would be a flex-item and would share its flex row with <div class="line">
- 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 anabsolute
ly-positioned child of aflex
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"?
Upvotes: 6