Reputation: 27
In the following codepen - https://codepen.io/tanmaylodha/pen/MWKXJWW
CSS:Line-26; the left:50%
is not working correctly.
But if I set display:inline-block
on the containing block .section-first a
of absolutely positioned element .badge
then it works fine.
<section class="section section-first">
<a href="#">
<h1 class="badge">Recommended</h1>
<h1 class="plus-plan">Our PLUS Plan</h1>
<h2>The most popular choice of our customers.</h2>
<p>
Benefit from increased storage and faster support to ensure that
your mission-critical data and applications are always available!
</p>
</a>
</section>
.section {
color: #6c6164;
background-color: #f7fafd;
padding: 1.563rem;
margin-bottom: 1.563rem;
border: 5px solid #fca156;
margin-right: 12.5rem;
box-shadow: inset 5px 5px 10px 2px #4fbf99;
}
.section-first {
margin-top: 8rem;
}
.section-first a {
position: relative;
}
.badge {
font-family: "Red Hat Display";
background-color: #60a7bd;
padding: 0.625rem;
border-radius: 5px;
margin: 0%;
position: absolute;
left: 50%;
}
.section h1.badge {
color: white;
}
.section-first .plus-plan {
margin-top: 50px;
}
.section-highlighted {
margin-left: 200px;
margin-right: 0px;
box-shadow: inset 5px 5px 10px 2px #4fbf99, 5px 5px 10px 2px #60a7bd;
text-align: right;
}
.section:hover {
border-color: #ff943c;
}
.section a {
text-decoration: none;
}
Now check this codepen - https://codepen.io/tanmaylodha/pen/jOWKyZP
But here the results are different. .child
being absolutely positioned element is getting correctly positioned after 50% width of its containing block .parent
<a href="" class="parent">
I am a Parent
<div class="child">
I am a child
</div>
</a>
.parent {
position: relative;
background-color: chocolate;
}
.child {
position: absolute;
background-color: darkgreen;
left: 50%;
}
In both the above Codepen, the containing block(being positioned relative) is always an inline element, then why the results are different?
Upvotes: 1
Views: 2357
Reputation: 272772
To make the issue more clear here is the minimal code that illustrate the difference:
.parent {
position: relative;
background-color: chocolate;
}
.child {
position: absolute;
background-color: darkgreen;
left: 50%;
}
<a href="" class="parent">
I am a Parent
<div class="child">
I am a child
</div>
</a>
<br><br><br><br><br>
<a href="" class="parent">
<div>I am a Parent</div>
<div class="child">
I am a child
</div>
</a>
Note how in the first case you have text content inside your inline element so your element is having a width used as reference for the left property. In the second case, you have a block element inside an inline element and this one is now having a width equal to 0
(no background coloration) and this is what you are facing in your first code. left:X%
of 0
is 0
so nothing will happen.
What you are doing is of course valid but having block element inside inline element will make the rendring a bit tricky. From the specification you can read:
When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.
Yes not easy to understand but let's take our example and add more CSS to better see:
.parent {
position: relative;
background-color: chocolate;
border:2px solid red;
}
some text before<br>
<a href="" class="parent">
<div>I am a Parent</div>
</a>
<br> some text after
You can see how the block element broke our inline element in two chunks that are empty.
To avoid dealing with this, avoid having block element inside inline elements. Use inline-block
to fix this issue:
.parent {
position: relative;
background-color: chocolate;
border:2px solid red;
display:inline-block;
}
some text before<br>
<a href="" class="parent">
<div>I am a Parent</div>
</a>
<br>
some text after
Upvotes: 2
Reputation: 4659
Please use this...
.section-first {
position: relative;
}
Instead of the below style.
.section-first a {
position: relative;
}
The <div>
tag is a block level element.
The <a>
tag is tag is an inline element.
Upvotes: 0