Add on a property to an existing style

517 Views Asked by At

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

2

There are 2 best solutions below

10
Andy Hoffman On

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>

0
Rounin On

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>