3

According to this statement:

When position is set to absolute or fixed, the left property specifies the distance between the element's left edge and the left edge of its containing block. (The containing block is the ancestor to which the element is relatively positioned.)

I put a fixed element inside a relative element, and set its 'left' property to some value.This value should relative to its parent div. But it doesn't work as expected. see my codepen: https://codepen.io/iamnotstone/pen/PgdPrJ?&editable=true

The text should inside the red box.

body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

.test {
  width: 500px;
  height: 132px;
  background-color: red;
  position: relative;
  left: 200px
}

h1 {
  position: fixed;
  top: 0px;
  width: 500px;
  margin: 0 auto;
  padding: 10px;
  left: 0px
}
<div class='test'>
  <h1>Fixed positioning</h1>
</div>
Adriano
  • 3,788
  • 5
  • 32
  • 53
欧阳维杰
  • 1,608
  • 1
  • 14
  • 22

4 Answers4

3

According to the doc: Fixed positioning

Fixed positioning is similar to absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport.

Instead of left you can use margin-left property:

body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}
.test{
  width: 500px;
  height: 132px;
  background-color: red;
  position: relative;
  left: 200px
}


h1 {
  position: fixed;
  top: 0px;
  width: 500px;
  margin: 0 auto;
  padding: 10px;
  margin-left: 0px
}
<div class='test'>
  <h1>Fixed positioning</h1>
</div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
  • Could you explain why I can not put a left inside a left ? – 欧阳维杰 Apr 23 '19 at 05:54
  • @欧阳维杰, *left* is only applicable for elements set with *absolute* or *relative* positioning...:) – Mamun Apr 23 '19 at 05:58
  • So that statement in mozilla is somewhat meaningless ? – 欧阳维杰 Apr 23 '19 at 06:02
  • 1
    @Mamun, I think you generalize a bit too much with your statement. The left property does apply to elements using `position: fixed`. [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/left) and a simple [demo](https://jsfiddle.net/25dr18bu/) – Nico O Apr 23 '19 at 06:08
  • @NicoO, it is strange, what the document says, I could not make it work!!! – Mamun Apr 23 '19 at 06:17
  • 3
    You seem to be correct about a mistake in the docs (see discussion above). I think [w3c.org](https://www.w3.org/TR/css-position-3/#fixed-pos) delivers the best description: `Fixed positioning is similar to absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport.` – Nico O Apr 23 '19 at 06:30
  • Hey friends! When I added a transform property in its parent. everything just works as expected! @Nico – 欧阳维杰 Apr 23 '19 at 07:02
  • This works because: In `absolute` or `fixed` positioned elements, if you omit positional properties (`left` and `right` for x-axis and `top` and `bottom` for y-axis), these elements take that position, which they would have with `static` positioning – yunzen Apr 24 '19 at 10:26
0

It's very strange. When I set a transform property inside its parent, everything just works as expected!

body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}
.test{
  width: 500px;
  height: 132px;
  background-color: red;
  position: relative;
  left: 200px;
  transform: translate(0) /* added this, and works as expected */
}


h1 {
  position: fixed;
  top: 0px;
  width: 500px;
  margin: 0 auto;
  padding: 10px;
  left: 0px
}
<div class='test'>
  <h1>Fixed positioning</h1>
</div>

finally , I found the answer.

There is also a statement here:

  1. If the position property is fixed, the containing block is established by the viewport (in the case of continuous media) or the page area (in the case of paged media).

  2. If the position property is absolute or fixed, the containing block may also be formed by the edge of the padding box of the nearest ancestor element that has the following:

    A transform or perspective value other than none

    A will-change value of transform or perspective

    A filter value other than none or a will-change value of filter (only works on Firefox).

    A contain value of paint (e.g. contain: paint;)

Community
  • 1
  • 1
欧阳维杰
  • 1,608
  • 1
  • 14
  • 22
  • 1
    This is a bug in Chrome: https://stackoverflow.com/questions/2637058/positions-fixed-doesnt-work-when-using-webkit-transform – yunzen Apr 23 '19 at 07:33
  • Yes, exactly ! So it is better to avoid transform property on parent element@yunzen – 欧阳维杰 Apr 23 '19 at 08:44
  • 1
    @yunzen it's not a bug, it's by design: https://stackoverflow.com/a/15256339/8620333 – Temani Afif Apr 23 '19 at 08:46
  • I found this : If the position property is absolute or fixed, the containing block may also be formed by the edge of the padding box of the nearest ancestor element that has the following: A transform or perspective value other than none A will-change value of transform or perspective A filter value other than none or a will-change value of filter (only works on Firefox). A contain value of paint (e.g. contain: paint;) – 欧阳维杰 Apr 23 '19 at 09:02
0

If you use position: fixed; you are defining the position of an element in the viewport. If you use position: absolute; then you are defining the position of an element in its parent's box. Also CSS prioritises code lower down, so for example in your code h1 is the most prioritised element (does not apply for classes and ID's, Classes take priority over elements and ID's take priority over classes).

Dat Boi
  • 595
  • 3
  • 12
0

You need to use position: fixed for the document's body and use position: absolute for the elements with the parent which has position: relative, so change h1's position to absolute :

body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}
.test{
  width: 500px;
  height: 132px;
  background-color: red;
  position: relative;
  left: 200px;
  transform: translate(0) /* added this, and works as expected */
}


h1 {
  position: absolute;   // 
  top: 0px;
  width: 500px;
  margin: 0 auto;
  padding: 10px;
  left: 0px
}
MN. Vala
  • 129
  • 1
  • 6