I believe, every front-end developer encountered this situation, at least once. Let’s say you need to absolute position something… And then you try to move it in some direction, and boom it disappears… You forgot the parent was set to overflow:hidden
and now your element is lost in the hidden
infinite vacuum.
Well, usually it ends by putting the absolute
element outside of the annoying overflow:hidden
parent, and you grumbling about how CSS sucks and so on… Actually you’re quite right. CSS do sucks a lot, even CSS3, I mean … ok no troll here 🙂
Let me show you a neat trick.
But first, if you’re trying to mess with these absolute/relative properties you really should be aware of these few important rules:
- An absolutely positioned element is actually positioned regarding a
relative
parent, or the nearest foundrelative
parent, which means it bubbles up the DOM until it finds arelative
context to apply the positioning. - If no relative parent is found it will then reach the highest possible « container », which is the browser window, aka the
viewport
(or thedocument
maybe, or thewindow
… ? hey you know what, I’m not a W3C expert ok!). - BTW, this is probably why they called it « re-la-tive », just sayin’ 😛
- It works the same if the parent is set to
absolute
instead ofrelative
(anabsolute
inside anotherabsolute
) the first absolute acts as the positioning context for the second absolute.
Anyway, here our main problem is that the relative
parent is also the overflow:hidden
one. Well, if we simply move the position
rule to put it just one level above, then the problem will be solved. True. Isn’t that just magic? Actually no, it’s not magic.
And let me prove what I’m saying.
HTML
<div class="parent">
<div class="child"></div>
</div>
CSS
.parent { position: relative; overflow: hidden; } .child { position: absolute; top: -10px; left: -5px; }
Result
Indeed, we can actually see that the little blue square is partially hidden by its overflow hidden parent.
Now the solution
Now let’s add another parent and move the position:relative
one level up (or, in your context, you could maybe simply use an existing upper parent).
HTML
<div class="grand-parent">
<div class="parent">
<div class="child"></div>
</div>
</div>
CSS
.grand-parent { position: relative; } .parent { /*position: relative;*/ overflow: hidden; } .child { position: absolute; top: -10px; left: -5px; }
Result
Magic.
Ressources
Thierry Koblentz’s article explaining different techniques to « clear floats » AND showing this clever trick.
* The post itself
* The overflow hidden / absolute demo (which isn’t there anymore apparently…)
Totally ridiculous solution, but it works. Thanks! I googled for the exact blog title… haha…
hehe ridiculous indeed 🙂
Ty ! it work 😀
Thanks, didn’t know, that it can be done so simple, I’ve been looking for this solution for ages:)))!
This isn’t completely ridiculous – it has to do with the default positioning of the container being “static” not relative and how absolute position will jump up to the nearest relative.
This is a good technique, however the downfall is that if the container is scrollable, the absolutely positioned item will not scroll with the container. It is essentially disconnected from it’s nearest parent element and is not affected by scrolling.
If there’s a solution for that without JS, I hope I can find it!
i agree , i want it to be relative relative to the element ‘s parent (to move with it whenever a scrolling happens) .at the same time, i don’t want my absolutely positioned element to be restricted by the || overflow : hidden || of the grand parent
did u find any solutions ?
Well, till the time it works its a perfect solution. Web indeed has many instances of ridiculous solutions 🙂 BTW @jkneb if one cannot simply comment or delete
position: relative;
property from parent element, would it be fine to override the same withposition: initial;
?Hey,
I don’t think it’ll work because the point with this trick is to have a
relative
parent, andinitial
would be equivalent tostatic
(which isposition
‘s default).And by the way
initial
is not supported in Internet Explorer.Small typo in the first example: the class “enfant” and “child” do not match
Indeed. Fixed. Thx.
Thank you a lot for your post. I was trying to find a solution for ages .
I have a div that contains an iframe
Now I replace it by:
(position relative)
(overflow hidden)
(position absolute with width and hight and left:0px and top:110px)
I solved the overflow hidden problem but now I can’t fix the div to the exacte position that I want . Left:0px and top:110px.
Does anyone know how to fix it??
Thanks again for your post you saved me! 🙂
Hi, can you provide a demo with jsbin or jsfiddle 🙂
The solution worked, but when I wrap the child into a div which has relative position, it fail again TT
see the demo
Hi, it looks fine on Chrome 38
Great post ! But what if the parent element has a fixed position. I’m facing this problem and can’t face it
Well this solution is not ridiculous. It is inproperly marked. Grand parent should be named parent and parent should be named first child and child should be named second child. They are all childs to the “grandparent”. Why do you ask? It’s because position obsolute makes the last div with positon: relative it’s parent. Hence why they are both childs.
Thank you!
Thanks!) It was useful for my case.
Great solution.
Maybe below is useful for someone:
What I’ve found was that it won’t work if you have any element in the stack with the css property of transform: translate3d(), this somehow breaks the behaviour and will result in that the overflow hidden is not being ignored by the absolute positioning of the child.
Hi! Thanks for your help. Really help me a lot!
Man, you ROCK!
ok, but if i change the grand-parent class to overflow:hidden i’ll get back the same problem again
Thank you, this saved my day….
I have the same problem with a datetimepicker (position:absolute) plugin in a relative positioned container ( .liquid-container)
https://jsbin.com/jufomolusi/edit?output (1. run with js, 2. click the input fields)
Indeed, I’d find a way to simply get rid of that .liquid-container
” I’d find a way to simply get rid of that .liquid-container”
Unfortunately I can’t remove the div. And if I would, there is the modal-body, also with overflow: hidden.
I need a more overall solution. Somehow .bootstrap-datetimepicker-widget should be in a layer on top of the others.
Could you help me pls, How to make absolute positioned elements overlap their overflow scroll parent?
You saved me! 😀
Thanks this works for me!
You saved me too! Thx dude 🙂
Super cool!! I was looking how to achive it without JS. GREAT!!!!
After scratching my head for 2 hours, such simple was the solution. Thanks a ton buddy…
You saved my time)) Thanks!
I need only outer part to display. Parent block should be transparent also, so that it can be used as like loader like element to display on something in the page.
it does not work with ios (12) properly.
sorry for my second post: it does not work with ios (12) properly, especially if you toggle something (hide/show) – any ideas?
aaand my third post: if your’e using “overflow: auto” combined with -webkit-overflow-scrolling: touch; – that’s making the issues… hmpf
If you want to understand the “magic”, try just replace `overflow: hidden` to `overflow: scroll` with content.
On the first example you’ll see how the small square will follow the scroll.
On the second, it’ll stick to the `.grand-parent` element.
2019 year… Thanks 🙂
I love your writing style!
thank you so much… the only solution that worked for me
Thank you for the solution. Works for me.
Now the issue is when I am using scroller in parent/grandparent , its again get hidden. Any solution for that?
Thanks.