Why does `transform` break `position: fixed`?
Regarding the why, a quick quote from this article by meyer:
A transformed element creates a containing block even for descendants that have been set to position: fixed. In other words, the containing block for a fixed-position descendant of a transformed element is the transformed element, not the viewport
It's a quirky behavior that's been around since 2011.
Why does transform break the dimensions of an element with position:fixed?
This behavior appears to be in conformance with the spec:
6 The Transform Rendering
ModelFor elements whose layout is governed by the CSS box model, any value
other thannone
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.
In other words, once you apply transform to an element (as you have done to .box
), any fixed positioned descendants (like your pseudo-element), start using the transformed element as the containing block, not the viewport.
transform3d' not working with position: fixed children
This is because the transform
creates a new local coordinate system, as per W3C spec:
In the HTML namespace, 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.
This means that fixed positioning becomes fixed to the transformed element, rather than the viewport.
There's not currently a work-around that I'm aware of.
It is also documented on Eric Meyer's article: Un-fixing Fixed Elements with CSS Transforms.
Using CSS transform scale breaks position:fixed
Well the transform: scale(x)
will break the element out of the coordinate flow and thereby can not have a fixed position.
I'd recommend instead wrapping the text below #header
in a constrained div
with overflow: auto
. A fixed
child of a fixed
ancestor just doesn't make that much sense, but I can see what you were going for.
Why does will-change:opacity treat fixed elements differently than will-change:transform in chrome?
The whole point of will-change
is to make all possible changes that browser would have to apply when the specified property will change in advance, reducing the time needed for the change itself. Effectively it means that by specifying will-change:transform
you make the element transformed (though visually it stays in the same position), and descendants of the transformed elements can't be fixed per the CSS Transforms spec. Opacity doesn't have such effect, so will-change:opacity
doesn't break fixed positioning.
Also, will-change
per se doesn't have any "optimization magic", it only optimizes the changes of the specified properties. Some properties force the elements to the composite layers that theoretically can be processed by the GPU more efficiently, but if there is too many such elements it may have the opposite effect. For optimizing scrolling, probably other strategies would be more efficient.
Positions fixed doesn't work when using -webkit-transform
After some research, there has been a bug report on the Chromium website about this issue, so far Webkit browsers can't render these two effects together at the same time.
I would suggest adding some Webkit only CSS into your stylesheet and making the transformed div an image and using it as the background.
@media screen and (-webkit-min-device-pixel-ratio:0) {
/* Webkit-specific CSS here (Chrome and Safari) */
#transformed_div {
/* styles here, background image etc */
}
}
So for now you'll have to do it the old fashioned way, until Webkit browsers catch up to FF.
EDIT: As of 10/24/2012 the bug has not been resolved.
This appears to not be a bug, but an aspect of the specification due to the two effects requiring separate coordinate systems and stacking orders. As explained in this answer.
How to force position fixed when parent container has a transformation?
The Answer is simple this is not possible with CSS. Visit the following question for details
Positions fixed doesn't work when using -webkit-transform
'transform3d' not working with position: fixed children
But you can achieve your target with js here is a basic example.
$(window).scroll(function() { $(".transform-fixed").css({ "top": $(window).scrollTop() });})
.rotate { transform: rotate(30deg); background: blue; width: 300px; height: 300px; margin: 0 auto; }.fixed { position: fixed; background: red; padding: 10px; color: white; top: 50px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><html>
<body> <div class="rotate"> <div class="fixed transform-fixed"> I am fixed inside a rotated div.</div> </div> <div class="fixed"> I am fixed outside a rotated div.</div></body>
</html>
Related Topics
How to Create a Teardrop in HTML
How to Center Multiple Divs Inside a Container in CSS
How to Have Two Items on Opposite Sides on The Same Line
Can't Show Some Websites in Iframe Tag
Should I Use <Ul>S and <Li>S Inside My <Nav>S
How to Extract Data from HTML Table in Shell Script
HTML 5 Audio Tag Multiple Files
Streaming a Video from Google Drive Using HTML5 Video Tag
Change Bootstrap Input Focus Blue Glow
2 Colors in One Placeholder of Input Field
Equivalent to Float in Outlook
Paragraph of Text in Circle Using CSS
Can a: :Before Selector Be Used with a <Textarea>
Height: 100% for <Div> Inside <Div> with Display: Table-Cell