You are using position:fixed, and then placing your :before at 150px from the top and 150px from the left, so it is normal that it is 'after' your .box that is 100px wide and 100px tall and positioned 100px from the left and 100px from the top, also in position fixed.
If you use position:absolute on your :after instead, it will be positioned relative to it's parent div. For example:
.box {
position: fixed;
width: 100px;
height: 100px;
top: 100px;
left: 100px;
background-color: yellow;
border: 10px solid green;
z-index: 1;
}
.box:before {
content: '';
position: absolute;
width: 100px;
height: 100px;
top: 0px;
left: -110px;
background-color: tomato;
z-index: -1;
}
<div class="box"></div>
Edit: After getting the comment from Amaury Hanser, I'm adding a second snippet (since I don't know if it was the original poster that upvoted).
To place the :before "below" the .box, in terms of z-index, you could make use of the :before in conjunction with :after:
.box:before {
content: '';
position: fixed;
width: 100px;
height: 100px;
top: 100px;
left: 100px;
background-color: yellow;
border: 10px solid green;
z-index: 1;
}
.box:after {
content: '';
position: absolute;
width: 300px;
height: 300px;
top: 150px;
left: 150px;
background-color: tomato;
z-index: 0;
}
<div class="box"></div>
In simple terms, think of pseudo-elements much like child/parent elements. A child element cannot have a z-index lower than the parent element unless the parent element has no z-index assigned. Also, some position CSS rules give a "default" z-index, and no child can "break out" of it to go behind.