Make floating child visible outside an overflow:hidden parent

In CSS the overflow:hidden is set on parent containers in order to allow it to expand with the height of their floating children.

But it also has another interesting feature when combined with margin: auto...

If PREVIOUS sibling is a floating element, it will actually appear juxtapose to it. That is if the sibling is float:left then the container with float:none overflow:hidden will appear to the right of the sibling, no newline - just as if it was floating in the normal flow. If the previous sibling is float:right then the container will appear to the left of the sibling. Resizing this container will accurately show it centered inbetween the floating elements. Say if you have two previous siblings, one float:left the other float:right, the container will appear centered inbetween the two.

So here's the problem...

How do I maintain that type of layout WITHOUT masking children?

Googling all over the web gives me ways on how to clear:both and expand a container... but I can't find any alternative solution to maintaining the left/right previous-child centering. If you make the container overflow:visible then the container suddenly ignores the layout flow of the floating elements and appears layered ontop of the floating element.

So question:

I have to have the container overflow:hidden to preserve layout...

how can I make it so the children aren't masked? I need to have the child absolutely positioned relative to the parent outside the container.

OR

How do I overflow:visible so I can absolutely position a child relative to the parent outside the container... YET preserve the sibling float-like-layout-flow?

147721 次浏览

This is an old question but encountered it myself.

I have semi-solutions that work situational for the former question("Children visible in overflow:hidden parent")

If the parent div does not need to be position:relative, simply set the children styles to visibility:visible.

If the parent div does need to be position:relative, the only way possible I found to show the children was position:fixed. This worked for me in my situation luckily enough but I would imagine it wouldn't work in others.

Here is a crappy example just post into a html file to view.

<div style="background: #ff00ff; overflow: hidden; width: 500px; height: 500px; position: relative;">
<div style="background: #ff0000;position: fixed; top: 10px; left: 10px;">asd
<div style="background: #00ffff; width: 200px; overflow: visible; position: absolute; visibility: visible; clear:both; height: 1000px; top: 100px; left: 10px;"> a</div>
</div>
</div>

You can use the clearfix to do "layout preserving" the same way overflow: hidden does.

.clearfix:before,
.clearfix:after {
content: ".";
display: block;
height: 0;
overflow: hidden;
}
.clearfix:after { clear: both; }
.clearfix { zoom: 1; } /* IE < 8 */

add class="clearfix" class to the parent, and remove overflow: hidden;

Neither of the posted answers worked for me. Setting position: absolute for the child element did work however.

For others, if clearfix does not solve this for you, add margins to the non-floated sibling that is/are the same as the width(s) of the floated sibling(s).

For others if this does not work try giving height in vh in the component where you need the scrollbar.

.parent {
overflow: hidden;
}


.child {
overflow: overlay;
height: 100vh;
}

just add a position: static to parent. (bootstrap dropdown example)

HTML

<div class="menu px-3">
<li class="dropdown tab"> <!-- this is one you should add position: static to -->
<a role="button" data-bs-toggle="dropdown" class="nav-link dropdown-toggle">
Click to show dropdown<span class="caret"></span>
</a>
<ul class="dropdown-menu show" style="position: absolute; inset: 0px auto auto 0px; margin: 0px; transform: translate3d(122px, 130px, 0px);" data-popper-placement="bottom-end">
<li>
<a href="#" class="dropdown-item text-16 gray-1 tab">
Link one
</a>
</li>
<li>
<a href="#" class="dropdown-item text-16 gray-1 tab ">
Link two
</a>
</li>
</ul>
</li>
</div>

CSS

div.menu {
overflow-y: hidden;
overflow-x: auto;
}
li.dropdown {
position: static;
}

Please return to this link for more info