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
, andleft
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 isauto
, regardless of their element'sposition
anddisplay
property.- But the behaviour of the
auto
value does depend on the element'sposition
and/or formatting context.
- But the behaviour of the
- So unless explicitly specified otherwise, every element has
- CSS has a lot of surprising and counter-intuitive behaviour.
- This is not intentional, but a consequence of how CSS evolved over time over the past ~25 years it's existed.
- Originally CSS wasn't capable of any layout control at all, it was only useful for things like font and text styling.
- In fact, CSS's main layout features (like
flex
,grid
, etc) weren't added (let alone supported by browsers) until well into the 2010s.
- This is not intentional, but a consequence of how CSS evolved over time over the past ~25 years it's existed.
Why <div >
fills the width of the page:
<div >
hasdisplay: 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 hasposition: 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 >
.
- This is why
- (Generally speaking) elements with
- 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.
- And because it has
- Also, because
<div >
hasdisplay: flex;
(rather thandisplay: 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 haswidth: 100%;
(which becomesflex-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.
- And because
Why <p >
is centered:
- As
<p >
usesauto
for all its box inset properties (i.e.top
,right
, etc) withposition: absolute;
then the computed value of those properties is the same as if<p >
wasposition: static;
.- However, if
<p >
wasposition: 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 tojustify-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.
- However, if
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"?