When using top, right, bottom, left
css
values, why am I able to use percentages sometimes, but other times I have to use pixels (px
), or the element
won't respond.
For example (on a given element):
top: 25%
- doesn't respond
top: 150px
- works
I usually will use percentages over pixels (px
) to keep things responsive, but why do percentages (%
) sometimes not work? In what scenarios do each work best? Thanks.
According to the WC3 specification for percentage units (<percentage>
(ref)):
Percentage values are always relative to another value, for example a length unit.
A length unit (<length>
(ref)) is a CSS data type that represents a distance value, or a value defined in relative (em
) or absolute (px
) length units.
A percentage unit (<percentage>
(ref)) is a CSS data type that represents a percentage value.
Percentage units (e.g: top: 50%
) used on nested elements won't apply if the containing element has no length unit (e.g: height: 200px
) value defined, since percentage values are always relative to another value.
This behaviour can be observed in the code snippet embedded below.
Code Snippet Demonstration:
.fixed-height {
height: 200px;
background: #4cbd2f;
}
.auto-height {
background: #d04f38;
}
.nested {
top: 50%;
position: relative;
}
hr {
border: 2px dashed #d4d4d4;
margin: 25px 0px;
}
.fixed-height, .auto-height {
padding: 10px;
box-sizing: border-box;
border: 2px dashed rgba(0, 0, 0, 0.3);
}
<h3>Fixed Height</h3>
<h4><code>height: 200px</code></h4>
<div class="fixed-height">
<div class="nested"><code>top: 50%</code></div>
</div>
<hr>
<h3>Auto Height</h3>
<h4><code>height: auto</code></h4>
<div class="auto-height">
<div class="nested"><code>top: 50%</code></div>
</div>
Demonstrated in the code snippet above, percentage values will be dependent on length values. So although both nested elements have a top
property of 50%
declared, only the element nested in the containing element with a height
property explicitly defined with length values will result in the expected behaviour.
Note: Although
<percentage>
values are also CSS dimensions, and are usable in some of the same properties that accept<length>
values, they are not themselves<length>
values. ref
Note: Only calculated values can be inherited. Thus, even if a percentage value is used on the parent property, a real value (such as a width in pixels for a
<length>
value) will be accessible on the inherited property, not the percentage value. ref