为什么此转换在 Chrome 和 Firefox 上的表现不同?
Why is this transition acting differently on Chrome and Firefox?
我有以下 SVG 动画(这是一个相当大的片段,参见 'Show code snippet'):
.logo > .logo-compass-frame {
fill: none;
stroke: black;
stroke-width: 15;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south {
stroke: black;
stroke-width: 8;
stroke-miterlimit: 10;
}
.logo > .logo-compass-south {
fill: none;
}
.logo > .logo-compass-center {
fill: black;
stroke: black;
stroke-width: 3;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
transition: 0.5s ease-in-out;
opacity: 1;
}
.logo:hover > .logo-compass-north, .logo:hover > .logo-compass-south {
transform-origin: center;
}
.logo:hover > .logo-compass-north {
transform: rotate(90deg) scale(1.5) translate(10px);
}
.logo:hover > .logo-compass-south {
transform: rotate(90deg) scale(1.5) translate(-10px);
}
.logo:hover > .logo-compass-center {
opacity: 0;
}
<svg class="logo" x="0px" y="0px" viewBox="0 0 272.6 272.6">
<circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
<polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
<polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
<circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>
问题是它在 Firefox 上的行为不同(我在 macOS 上没有在 Edge 或 IE 上测试过)。对于 WebKit 浏览器和 Opera,我得到:
Chrome60.0.3112.90:
野生动物园 10.1:
歌剧 47.0.2631.39:
火狐 54.0.1:
发生了一些可疑的事情。我没有尝试过 Edge 或 IE,所以这可能是某种 CSS 规范合规性问题?我想也许 transform-origin
没有得到支持,因为它是一项实验性技术,但添加 -moz-transform-origin
没有任何作用,MDN 报告说 transform-origin
现在受到支持。
为什么过渡在不同的浏览器上表现不同,是否可以解决这个问题?
您现在不能真正为 transform-origin 使用百分比值,因为百分比值在 Chrome 和 Firefox 中的处理方式不同。这也适用于像 "center" 这样的伪值,它被定义为等同于“50%”。
您需要使用绝对像素值而不是跨浏览器兼容。
.logo > .logo-compass-frame {
fill: none;
stroke: black;
stroke-width: 15;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south {
stroke: black;
stroke-width: 8;
stroke-miterlimit: 10;
}
.logo > .logo-compass-south {
fill: none;
}
.logo > .logo-compass-center {
fill: black;
stroke: black;
stroke-width: 3;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
transition: 0.5s ease-in-out;
opacity: 1;
}
.logo:hover > .logo-compass-north {
transform-origin: 138px 99px;
}
.logo:hover > .logo-compass-south {
transform-origin: 138px 173.5px;
}
.logo:hover > .logo-compass-north {
transform: rotate(90deg) scale(1.5) translate(10px);
}
.logo:hover > .logo-compass-south {
transform: rotate(90deg) scale(1.5) translate(-10px);
}
.logo:hover > .logo-compass-center {
opacity: 0;
}
<svg class="logo" x="0px" y="0px" viewBox="0 0 272.6 272.6">
<circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
<polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
<polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
<circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>
更新
我已经弄清楚为什么 Firefox 的行为会有所不同。这不是错误。 Firefox 实际上是正确的。这是因为 Firefox 正确解释了规范,而其他浏览器则没有。
直接原因是我们在:hover
规则中指定了transform-origin
。所以原点也被插值(即移动)。解决方法是:
指定我们只想转换变换属性。
transition: transform 0.5s ease-in-out;
或者将 transform-origin
移出悬停规则。
以下是使用方法 #2 的更新版本。
.logo > .logo-compass-frame {
fill: none;
stroke: black;
stroke-width: 15;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north {
stroke: black;
stroke-width: 8;
transform-origin: 138px 99px;
}
.logo > .logo-compass-south {
stroke: black;
stroke-width: 8;
fill: none;
transform-origin: 138px 173.5px;
}
.logo > .logo-compass-center {
fill: black;
stroke: black;
stroke-width: 3;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
transition: 0.5s ease-in-out;
opacity: 1;
}
.logo:hover > .logo-compass-north {
transform: rotate(90deg) scale(1.5) translate(10px);
}
.logo:hover > .logo-compass-south {
transform: rotate(90deg) scale(1.5) translate(-10px);
}
.logo:hover > .logo-compass-center {
opacity: 0;
}
<svg class="logo" width="300px" viewBox="0 0 272.6 272.6">
<circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
<polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
<polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
<circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>
我有以下 SVG 动画(这是一个相当大的片段,参见 'Show code snippet'):
.logo > .logo-compass-frame {
fill: none;
stroke: black;
stroke-width: 15;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south {
stroke: black;
stroke-width: 8;
stroke-miterlimit: 10;
}
.logo > .logo-compass-south {
fill: none;
}
.logo > .logo-compass-center {
fill: black;
stroke: black;
stroke-width: 3;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
transition: 0.5s ease-in-out;
opacity: 1;
}
.logo:hover > .logo-compass-north, .logo:hover > .logo-compass-south {
transform-origin: center;
}
.logo:hover > .logo-compass-north {
transform: rotate(90deg) scale(1.5) translate(10px);
}
.logo:hover > .logo-compass-south {
transform: rotate(90deg) scale(1.5) translate(-10px);
}
.logo:hover > .logo-compass-center {
opacity: 0;
}
<svg class="logo" x="0px" y="0px" viewBox="0 0 272.6 272.6">
<circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
<polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
<polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
<circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>
问题是它在 Firefox 上的行为不同(我在 macOS 上没有在 Edge 或 IE 上测试过)。对于 WebKit 浏览器和 Opera,我得到:
Chrome60.0.3112.90:
野生动物园 10.1:
歌剧 47.0.2631.39:
火狐 54.0.1:
发生了一些可疑的事情。我没有尝试过 Edge 或 IE,所以这可能是某种 CSS 规范合规性问题?我想也许 transform-origin
没有得到支持,因为它是一项实验性技术,但添加 -moz-transform-origin
没有任何作用,MDN 报告说 transform-origin
现在受到支持。
为什么过渡在不同的浏览器上表现不同,是否可以解决这个问题?
您现在不能真正为 transform-origin 使用百分比值,因为百分比值在 Chrome 和 Firefox 中的处理方式不同。这也适用于像 "center" 这样的伪值,它被定义为等同于“50%”。
您需要使用绝对像素值而不是跨浏览器兼容。
.logo > .logo-compass-frame {
fill: none;
stroke: black;
stroke-width: 15;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south {
stroke: black;
stroke-width: 8;
stroke-miterlimit: 10;
}
.logo > .logo-compass-south {
fill: none;
}
.logo > .logo-compass-center {
fill: black;
stroke: black;
stroke-width: 3;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
transition: 0.5s ease-in-out;
opacity: 1;
}
.logo:hover > .logo-compass-north {
transform-origin: 138px 99px;
}
.logo:hover > .logo-compass-south {
transform-origin: 138px 173.5px;
}
.logo:hover > .logo-compass-north {
transform: rotate(90deg) scale(1.5) translate(10px);
}
.logo:hover > .logo-compass-south {
transform: rotate(90deg) scale(1.5) translate(-10px);
}
.logo:hover > .logo-compass-center {
opacity: 0;
}
<svg class="logo" x="0px" y="0px" viewBox="0 0 272.6 272.6">
<circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
<polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
<polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
<circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>
更新
我已经弄清楚为什么 Firefox 的行为会有所不同。这不是错误。 Firefox 实际上是正确的。这是因为 Firefox 正确解释了规范,而其他浏览器则没有。
直接原因是我们在:hover
规则中指定了transform-origin
。所以原点也被插值(即移动)。解决方法是:
指定我们只想转换变换属性。
transition: transform 0.5s ease-in-out;
或者将
transform-origin
移出悬停规则。
以下是使用方法 #2 的更新版本。
.logo > .logo-compass-frame {
fill: none;
stroke: black;
stroke-width: 15;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north {
stroke: black;
stroke-width: 8;
transform-origin: 138px 99px;
}
.logo > .logo-compass-south {
stroke: black;
stroke-width: 8;
fill: none;
transform-origin: 138px 173.5px;
}
.logo > .logo-compass-center {
fill: black;
stroke: black;
stroke-width: 3;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
transition: 0.5s ease-in-out;
opacity: 1;
}
.logo:hover > .logo-compass-north {
transform: rotate(90deg) scale(1.5) translate(10px);
}
.logo:hover > .logo-compass-south {
transform: rotate(90deg) scale(1.5) translate(-10px);
}
.logo:hover > .logo-compass-center {
opacity: 0;
}
<svg class="logo" width="300px" viewBox="0 0 272.6 272.6">
<circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
<polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
<polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
<circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>