Reputation: 2405
I recreated a stripped down version of the phenomenon I'm facing. So the parent has position: relative
and the ::after
child has position: absolute
with all directional values set to zero. This would normally stretch out the child directly over the parent perfectly in my experience. Also * { margin: 0; padding: 0 }
is set to be safe and make sure this isn't a margin
or padding
issue.
I know I can just set the child element -1px
left and up... but I'm kind of curious to why this is happening if the child is stretched out directly over it's parent? Is there a way to make it work with top
, right
, bottom
, and left
set to 0?
* {
margin: 0;
padding: 0;
}
body {
padding: 5rem; /* to push div closer to center of snippet window */
}
div {
transform: scale( 5 ); /* added so displacement can be easily seen */
}
div, div::after {
display: block;
position: relative;
width: 1rem;
height: 1rem;
background-color: #eee;
border-style: solid;
border-width: 0.1rem;
border-color: #666;
border-radius: 0.25rem;
content: '';
}
div::after {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
<div></div>
Notice from the snippet ( In Chrome atleast ) The div's
are offset from each other by about 1 px.
Picture of what I'm seeing in Chrome on desktop:
Why aren't these div's placed directly on top of each other?
Upvotes: 2
Views: 1024
Reputation: 273750
The reference is the padding-box
and not the border-box
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
... the containing block is formed by the padding edge of the ancestor. ref
Then the values are over-constrained since you are defining left
/right
/width
and the width is equal to the parent (containing block) width so the right
will be ignored (use any value for it and nothing will happen)
If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. ref
Same logic with top
/bottom
/height
where the bottom
is ignored.
If you replace your border with a box-shadow
for example you will have a perfect overlap:
* {
margin: 0;
padding: 0;
}
body {
padding: 5rem; /* to push div closer to center of snippet window */
}
div {
transform: scale( 5 ); /* added so displacement can be easily seen */
}
div, div::after {
display: block;
position: relative;
width: 1rem;
height: 1rem;
background-color: #eee;
box-shadow:0 0 0 0.1rem #666;
border-radius: 0.25rem;
content: '';
}
div::after {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
<div></div>
Upvotes: 2