Why Does Perspective Changes Fixed Position in CSS

Why are my elements moving when changing position from fixed to static?

HTML elements are positioned static by default. No need to define that in your CSS, unless you are using a library/framework of some sorts that define the positioning on your element.

An element with position: fixed; is positioned relative to the viewport, which means it always stays in the same place even if the page is scrolled.

This means that if you're setting left: 3%; and bottom: 93%;, the element will be positioned 97% to the left and 7% to the bottom (very close to the top) relative to the viewport - not its parent container, which in this case would be discord.

So unless you want the element to be there while you're scrolling the page, don't use position:fixed;. If you want your navbar to be set in place and stay there during scrolling, ONLY apply position: fixed; to the navbar's parent - the full container containing all your img-elements.

Codepen: https://codepen.io/sigurdmazanti/pen/wvpPJPz

Example snippet that has position:fixed; on its parent container:

body {
height: 150vh;
background-color: blue;
}

nav.fixed {
width: 100%;
position: fixed;
}

nav.static {
width: 100%;
padding-top: 100px;
}

ul {
max-width: 50%;
margin: 0 auto;
list-style-type: none;
display: flex;
justify-content: space-between;
}

li {
background-color: white;
}
<body>
<nav class="fixed">
<ul>
<li>fixed</li>
<li>fixed</li>
<li>fixed</li>
</ul>
</nav>

<nav class="static">
<ul>
<li>static</li>
<li>static</li>
<li>static</li>
</ul>
</nav>
</body>

Why perspective isn't giving the same result when some styles are updated?

Each have almost the same values, one perspective looks fine,

No they don't have the same values. One is using position:absolute and the the other one position:relative and this make a big difference. If you inspect the god element you will notice that its height is 0 when using the position:absolute (the first case) which is creating the issue.

Here is a simplified code to better show your issue:

.box {
display: inline-block;
vertical-align:top;
width: 100px;
perspective: 200px;
position: relative;
margin: 20px;
background:blue;
}

.box>div {
position: relative;
padding: 10px;
background: red;
color: #fff;
transition: 1s all linear;
transform-origin: top left;
}

body:hover .box > div {
transform: rotateY(-40deg);
}
<div class="box">
<div>Some text here</div>
</div>
<div class="box">
<div style="position:absolute;">Some text here</div>
</div>

perspective() problems fixed with perspective?

Keep the pespective constant, don't change it on hover.

Just add to .card: (no rotation, but the same pespective that you are setting on hover)

transform: perspective(1000px) rotateY(0deg);

.front,.back,.card {  width: 100px;  height: 170px;  border-radius: 10px;  text-align: center;}
.card { position: relative; transition: transform 1s ease-in-out 0s; transform-style: preserve-3d; transform-origin: right; transform: perspective(1000px) rotateY(0deg);}
.card:hover { transform: perspective(1000px) rotateY(180deg);}
.front { background-color: red;}
.back { background-color: blue; transform: rotateY(180deg); position: absolute; top: 0px; z-index: -1;}
<div class="card">  <div class="front">    FRONT  </div>  <div class="back">    BACK  </div></div>

CSS make DIV position fixed inside DIV with PERSPECTIVE propertie

Since you can't have the fixed inside, Why does perspective changes fixed position in CSS?, I suggest you add an extra wrapper for your javascript overlay function.

Since you can't have the fixed inside, Why does perspective changes fixed position in CSS?, just place them outside your container (as in below sample), as I can't see the point adding a second wrapper because the fixed div is relative to the window anyway.

#container { width:100%; height:100%; perspective:300px;  perspective-origin:50% 50%;  overflow-y:scroll;}
.parallaxBase { width:100%; position:absolute; top:200px; left:50%; transform:translateZ(0); transform:translateX(-50%);
}
.parallaxBack { height:100vh; transform:translateZ(-300px) scale(2);
}
#background {background:red; height:200px; padding-top:100px; }#content {background:yellow; }#fixed {background:green; width:100%; height:40px; position:fixed; z-index:1; top: 0; left: 0; }
#overlay {width:200px; height:200px; background:purple;position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); }
<div id="fixed">this is fixed // why not fixed?</div><div id="container">  <div class="parallaxBack">    <div id="background"> this is parallax</div>  </div>  <div class="parallaxBase">    <div id="content">      this is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is content      this is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is contentthis is content    </div>  </div></div><div id="overlay">  this is overlay</div>

Why changing the position changes the effect of 3D transform?

although both of them has the same perspective view why changing their position changed the effect of 3D transform ?

They have the same perspective, yes but the trick is in the perspective-origin which is set to be the center of the parent element (not the elements). Your Red element is already in center so it will only comes close to your while the yellow element isn't in the center so its movement will be different.

To better illustrate here is another example using a rotate transformation.

.container {
border:2px solid red;
perspective:300px;
perspective-origin:50% 50%;
padding:20px;
display:flex;
justify-content:space-around;
}

.container > div {
width:50px;
height:50px;
background:blue;
transform:rotateY(20deg);
}
<div class="container">
<div></div>
<div></div>
<div></div>
</div>

<div class="container" style="perspective-origin:10% 50%">
<div></div>
<div></div>
<div></div>
</div>

<div class="container" style="perspective-origin:70% 50%">
<div></div>
<div></div>
<div></div>
</div>

What happens when nesting elements with position: fixed inside each other?

The fixing and the positioning are two separate things. They're positioned the same as absolutely positioned elements: relative to their containing block. But in contrast with absolutely positioned elements, they remain fixed to that position with respect to the viewport (i.e. they don't move when scrolling):

http://www.w3.org/TR/CSS2/visuren.html#propdef-position

The box's position is calculated according to the 'absolute' model, but in addition, the box is fixed with respect to some reference.

Positioning

The definition of containing block says:

If the element has 'position: fixed', the containing block is established by the viewport in the case of continuous media (...)

and

If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed' (...)

which suggests that while their positioning algorithm is the same (they're both positioned relative to their containing block), the containing block for fixed elements is always the viewport, in contrast with absolutely positioned elements, so they should be positioned relative to that and not to any absolutely or fixed-positioned elements.

And as a matter of fact, that is indeed the case. For example, if you add top: 20px to .fixed, both divs will be positioned 20 pixels from the top of the viewport. The nested fixed div does not get positioned 20 pixels down from the top of its parent.

The reason you're not seeing that in this case is because you're not actually setting any of the left/top/right/bottom properties, so their positions are determined by the position they would have in the flow (their "static position"), which as my first quote said, is done according to the absolute model.

Why does applying a CSS-Filter on the parent break the child positioning?

If we refer to the specification we can read:

A value other than none for the filter property results in the
creation of a containing block for absolute and fixed positioned
descendants unless the element it applies to is a document root
element in the current browsing context. The list of functions are
applied in the order provided.

This means that your position:fixed element will be positioned relatively to the filtered container and no more the viewport. In other words, it's still fixed but inside its new containing block (the filtered container)

Here is a simplified version to illustrate the issue:

.container {
display: inline-block;
width: 200px;
height: 200vh;
border: 1px solid;
}

.container>div {
position: fixed;
width: 100px;
height: 100px;
background: red;
color: #fff;
}
<div class="container">
<div>I am fixed on scroll</div>
</div>

<div class="container" style="filter:grayscale(1);">
<div>I move with the scroll</div>
</div>


Related Topics



Leave a reply



Submit