开发者

-webkit-transform and accommodating the cascade (how to not over-ride previous settings)

The dilemma:

In my CSS file, I have this:开发者_开发知识库

div {
    -webkit-transform: scale(0.5);
}

In my jQuery, I then later do this:

$('div).css('-webkit-transform','rotate(3deg)')

What happens (as you can maybe guess) is that setting -webkit-transform inline via jQuery over-rides the original setting. Normally this is fine/expected. But the issue here is that I'm actually setting two entirely different styles (scale and rotatation) but due to how webkit uses the same property name for both, one 'over-rides' the other.

Can anyone think of an elegant way to handle this? The best I can think of is to come up with a jQuery function that will parse this particular style and append to/subtract from a comma delimited list of values (akin to remove/addClass). That still may be a challenge, though, if one is dynamically updating nested elements all with different transformations. (for instance, I have a wrapper DIV that I want scale to apply to (and its children). One of the children also need to do a rotation, but still preserve the scale).

UPDATE:

Upon further investigation, this appears to not necessarily be a DOM updating issue but rather just an odd CSS cascade issue.

Sample code:

<html>
<head>
    <style>
      #parentSpan {
        -webkit-transform: scale(.25);
      }
    </style>
</head>
<body>
    <span id="parentSpan" style="
      display: block;
      border: 1px solid orange;
      width: 600px;
      -webkit-transform: rotate(5deg);
      ">
    hello
    </span>

I'm setting a scale style in the HEAD and then a rotate style inline. The inline rotate completely over-rides the scale since they are both '-webkit-transform' properties. Is that just the way it is?

UPDATE 2:

I think I have a workaround.

Turns out, I don't think this is an inheritance issue. My above example is over-writing the transform declaration, not adding to (inheritance).

The workaround would appear to add some extra markup. Apply the scale transform to a wrapper div, then apply the rotation transform to a child div. That child div will then have rotation AND also be scaled down visually due to the parent being scaled.


Yes, that's the way CSS is supposed to work, you're overriding the -webkit-transform property with a later/more specific definition. You could try something like:

$('div').css('-webkit-transform', $('div').css('-webkit-transform') + ' rotate(3deg)')

Or you could do a special case for the div that already has the transform set.


This behavior is sort of expected, because the transformation depends on the order in which the transformations are stated. It's different if you skew and then rotate than if you rotate and then skew (they produce different shapes) and this doesn't bode well with the cascading declarations.

Unfortunately, the facilites for getting around this in webkit are quite clunky, here is an example:

function getMatrix() {
  var element = document.getElementById("whatever");
  var transform = window.getComputedStyle(element).webkitTransform;
  return matrix = new WebKitCSSMatrix(transform);
}


$("#smaller").click(function(){
   getMatrix();
  $("#whatever").css("webkit-transform", matrix.scale(0.8));
});

$("#bigger").click(function(){
   getMatrix();
  $("#whatever").css("webkit-transform", matrix.scale(1.2));
});

$("#rotate").click(function(){
   getMatrix();
  $("#whatever").css("webkit-transform", matrix.rotate(5));
});

$("#invert").click(function(){
   getMatrix();
  $("#whatever").css("webkit-transform", matrix.inverse(1));
});

You can see it in action here: http://jsfiddle.net/VSqZt/


Depending on how your application is organized, you can encapsulate the various transform properties and then apply them all to your element with one transform rule.

For example:

The div you wish to transform is represented by a view or object. Give the view properties for the various transforms you wish to control. From your example, scale and rotate. Modify these properties on the view then update/render the element to set all transform properties at once.

var view = {
    scale: 1.0,
    rotate: "0deg",
    render: function() {
        $("#some-element").css("-webkit-transform", "scale("+this.scale+") rotate("+this.rotate+")");
    }
}

view.scale = 2.0;
view.rotate = "45deg";

view.render();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜