Transform-Origin Not Working in Firefox Even Properties in Percentage Value

transform-origin not working in Firefox even properties in percentage value

To summarise the comments you have been getting:

  1. The transform-origin property with percentage values on SVG elements has been broken in Firefox, and has only just been fixed/implemented.

  2. The meaning of transform-origin: 50% 50% when applied to SVG elements has not been fully specified until recently. Chrome used the centre of the element's bounding box. Firefox uses the centre of the SVG.

  3. How percentage origins are to be calculated has only recently been decided. There is a new property called transform-box. See: https://drafts.csswg.org/css-transforms/#transform-box

The default value of transform-box for SVG elements is view-box (typically the centre of the whole SVG). However Chrome currently uses the equivalent of fill-box.

In summary, you should not rely on Chrome's behaviour. It is probably going to change to match what is specified by the new transform-box property.

If you want to have your SVG work now on both browsers, don't use percentage values in transform-origin. Use absolute coordinates. See example below.

.tyreA {  -webkit-transform-origin: 71.59px 43.42px;  -moz-transform-origin: 71.59px 43.42px;  transform-origin: 71.59px 43.42px;  transform: rotate(0);  -webkit-animation: spin 1s linear infinite;          animation: spin 1s linear infinite;}
.tyreB { -webkit-transform-origin: 19.83px 43.39px; -moz-transform-origin: 19.83px 43.39px; transform-origin: 19.83px 43.39px; transform: rotate(0); -webkit-animation: spin 1s linear infinite; animation: spin 1s linear infinite;}
.tyreC { -webkit-transform-origin: 51.2px 43.39px; -moz-transform-origin: 51.2px 43.39px; transform-origin: 51.2px 43.39px; transform: rotate(0); -webkit-animation: spin 1s linear infinite; animation: spin 1s linear infinite;}
@-webkit-keyframes spin { from { transform: rotate(360deg); } to { transform: rotate(0deg); }}@keyframes spin { from { transform: rotate(360deg); } to { transform: rotate(0deg); }}
<svg class='truck' viewBox='0 0 93 53' xmlns='http://www.w3.org/2000/svg' height="180">  <g class='chase' fill-rule='evenodd' fill='none'>    <path d='M32.087 35.263h3.023V5.973h-3.023v29.29z' fill='#EE7C00'></path>    <path d='M87.84 35.262H5.007v4.065L9.07 43.39h74.707l4.062-4.063v-4.065z' fill='#9B9B9B'></path>    <path d='M35.11 35.262h57.445v-3.966H35.11v3.966z' fill='#F09E00'></path>    <path d='M90.393 35.262h2.16v-3.966h-2.16v3.966z' fill='#E2000F'></path>    <path d='M17.498.493L2.91 15.08v20.182h29.175V.492H17.498z' fill='#FCC400'></path>    <path d='M29.495 2.905H18.16L6.823 14.24h22.67V2.905z' fill='#575656'></path>    <path d='M0 35.262h10.014v-3.966H0v3.966z' fill='#F09E00'></path>    <path d='M5.008 37.294h82.83v-2.032H5.01v2.032z' fill='#575656'></path>    <path d='M.75 29.858h2.16v-6.995H.75v6.995zM11.015 20.074h3.497v-2.16h-3.497v2.16z' fill='#E2000F'></path>    <path d='M28.447 35.262h1.05V14.24h-1.05v21.022z' fill='#EE7C00'></path>    <path d='M53.51 27.23h34.33v4.065H53.51V27.23z' fill='#575656'></path>  </g>  <g class='tyreA'>    <path d='M64.827 36.593a9.61 9.61 0 0 0 0 13.59c3.753 3.754 9.837 3.754 13.59 0a9.61 9.61 0 0 0-13.59-13.59' fill='#1A1A18'></path>    <path d='M67.287 39.053a6.13 6.13 0 0 0 0 8.67 6.13 6.13 0 1 0 0-8.67' fill='#9B9B9B'></path>    <path d='M67.287 39.053a6.133 6.133 0 0 0 0 8.67 6.134 6.134 0 0 0 8.67 0l-8.67-8.67z' fill='#C5C5C6'></path>    <path d='M68.784 40.55a4.012 4.012 0 0 0 5.676 5.677 4.012 4.012 0 0 0-5.676-5.676' fill='#868685'></path>    <path d='M65.526 37.293A8.62 8.62 0 1 1 77.72 49.486a8.62 8.62 0 0 1-12.192-12.193m-.385-.386c-3.578 3.578-3.578 9.384 0 12.963 3.58 3.58 9.385 3.58 12.964 0 3.578-3.58 3.578-9.385 0-12.963-3.58-3.58-9.386-3.58-12.964 0' fill='#3B3A39'></path>  </g>  <g class='tyreB'>    <path d='M13.038 36.593c-3.754 3.754-3.754 9.838 0 13.59a9.61 9.61 0 0 0 13.59 0c3.754-3.752 3.754-9.836 0-13.59a9.61 9.61 0 0 0-13.59 0' fill='#1A1A18'></path>    <path d='M15.498 39.054a6.128 6.128 0 0 0 0 8.67 6.13 6.13 0 0 0 8.67 0 6.13 6.13 0 0 0-8.67-8.67' fill='#9B9B9B'></path>    <path d='M15.498 39.054a6.13 6.13 0 1 0 8.67 8.67l-8.67-8.67z' fill='#C5C5C6'></path>    <path d='M16.996 40.55a4.012 4.012 0 1 0 5.675 5.677 4.014 4.014 0 0 0-5.674-5.676' fill='#868685'></path>    <path d='M13.737 37.293a8.622 8.622 0 0 1 12.192 0 8.622 8.622 0 0 1 0 12.192 8.622 8.622 0 0 1-12.193 0 8.622 8.622 0 0 1 0-12.192m-.385-.385a9.164 9.164 0 0 0 0 12.962c3.578 3.58 9.384 3.58 12.962 0a9.164 9.164 0 0 0 0-12.962 9.164 9.164 0 0 0-12.962 0' fill='#3B3A39'></path>  </g>  <g class='tyreC'>    <path d='M44.406 36.593c-3.753 3.754-3.753 9.838 0 13.59 3.754 3.755 9.838 3.755 13.59 0 3.755-3.752 3.755-9.836 0-13.59-3.752-3.753-9.836-3.753-13.59 0' fill='#1A1A18'></path>    <path d='M46.868 39.054a6.128 6.128 0 0 0 0 8.67 6.128 6.128 0 0 0 8.67 0 6.128 6.128 0 0 0 0-8.67 6.13 6.13 0 0 0-8.67 0' fill='#9B9B9B'></path>    <path d='M46.868 39.054a6.13 6.13 0 1 0 8.67 8.67l-8.67-8.67z' fill='#C5C5C6'></path>    <path d='M48.364 40.55a4.014 4.014 0 1 0 0 0' fill='#868685'></path>    <path d='M45.106 37.293a8.622 8.622 0 0 1 12.192 0 8.622 8.622 0 0 1 0 12.192 8.622 8.622 0 0 1-12.192 0 8.622 8.622 0 0 1 0-12.192m-.385-.385a9.164 9.164 0 0 0 0 12.962c3.58 3.58 9.385 3.58 12.963 0 3.58-3.578 3.58-9.384 0-12.962a9.164 9.164 0 0 0-12.962 0' fill='#3B3A39'></path>  </g></svg>

Setting transform-origin on SVG group not working in Firefox

I was attempting to rotate a simple cog svg graphic around its centre point using a CSS transition. I had the same problem as you with Firefox; transform-origin seemed to have no effect.

The solution was to draw the original svg shape so that its centre was at coordinate 0, 0:

<svg x="0px" y="0px" width="400px" height="400px" viewBox="0 0 400 400">
<rect id="myObject" x="-50" y="-50" fill="#E52420" width="100" height="100"/>
</svg>

Then add a group around it and translate to the position you want:

<svg x="0px" y="0px" width="400px" height="400px" viewBox="0 0 400 400">
<g transform="translate(150, 100)">
<rect id="myObject" x="-50" y="-50" fill="#E52420" width="100" height="100"/>
</g>
</svg>

Now you can apply css transitions that should work in Firefox (I add a class to the HTML tag using JavaScript based on a user action (js-rotateObject) and use Minimizr to check that the browser can handle transforms and transitions (.csstransforms.csstransitions):

#myObject{
transform: rotate(0deg);
transition: all 1s linear;
}

.csstransforms.csstransitions.js-rotateObject #myObject{
transform: rotate(360deg);
}

Hope that helps.

SVG transform origin differences in FireFox / Chrome

When i used absolute values instead of percentage it worked fine
for instance change transform-origin: 50% 50% to transform-origin: 512px 660px

The working code

See the Pen Just developing by Abdelrahman Ismail (@ismail9k) on CodePen.

Transform origin on SVGs in Firefox

transform-origin with percentage units works from Firefox 43 onwards.

svg transform-origin problems in firefox

Firefox is behaving correctly as per the spec. Chrome implemented transform-origin early before the spec finalised. It handles percentage values differently to what the final spec specified. AFAIK they have not fixed that yet.

If you want your animation to be compatible with all browsers, don't use percentage values in transform-origin.

transform-origin: 3246px 6271px;

http://codepen.io/anon/pen/MbrWod

Is there a way to force Firefox to define the transform origin of an SVG path to be relative to the path itself, rather than the SVG?

Why do SVG paths behave differently than every other HTML element?

Two reasons:

  1. SVG elements are not HTML elements, and are not subject to the same rules.
  2. The defined behaviour is consistent with the way percentage coordinates work elsewhere in SVGs.

A new property called transform-box has been proposed that will allow you to alter the behaviour of transform-origin for both HTML and SVG.

If and when browsers support this new property, you will be able to get behaviour that matches Chrome's current behaviour by using:

transform-box: fill;

FF has already implemented this, but it is not enabled by default yet (AFAIK).

For now, you will need to calculate the centre coordinates yourself. Or, alternatively, rearrange your SVG so that the path is centred on the origin and use a combination of transforms to do your rotation.

For example:

.mypath {  fill: red;  animation: spin 1s linear 0s infinite;}
@-webkit-keyframes spin { from { -webkit-transform: rotate(0deg); } to { -webkit-transform: rotate(360deg); }}@keyframes spin { from {transform:rotate(0deg);} to {transform:rotate(360deg);}}
<svg width="400px" height="400px">  <g transform="translate(200,200)">    <!-- path centred on (0,0) -->    <path d="M -100,-100 L 100,-100 100,100 -100,100 Z" class="mypath"/>  </g></svg>

How can I show the css3 transform-origin property in percent?

See these two examples:

This works in Firefox 11. It just displays the value as percentages:

Firefox (11) Example

This one works for example in the current Chromium, I do the formatting from Pixels to Percentages myself:

Chromium Example

In Chrome 'transform-origin' is invalid?

I've found the origin of my issue.

The problem is that -webkit- browsers don't accept the transform-origin attribute when it is isolated from a supporting attribute (an attribute that actually uses the transform-origin).

So, for example, if I use something like this, -webkit- assumes it is wrong:

#divOne{
transform-origin:50% 50%;
animation:jump 1s ease both;
}
@keyframe jump{
from { transform: translateX(-20%) rotateY(-90deg); }
to{ transform: translateX(0%) rotateY(0deg); }
}

It is wrong because the origin attribute is detached from the transform that is going to take use of it. Even though it works, it is not entirely correct on the browser's perspective.

It should be something like this to be correct:

#divOne{
animation:jump 1s ease both;
}
@keyframe jump{
from { transform: translateX(-20%) rotateY(-90deg); transform-origin:50% 50%; }
to{ transform: translateX(0%) rotateY(0deg); transform-origin:50% 50%; }
}

Where both transforms are together on the same element.

CSS transform-origin having no effect when using translateZ

As pointed out by @JonP, transform-origin is the wrong property to achieve the desired effect. Instead, I need to use perspective-origin on the parent element:

.parent {
perspective: 10000px;
perspective-origin: top;
}
.child {
transform: translateZ(-200px);
}


Related Topics



Leave a reply



Submit