Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a single value of transform while leaving the other values?

Tags:

javascript

css

If you have an element with many values for transform how do you change just one of those values without changing the other values?

You could rewrite them every time but in some situations that means you will have to parse apart the css for the transform into its different parts. For example:

-webkit-transform:rotateY(45deg) rotate(45deg);

you would have to get the property and value for rotate and rotateY. Isn't there a way to get and set just rotate without changing the value for rotateY?

The problem is illustrated here.

like image 231
user1873073 Avatar asked Dec 07 '12 19:12

user1873073


People also ask

When adding multiple transformations in a single transform property separate them with?

In the example below, we'll use multiple values of the transform property. It is possible to add multiple values applied one after another. The values must be separated by space.

Which value of the transform property allows to move an object to the side?

skewX() and skewY() : Tilts an element to the left or right, like turning a rectangle into a parallelogram. skew() is a shorthand that combines skewX() and skewY by accepting both values. translate() : Moves an element sideways or up and down.

What is the transform translate () method used for?

The translate() method moves an element from its current position (according to the parameters given for the X-axis and the Y-axis).

Can you have two transform CSS?

The transform property can be given multiple values that are applied one after another.


1 Answers

There is no way to directly modify a single component of the transform. Sadly, the various possible transforms were implemented as values on the transform attribute, rather than attributes themselves. There is no object model for CSS attribute values - attribute values are always just a string, as far as JavaScript is concerned. It would've been nice if transform was treated as a shorthand attribute for, eg, transform-rotate-y, transform-*, etc, the same way that background is a shorthand attribute for all the background-* attributes. This would've allowed us direct access to the values via JavaScript, but it was not implemented that way, so we are out of luck.

Edit: The simplest way to accomplish this (without studying the spec and doing a bunch of math) would be to nest your elements, applying different transformations to each. If you apply several transformations that won't change, go ahead and combine those on to one element. Any transformation that you do want to change, use a separate element:

Works here: jsfiddle.net/mkTKH/15


Edit: My original solution below won't work. In testing it out I discovered that getComputedStyle() converts the transform into a matrix(). An early draft of the spec says:

The transform property of the style object returned by getComputedStyle contains a single CSSTransformValue with a type of CSS_MATRIX. The 6 parameters represent the 3x2 matrix that is the result of applying the individual functions listed in the transform property.


So, you have to parse it. If you want to change just one portion of an attribute value, you can use a regular expression to parse the value:

var rotateY = "rotateY(" + deg + "deg)";
var transform = el.style.webkitTransform.replace(/\brotateY([^)]+)\b/, rotateY);
el.style.webkitTransform = transform;

I'd create a reusable function:

function setTransformValue(el, name, value) {
    var currentValue = new RegExp(name + "([^)]+)");
    var style = window.getComputedStyle ? getComputedStyle(el) : el.currentStyle;
    var currentTransform = style.transform ||
                           style.webkitTransform ||
                           style.MozTransform ||
                           style.msTransform ||
                           style.OTransform;
    var transform;
    if (currentValue.test(currentTransform )) {
        transform = currentTransform.replace(currentValue, name + "(" + value + ")");
    }
    else {
        transform = currentTransform + " " + name + "(" + value + ")";
    }
    el.style.transform = transform;
}

Untested.

like image 164
gilly3 Avatar answered Oct 05 '22 13:10

gilly3