2

I've been doing CSS for a while now but couldn't figure out what's going here. Feeling really dumb :) Could you explain the behaviour?

.parent {
  display:inline-block;
}

.child {
    border: 2px solid red;
    padding: 20px; /* this works as expected */
    padding: 20%;
    box-sizing: border-box; /* makes no difference */
}
<div class="parent">
  <div class="child">CSSisAwesome</div>
</div>
Miro
  • 8,402
  • 3
  • 34
  • 72

3 Answers3

2

You are facing a cyclic calculation due to the use of percentage value. The parent is an inline-block element so its width is defined by its content and that same content is using a percentage value so the content need a reference for that percentage which is the width of the parent. You have a cycle.

In such case, the browser will first ignore the padding to define the parent width and then calculate the padding BUT we don't get to calculate the parent width again because will have an infinite loop.

Check this:

.parent {
  display: inline-block;
}

.child {
  border: 2px solid red;
  
}
<div class="parent">
  <div class="child">CSSisAwesome</div>
</div>
<br>
<br>
<div class="parent">
  <div class="child" style="padding: 20%;">CSSisAwesome</div>
</div>

Note how in both cases, the width of the parent is the same and that width is defined by the content. The padding is added later and create an overflow.

You can find mode detail in the Specification

Sometimes the size of a percentage-sized box’s containing block depends on the intrinsic size contribution of the box itself, creating a cyclic dependency.

Related questions:

Why does percentage padding break my flex item?

CSS Grid - unnecessary word break

How percentage truly works compared to other units in different situations

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Great explanation as usual Temani! Thanks a lot! I wish CSS was a little smarter and did at least 2 loops after the initial ignoring. That way 20% would work as 20px (on 100px width) but I guess it would cause other issues when changing the width. – Miro Oct 25 '22 at 20:54
-1

As seen in this CSSTricks article, padding using percentage units is in relation to the parent container, not the content within the element. The 20% padding you're setting in your code snippet is in relation to the .parent div's dimensions, not in relation to the content within the .child div.

micahlt
  • 377
  • 2
  • 11
  • I get that. The parent is ~100px wide. That's 20px. But applying 20px works on all sides as expected. Applying 20% doesn't work like 20px. – Miro Oct 25 '22 at 06:24
  • The reason the 20px works is because it's an absolute unit while percentage is relative. Since the `.parent` doesn't have set dimensions, it expands to fit the newly resized (due to % padding) `.child` which then must recalculate its padding, resulting in this unexpected behavior. – micahlt Oct 25 '22 at 06:34
-1

If you are using % as a unit, Parent should have fixed width and height