If the child is position:absolute
, the parent is overflow:hidden
, and the parent is position:static
, the child still overflows:
<div style="overflow:hidden;height:100px;border:2px solid red;">
<div style="position:absolute;height:200px;width:200px;background:blue;opacity:0.5">
</div>
</div>
If the parent has a position other than static
, the child no longer overflows:
<div style="overflow:hidden;height:100px;border:2px solid red;position:relative;">
<div style="position:absolute;height:200px;width:200px;background:blue;opacity:0.5">
</div>
</div>
Why does this occur? What is this behavior called?
I'm using Chrome, is this behavior consistent across browsers?
It is because you are using position absolute. You cannot use position absolute with overflow hidden, because position absolute moves the targeted element out of context with the document structure.
We have a dropdown-menu that gets filled with suggestions when the user type (type 'c' in the search field to see). This dropdown-menu is currently hidden behind the menubar, because it has "overflow hidden". We can break out, if we remove the top:100% and set position to fixed .
Absolute In position: relative , the element is positioned relative to itself. However, an absolutely positioned element is relative to its parent. An element with position: absolute is removed from the normal document flow.
An element with position: relative won't look any different, but its children might. If grandchild has position: absolute , it will position itself relative to the browser window because there is no parent with a position other than the default of static .
That's because the spec defines overflow
as
This property specifies whether content of a block container element is clipped when it overflows the element's box. It affects the clipping of all of the element's content except any descendant elements (and their respective content and descendants) whose containing block is the viewport or an ancestor of the element.
The absolutely positioned element is a descendant whose containing block is established by an ancestor of the element with overflow: hidden
, as explained in Definition of "containing block"
If the element has
position: absolute
, the containing block is established by the nearest ancestor with aposition
ofabsolute
,relative
orfixed
Therefore the absolutely positioned element is not affected by that overflow: hidden
.
If the parent were positioned, it would be the containing block of the absolutely positioned element, and then overflow: hidden
would affect it.
First of all, take a close look at the MDN Documentation CSS Position.
So how does this relate to your question? let's first analyze position: absolute
:
absolute: Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor or to the containing block. Absolutely positioned boxes can have margins, they do not collapse with any other margins.
As far as your case goes, the positioned ancestor div
element does not have any specified position
attribute to it.
Therefore, it assumes the default position: static
which literally specifies nothing other than the standard position of the element in the page. Check it out:
static: This keyword lets the element use the normal behavior, that is it is laid out in its current position in the flow. The top, right, bottom, left and z-index properties do not apply.
In other words, the child will not be positioned relative to its parent. The weird behavior is because you expect the parent div
to be positioned when is not positioned at all. It falls to ask: what is the nearest positioned parent then? The answer is to go up on the DOM tree and find it, logically since you have nothing in your example but your two div
, the nearest parent will be webpage document itself.
So, how can you fix this? By adding (for example) position: relative
to the parent div
element.
EDIT: Overflow and Position properties:
By using overflow
, you are typically trying to do one (or all) of the following: clip content, render a scroll bar, display any overflown content in a particular way. I gather your goal however is to have the child div
not overflow the parent div
. The question of how to avoid this overflow can take you to a place you do not want to go.
So by narrowing down what overflow is all about: (long story short) it is about controlling/modifying the look and feel of the content of what is inside a particular HTML element. Keep in mind, the content, not the element itself.
In your case, you may perceive the child element of your parent div
as being the content of the parent div
. Rather, what you actually see is the contents of the child element. The positioning of the parent and child with respect to each other is thus not controlled by the overflow
property, but by the position
property.
Is this consistent across browsers?:
Since CSS 2.1, the overflow (visible | hidden | scroll | auto)
and position (static | relative | absolute)
have been supported in all major browsers. Any discrepancies would occur when you extend on the overflow
since certain of its attributes are not widely supported. See here for reference: Can I Use: Overflow (also scroll to the bottom for the CSS 2.1 reference).
Do you have any questions about this? Ask in the comments below.
overflow property is not inherited anyhow: http://www.w3schools.com/cssref/pr_pos_overflow.asp
So in your first case it is understandable it is not working, since with static position the browsers put it in the order it reads and overlooks collisions.
In your second case absolute positioning actually sets a space for the container div and then puts the second div into it - thus makes the overflow hidden.
You can imagine it this way: in your first case you created two divs which are not related to each other but positioned on each other in the second case you created a container and forced another div into it by setting the container's overflow to hidden.
Hope it helped easy understanding,
Andrew
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With