Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If the child is position:absolute and the parent is overflow:hidden, why does the child overflow?

Tags:

html

css

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?

like image 396
Leo Jiang Avatar asked Jan 04 '16 19:01

Leo Jiang


People also ask

Why does overflow hidden not work?

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.

How do I break out of overflow hidden?

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 .

Is absolute position relative to parent?

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.

How does position relative affect children?

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 .


3 Answers

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 a position of absolute, relative or fixed

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.

like image 57
Oriol Avatar answered Oct 22 '22 09:10

Oriol


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.

like image 43
AGE Avatar answered Oct 22 '22 08:10

AGE


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

like image 32
Andrew Adam Avatar answered Oct 22 '22 10:10

Andrew Adam