transform:rotateY
を使用してフリップアニメーションを実装したところ、Microfost Edgeで残像が残る現象に遭遇。

この他にも、Edgeでのみアニメーションがぎこちない(滑らかではない)というのもありますが、上述の現象から比べればまだ些事かと。
再現環境
- 現象再現用URL: Perspective Kyoto
<div class="container w-100">
<div class="row">
<div class="col-sm-6 col-md-4 item">
<div class="item_card">
<div class="item_imgWrapper">
<img src="https://placehold.jp/320x320.png" class="d-block mx-auto">
</div>
<div class="item_descWrapper p-lg-4 p-3">
<h4 class="item_descTitle my-3 text-center">irrespective</h4>
<div class="item_description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 item">
<div class="item_card">
<div class="item_imgWrapper">
<img src="https://placehold.jp/320x320.png" class="d-block mx-auto">
</div>
<div class="item_descWrapper p-lg-4 p-3">
<h4 class="item_descTitle my-3 text-center">introspective</h4>
<div class="item_description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 item">
<div class="item_card">
<div class="item_imgWrapper">
<img src="https://placehold.jp/320x320.png" class="d-block mx-auto">
</div>
<div class="item_descWrapper p-lg-4 p-3">
<h4 class="item_descTitle my-3 text-center">inspective</h4>
<div class="item_description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
</div>
</div>
</div>
こんなHTMLで、
@charset "utf-8";
.item {
padding-bottom: 30px;
}
.item img {
width: 100%;
height: auto;
border-radius: 0;
}
.item_imgWrapper, .item_descWrapper {
width: 100%;
height: 100%;
transition: 0.8s;
position: absolute;
top: 0;
left: 0;
backface-visibility: hidden;
}
.item_imgWrapper {
transform: rotateY(0);
}
.item_descWrapper {
transform: rotateY(180deg);
background-color: #4c4c4c;
color: #fff;
}
.item_descTitle {
font-weight: normal;
}
.item_card {
width: 100%;
height: auto;
position: relative;
cursor: e-resize;
perspective: 100rem;
transition: 0.3s ease-out;
}
.item_card::before {
content: "";
display: block;
padding-top: 100%;
}
.item_card:hover .item_imgWrapper, .item_card.activeClick .item_imgWrapper {
transform: rotateY(-180deg);
}
.item_card:hover .item_descWrapper, .item_card.activeClick .item_descWrapper {
transform: rotateY(0);
}
こんなcssを記述したところ、発生。
原因
原因はcssのperspective
の指定のようです。
.item_card {
/* 略 */
perspective: 100rem;
/* 略 */
}
サンプルコードだと上述の部分ですね。
この部分を削ると現象は発生しなくなりました。ただし、奥行きがなくなるのでフリップアニメーションの回転が平面的になってしまいます。
対処
- 対処確認URL: Perspective Kyoto
bowserを使って「Edge以外のブラウザの場合のみperspective
を指定する(=Edgeではperspective
を指定しない)」ということで対処しました。
「原因」のところでも記述した通りフリップアニメーションの奥行きは犠牲になりますが、その影響範囲をEdgeのみとなるべく絞った形になります。
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://unpkg.com/bowser@2.7.0/es5.js"></script>
<script src="./js/index.js"></script>
HTMLはbowserの読み込みと判定のスクリプトを追加。
$(() => {
const browser = bowser.getParser(window.navigator.userAgent);
const $body = $("body");
if (browser.getBrowserName().indexOf('Edge') > -1) {
//Edgeならば
$body.addClass("msEdge");
}
});
jQueryでサクッとbody
タグにmsEdge
クラスを付与するスクリプトを記述。
.item_card {
width: 100%;
height: auto;
position: relative;
cursor: e-resize;
transition: 0.3s ease-out;
}
body:not(.msEdge) .item_card {
/* Edgeでない場合のみ付与 */
perspective: 100rem;
}
cssは親セレクタにbody:not(.msEdge)
を記述することで、JavaScriptの記述と併せて「Edgeではない場合」と絞った形になります。
備考1 (Edgeの行く末)
- ASCII.jp:Chromeと同じエンジンのEdge、正式版の来年1月配信を前に開発版の機能を見る (1/2)|Windows Info
- Chromiumベースの Microsoft Edgeブラウザー RC版公開。正式リリースは2020年1月15日予定 – Engadget 日本版
Microsoft Edgeは上述記事の通り来月(2020/1/15)にレンダリングエンジンをChromiumに変更したバージョンをリリース予定にしており、レンダリングエンジンがEdgeHTMLである現行バージョン特有のバグはなくなると思われます(事実、dev版のEdgeでは今回の症状は発生しませんでした)。
したがって、あと1ヶ月足らずで変更されるものについて今更感がある(大掛かりな対応はしたくない)のですが、今回はこれで。
備考2 (css, 可変幅・高さの親要素に子要素をposition:absolute;
指定して親要素の高さが潰れた場合の対処法)
上述のコードでさらっと使っているのですが、今回のカードはBootstrap4のグリッドに則っているのでカードの幅と高さは可変になっています。
このカードにアニメーションのためposition: absolute;
を指定すると親要素の高さが潰れてしまいます。
対処法が上述の記事。
.item_imgWrapper, .item_descWrapper {
/* 略 */
position: absolute;
top: 0;
left: 0;
/* 略 */
}
.item_card {
width: 100%;
height: auto;
position: relative;
/* 略 */
}
.item_card::before {
/* 潰れた高さを戻す */
content: "";
display: block;
padding-top: 100%;
}
今回はこのような使い方をしました。