parent & child with position fixed, parent overflow:hidden bug
Solution 1
Because a fixed position element is fixed with respect to the viewport, not another element. Therefore since the viewport isn't cutting it off, the overflow becomes irrelevant.
Whereas the position and dimensions of an element with position:absolute are relative to its containing block, the position and dimensions of an element with position:fixed are always relative to the initial containing block. This is normally the viewport: the browser window or the paper’s page box.
ref: http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Fixed_positioning
Solution 2
You could consider using CSS clip: rect(top, right, bottom, left);
to clip a fixed positioned element to a parent. See demo at http://jsfiddle.net/lmeurs/jf3t0fmf/.
Beware, use with care!
Though the clip style is widely supported, main disadvantages are that:
- The parent's position cannot be static or relative (one can use an absolutely positioned parent inside a relatively positioned container);
- The rect coordinates do not support percentages, though the
auto
value equals100%
, ie.clip: rect(auto, auto, auto, auto);
; - Possibillities with child elements are limited in at least IE11 & Chrome34, ie. we cannot set the position of child elements to relative or absolute or use CSS3 transform like scale.
See http://tympanus.net/codrops/2013/01/16/understanding-the-css-clip-property/ for more info.
EDIT: Chrome seems to handle positioning of and CSS3 transforms on child elements a lot better when applying backface-visibility, so just to be sure we added:
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
to the main child element.
Also note that it's not fully supported by older / mobile browsers or it might take some extra effort. See our implementation for the menu at bellafuchsia.com.
- IE8 shows the menu well, but menu links are not clickable;
- IE9 does not show the menu under the fold;
- iOS Safari <5 does not show the menu well;
- iOS Safari 5+ repaints the clipped content on scroll after scrolling;
- FF (at least 13+), IE10+, Chrome and Chrome for Android seem to play nice.
EDIT 2014-11-02: Demo URL has been updated.
Solution 3
2016 update:
You can create a new stacking context, as seen on Coderwall:
<div style="transform: translate3d(0,0,0);overflow:hidden">
<img style="position:fixed; ..." />
</div>
Which refers to http://dev.w3.org/csswg/css-transforms/#transform-rendering
For elements whose layout is governed by the CSS box model, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
Solution 4
As an alternative to using clip you could also use {border-radius: 0.0001px}
on a parent element. It works not only with absolute/fixed positioned elements.
Solution 5
If you want to hide overflow on fixed-position elements, the simplest approach I've found is to place the element inside a container element, and apply position:fixed
and overflow:hidden
to that element instead of the contained element (you must remove position:fixed
from the contained element for this to work). The content of the fixed container should then be clipped as expected.
In my case I was having trouble with using object-fit:cover
on a fixed-position element (it was spilling outside the bounds of the page body, regardless of overflow:hidden
). Placing it inside a fixed container with overflow:hidden
on the container fixed the issue.
kirkas
I'm Léo Galley, a young Swiss multimedia designer. I am passionate about communications and the manifestations of it in every form, with a particular love for web design and UI design
Updated on July 05, 2022Comments
-
kirkas almost 2 years
I don't know if there is an issue, but I was wondering why the
overflow:hidden
does not function onfixed
parent/children element.Here's an example:
CSS and HTML:
.parent{ position:fixed; overflow:hidden; width:300px; height:300px; background:#555; } .children{ position:fixed; top:200px; left:200px; width:150px; height:150px; background:#333; }
<div class="parent"> <div class="children"> </div> </div>
Live demo: jsFiddle
-
bonflash over 9 yearsA brilliand solution, cheers!
iOS Safari 5+ repaints the clipped content on scroll after scrolling;
iOS 8 Safari (even after the update) still seems to behave that way.The rect coordinates do not support percentages
but we can give the .parent the needed percentage dimensions. -
JPSirois over 9 yearsThat’s life changing! Thank you so much for that technique!
-
Chris over 9 years@Imeurs Great solution. One caveat is that
clip
is now deprecated. Going forward we should be using theclip-path
property. In addition toclip: rect(auto, auto, auto, auto);
, we should also includeclip-path: inset(0 0 0 0);
-
Rogala over 9 years@Imeurs - Brilliant!!
-
Rudey over 7 years@Chris
clip
may be deprecated, butclip-path
is still not supported in IE11 or Edge. I will be usingclip
for now. -
Rudey over 7 yearsIt works in Edge, but it does not work in Internet Explorer 11.
-
Krupp over 6 yearsChrome renders
clip-path
very-very-very slowly. Hope they never deprecateclip
-
Starwave almost 6 yearsThere is still a problem - transform property introduces a new local coordinate system. so if I wanted my img to be fixed relative to viewport, now it is fixed relative to this overflow container element.
-
nektobit over 5 yearsjsfiddle link broken
-
Jarvis over 5 yearsHowever,
position: fixed;
of child doesn't work as expected. -
robbe clerckx over 5 yearsDoes not work in firefox, though. Would have loved this, much more reliable than repositioning all of your junk in javascript.
-
jlouzado over 4 yearswas this only down-voted because of the link? The answer is straightforward and works as intended.
-
Amit over 3 yearsThis solution worked great for me in 2020. Thanks!
-
M.Ortega about 3 years@Chris You made my day. It's working with clip and clip-path, very easy.
-
SalmanShariati over 2 yearsThe shortest answer is:
clip-path: inset(0)