Why Aren't My Absolutely/Fixed-Positioned Elements Located Where I Expect

Why aren't my absolutely/fixed-positioned elements located where I expect?

To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:

'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block

We don't have any border and padding so in your case it will simply be:

'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block

And if you read under you will find this:


  1. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.

So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position

..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..

To make it easy, it's the position of the element if you didn't set position:absolute.

Here is an easy illustration to better understand

.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}


.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}

.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>

<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>

Why position: fixed does not follow the stacking context rules?

As mdn says about position: fixed:

Its final position is determined by the values of top, right, bottom,
and left.

So your code would look like this:

.fx {
position: fixed;
height: 30px;
width: 30px;
background-color: pink;
margin-top: 60px;
margin-left: 30px;
z-index: 10000;
top: 20px;
left: 10px;
}

.rel {
z-index: 7;
position: relative;
height: 500px;
width: 200px;
background-color: red;
margin-top: 30px;
}

.rel1 {
z-index: 6;
position: relative;
height: 500px;
width: 100px;
background-color: black;
margin-top: -300px;
}
<div class="rel">
</div>

<div class="rel1">
</div>

<div class="fx">
</div>

css element with translatey(0) is not being positioned properly

The transform property will apply relative transformation. It is usually used for animation more than positionning, and doesn't work in pair with position property.

Why does this footer element just disappear when it has fixed positioning?

Well, you've kind of hinted at the problem yourself already.

I noticed that when I set a footer to have fixed positioning (with no
left/right/top/bottom properties set), it just disappears.

Just because you haven't provided left/right/top/bottom properties, doesn't mean they are not in effect.

In this case, the default values (which most likely reflect the effective top/left values with the default position: static) are just not ideal.

Since the footer takes up the full width of the screen, the left value likely defaults to 0; this is fine and that's not the source of the problem.
But, since the footer is located on the bottom of your site, its auto/default top value max well be like 2000px -> you have to scroll down to even be able to see it.

Once you enabled fixed positioning, and didn't provide any top value yourself, that number would still be top: 2000px. And since it's now fixed in place, scrolling has no effect on it, which means its permanently located outside of your viewport. If your browser window was to be >2000px high, you would be able to see it, just hovering along by itself way below the rest of the site.

Justify-self not working on absolutely positioned elements in Chrome

Just add position: relative to the grid container.

body {  display: grid;  height: 100vh;  margin: 0;  position: relative; /* new */}
#absolute { position: absolute; align-self: end; justify-self: end;}
<div id="absolute">  <p>This element is absolutely positioned at the container's end.</p></div>

Why do I have to set top/bottom and left/right to 0 in order for my body::before to completely cover the page?

The body element by default has margin of 8px on all sides which causes it to move slightly to bottom-right, so when you remove the margins of the body body { margin: 0; }, it fixes that.

Secondly, when you set position: relative; width: 100%; height: 100%, the element goes with the normal flow of the document and takes up 100% of width and height but you did not define the width and height of the body element. So the normal flow of ::before becomes the 100% of the parent which is 0 (i.e. not defined) and hence doesn't show up. Thus in order to use position: relative; on a child element, you need to atleast define the width and height of the parent element with absolute length units.

Hence, the following works

body{
background: #000;
width: 100vw;
height: 100vh;
}

body::before {
content: "";
position: relative;

/* 100% is a relative unit and requires its
parent to have dimensions with absolute units */
width: 100%;
height: 100%;
...
}


Related Topics



Leave a reply



Submit