3

I'm trying to shift an element to the left by using transform. However, there is already an existing property on the style transform which looks like this: transform: translate3d(tx, ty, tz)

What I want to do is in addition of the translate3d(tx, ty, tz), I want to add another property called translateX(tx). So the whole style will look like this:

transform: translate3d(tx, ty, tz) translateX(tx)

Is there a way to do this in CSS? I don't want to overwrite the existing style property but add onto it.. My project is in Angular so would I have to do some code in the component end? Any help is greatly appreciated!

EDIT: I should also mention that the translate3d style is already defined for the element, not in my css file but by default (I'm using a library that sets the style for the element already). What I am trying to figure out is how to grab the current style, which is transform: translate3d AND add the translateX style to it as well so that it looks like:

transform: translate3d(tx, ty, tz) translateX(tx)

I will say it again, I do not set the translate3d in my own css file but it's a style that is automatically set for that specific element because of the library. If it helps, the library I am using is Leaflet for Angular

fairlyMinty
  • 413
  • 8
  • 22
  • What kind of element are you trying to translate? A `L.Marker` or the like? – IvanSanchez Sep 14 '21 at 18:57
  • @IvanSanchez specifically the popup. `leaflet-popup` – fairlyMinty Sep 14 '21 at 19:29
  • This is a [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), then. Use `L.Popup`'s `offset` option (inherited from `DivOverlay`). See https://leafletjs.com/reference-1.7.1.html#popup-option – IvanSanchez Sep 14 '21 at 19:42
  • @IvanSanchez I see.. So I would have to set the offset for the popup then? What if I have multiple popups though and the size of the popup will not always be the same? – fairlyMinty Sep 14 '21 at 20:04
  • The `offset` is a per-popup option. You seem to be assuming that it's some kind of global setting. Also, the offset does not depend on the popup size (and vice versa). – IvanSanchez Sep 14 '21 at 20:21
  • @IvanSanchez so how would I know what to set the `offset` to? – fairlyMinty Sep 14 '21 at 20:52
  • Judging by your question, you want to offset the popup to the left but *you* don't specify an amount, nor your use case, nor provide screenshots. We mortals cannot read minds or anticipate use cases. – IvanSanchez Sep 14 '21 at 21:01
  • @IvanSanchez I asked a previous question that contains all my code, use case and screenshots if that helps: https://stackoverflow.com/questions/69136459/adjust-leaflet-popup-to-table-size-in-angular-leaflet – fairlyMinty Sep 14 '21 at 23:00

2 Answers2

0

Update 2

No more custom variables. This example directly changes the translate3d's x value. Note: I mostly copied the getTransform function from another SO post.

const myEl = document.querySelector(".myElement");
const MOD = 10;

const getTransform = el => {
  var transform = window.getComputedStyle(el, null).getPropertyValue('-webkit-transform');
  var results = transform.match(/matrix(?:(3d)\(-{0,1}\d+(?:, -{0,1}\d+)*(?:, (-{0,1}\d+))(?:, (-{0,1}\d+))(?:, (-{0,1}\d+)), -{0,1}\d+\)|\(-{0,1}\d+(?:, -{0,1}\d+)*(?:, (-{0,1}\d+))(?:, (-{0,1}\d+))\))/);

  if (!results) return [0, 0, 0];
  if (results[1] == '3d') return results.slice(2, 5);

  results.push(0);
  return results.slice(5, 8);
}

document.querySelector(".button").addEventListener("click", () => {
  const [x, y, z] = getTransform(myEl);
  const newX = parseInt(x, 10) + MOD;
  myEl.style.transform = `translate3d(${newX}px, ${y}, ${z})`;
});
.myElement {
  transform: translate3d(100px, 0, 0);
  display: inline-block;
  padding: 1rem;
  background-color: tomato;
  color: white;
  transition: 0.3s transform;
}

.button {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: gray;
  padding: .5rem 0;
  color: white;
  font-size: 1.4rem;
}
<div class="myElement">Test</div>
<button class="button">Move it</button>

Update

This will work and add 10px onto the initial x translation in the translate3d:

/* 200px + 10px = 210px x translation */
transform: translate3d(200px, 0, 0) translateX(10px);

div {
  background-color: red;
  padding: 1rem 2rem;
  display: inline-block;
  transform: translate3d(200px, 0, 0) translateX(10px);
}
<div></div>

Original Answer

Instead of this pattern…

transform: translate3d(tx, ty, tz) translateX(tx);

…you could set up the translate3d properties so they consume custom properties up front, and update the individual values as necessary.

transform: translate3d(var(--tx), var(--ty), var(--tz));

In the following example, I'm updating individual custom properties to move the box down and to the right. Note that nothing is overwritten and we have total control over the changes we'd like to make.

document.querySelector(".button").addEventListener("click", () => {
  const style = document.documentElement.style;
  style.setProperty("--tx", "120%");
  style.setProperty("--ty", "80px");
});
:root {
  --tx: 100%;
  --ty: 40px;
  --tz: 0;
}

.myElement {
  transform: translate3d(var(--tx), var(--ty), var(--tz));
  display: inline-block;
  padding: 1rem;
  background-color: tomato;
  color: white;
  transition: 0.3s transform;
}

.button {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: gray;
  padding: .5rem 0;
  color: white;
  font-size: 1.4rem;
}
<div class="myElement">Test</div>
<button class="button">Move it</button>
Andy Hoffman
  • 18,436
  • 4
  • 42
  • 61
  • Hmm the only thing is that the `translate3d` is already set and I don't want to modify or change it. I just want to add `translateX(-50%)` to the `transform` style t9 shift the element to the left – fairlyMinty Sep 14 '21 at 17:18
  • @fairlyMinty Not sure what you mean. The whole point of my answer is that you can change only one part of `translate3d` at a time. The first argument to `translate3d` *is* `translateX`. – Andy Hoffman Sep 14 '21 at 17:27
  • Yeah, that's the thing. I can't or shouldn't change anything in the `translate3d` since the values in there are already set and fixed. I don't have control over the values in `translate3d` which is why I wanted to try to add another property (translateX) to the style. Is that possibe? – fairlyMinty Sep 14 '21 at 17:43
  • @fairlyMinty I see. I updated my answer so that the origin `translate3d` is unchanged and the additional `translateX` simply adds onto the current `x` value as defined in the `translate3d`. – Andy Hoffman Sep 14 '21 at 17:50
  • I do see what you did. I guess I should also mention that the `translate3d` style is already defined for the element not in my css file but by default (I'm using a library that sets the style for the element already), so I need to figure out how to get the current style, which is `transform: translate3d` and add the `translateX` to it as well. – fairlyMinty Sep 14 '21 at 18:38
  • @fairlyMinty I think I have what you're looking for now. Please see my latest update. – Andy Hoffman Sep 14 '21 at 19:57
  • ah I see how you did it. You would have to do it using `document.querySelector` then. So there's no way to do this through CSS – fairlyMinty Sep 14 '21 at 20:09
  • @fairlyMinty There's no way to do this via `CSS` completely. I updated my latest example to get the first value in `translate3d`, add a modifier value to it, and update the DOM. – Andy Hoffman Sep 14 '21 at 20:20
  • Gotcha! I appreciate the help. One more thing, is there a way to do this in Angular? Because I know it's not ideal to use the DOM variables in Angular.. – fairlyMinty Sep 14 '21 at 21:09
  • @fairlyMinty I am not an Angular dev. This is the best I can do. – Andy Hoffman Sep 14 '21 at 21:23
0

One quick and dirty way to achieve this effect would be to take advantage of relative positioning, using the following CSS properties:

  • position: relative
  • left: [tx]

Working Example:

.my-heading-a,
.my-heading-b {
  position: relative;
  transform: translate3d(40px, 20px, 10px);
}

.my-heading-a {
  left: 0;
}

.my-heading-b {
  left: 80px;
}
<h2 class="my-heading-a">My Heading A</h2>
<h2 class="my-heading-b">My Heading B</h2>
Rounin
  • 27,134
  • 9
  • 83
  • 108