How to suspress the position: relative when using translate
Asked Answered
R

3

16

it seems that using transform: translateY(1px); also causes the element to gain an extra position: relative;-behaviour.

Is there a way to suspress this?

Here is a example on codepen.io.

I would like to position the whitebox absolutely to the green one, not the parent (red) one.

Remittance answered 9/3, 2015 at 17:14 Comment(0)
D
4

One option would be to displace/negate the parent's positioning by wrapping an element around #three (in this case, I added the .displacement element).

Absolutely position this wrapper element, and position it to cover the parent (using top: 0/right: 0/bottom: 0/left: 0). Then displace the element by giving it negative translation values, relative to the parent's.

<div class="displacement">
    <div id="three"></div>
</div>
.displacement {
  -webkit-transform: translateY(-25px) translateX(-25px);
  transform: translateY(-25px) translateX(-25px);
  position: absolute;
  top: 0; right: 0;
  bottom: 0; left: 0;
  width: 200%; height: 200%;
}

In doing so, the element #three is positioned absolutely relative to #one, and the parent #two's translated positioning is effectively displaced.

Updated Example

.displacement {
  -webkit-transform: translateY(-25px) translateX(-25px);
  transform: translateY(-25px) translateX(-25px);
  position: absolute;
  top: 0; right: 0;
  bottom: 0; left: 0;
  width: 200%; height: 200%;
}
#three {
  background-color: white;
  height: 25px;
  width: 25px;
  position: absolute;
  left: 0;
  bottom: 0;
}
Dhumma answered 9/3, 2015 at 17:20 Comment(3)
Thanks for your answer! This indeed, resolves the examples issue. But it won't work if you do not know all dimensions.. Lets say #three should be ´left: 0´ and ´right: 0´. This does not help then, does it?Remittance
@Remittance I figured out a work-around actually... codepen.io/anon/pen/yyxRzaDhumma
Great idea! Mind sharing that as an answer? I'll tick it as answering then (:Remittance
T
0

position:absolute (from moz) Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor or to the containing block. Absolutely positioned boxes can have margins, they do not collapse with any other margins.

so in your case the closest ancestor will always be #two which doesn't inherit any position property , just default position: static;...


if you gave #two position:relative// or absolute and positioned it with top: and left: maybe it's easier to place #three: http://codepen.io/maio/pen/qEMJpY

Transitory answered 9/3, 2015 at 17:30 Comment(2)
Youre reading it wrong. The containing block is the fallback, not prioritized check. You can also see this when removing the transforms from #two. Then #three will be positioned to #oneRemittance
I'm sure that two has position:static cause I checked dev-tools (also check adding a property like left:33px -> it doesn't react) ,since #three is nested in # two that's where absolute positioning is being calculated fromTransitory
A
0

Here's a less-than-ideal workaround, but it works for your existing markup.

Change your #two CSS to a pseudo-element, adding these styles:

#two::before {
  content: '';
  display: block;
}

Updated CodePen


Short of changing your markup, your other solution is to use JavaScript to make three a child of element one:
document.querySelector('#one').appendChild(document.querySelector('#three'));

However, it will no longer inherit any styles from element two, as demonstrated in this CodePen.

Here's an interesting read, which confirms "transforming an element force-adds position: relative.": http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/

Not only that, but it also affects fixed-position elements, which doesn't make much sense.

Area answered 9/3, 2015 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.