首页 > 解决方案 > 在 Chrome 中裁剪 3D CSS 元素或在 Firefox 中根本没有 3D

问题描述

在我的纸牌游戏项目中,如果添加了以下 CSS,则会在 Chrome 中裁剪地图中的 CSS 元素(卡片):

.state { transform-style: preserve-3d; }

但是如果没有这个 CSS,菜单中的 3D 视差在 Firefox 中根本不起作用。

由于这个问题不容易重现,我将提供代码、相关 CSS 和 HTML 结构的最小解释。

完整代码可以在 Github https://github.com/rafaelcastrocouto/foda上找到,整个过程在这里https://foda-app.herokuapp.com/

我知道这是浏览器中不同实现的结果,我不是在寻找深入的解释,而只是寻找一种让它在 Firefox 和 Chrome 中工作的方法。

/* on 'body' mousemove change '.states' perspective-origin */
/* on '.card.skill' mousemove toggle '.map .card' className 'highlight' */
body, html {
  user-select: none;
  -webkit-user-select: none;
  margin: 0;
  width: 100%;
  height: 100%;
  min-width: 485px;
  min-height: 300px;
}

body {
  background-attachment: fixed;
  background-color: #22272c;
  background: radial-gradient(ellipse farthest-corner at center top,#6e7a66 0,#343b43 30%,#22272c 60%,#22272c 100%),#22272c;
  background-size: 100% 20%;
  background-repeat: no-repeat;
  box-shadow: 0 -50px 100px rgba(0,0,0,.7) inset;
  -webkit-tap-highlight-color: transparent;
  -webkit-tap-highlight-color: transparent;
  backface-visibility: hidden;
}
.container, .states {
  background-size: cover;
  overflow: hidden;
}
.container {
  top: 50%;
  left: 50%;
  transform: translate3d(-50%,-50%,0);
  color: #fff;
  background-position: 50%;
  background-color: #859890;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  image-rendering: optimizeSpeed;
  will-change: transform;
}
.container, .container:after, .state, .states {
  width: 970px;
  height: 600px;
  position: absolute;
}
.container:after {
  content: "";
  display: block;
  pointer-events: none;
  top: -2px;
  left: -2px;
  border: 2px solid #000;
}
.states {
  animation: persp 20s infinite;
}

.state, .states {
  top: 0;
  left: 0;
}
.states {
  transform: translate3d(0,0,1px);
  perspective: 600px;
  transform-style: preserve-3d;
  image-rendering: auto;
  perspective-origin: 50% 50%;
  will-change: perspective-origin;
}
.table .camera {
  position: absolute;
  top: 45px;
  left: 0;
  width: 718px;
  height: 450px;
  perspective: 800px;
  perspective-origin: 57% 50%;
  overflow: hidden;
  transform: translateZ(0);
  background-repeat: no-repeat;
  background-color: rgba(0,0,0,.5);
}
.table .map {
  z-index: 0;
  transform: translate(-49.7%,-50.6%) rotateX(32deg) scale3d(.21,.21,.21);
  transform-style: preserve-3d;
  padding: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transition: all 2s;
}
.map .spot {
  width: 200px;
  height: 300px;
  position: relative;
  border: 6px solid rgba(0,0,0,.1);
  border-radius: 6px;
  display: inline-block;
  transform: translate3d(0,0,1px);
  transform-style: preserve-3d;
  transition: all .3s,filter 2s,-webkit-filter 2s;
}
.map .row {
  height: 312px;
}
.states .table .map .card {
  position: absolute;
  z-index: 3;
  top: 50%;
  left: 50%;
  transform: translate3d(-50%,-50%,2px);
  transform-style: preserve-3d;
}
.card.trees, .card.trees .portrait {
  background-color: #5ba22f;
}
.card {
  position: relative;
  display: inline-block;
  text-align: left;
  transition: all .3s;
  padding: 0;
  width: 200px;
  height: 300px;
  border-radius: 8px;
  z-index: 1;
  color: #4d4843;
  cursor: pointer;
  transform: translateZ(0);
  transform-style: preserve-3d;
  background: #898;
  will-change: transform;
}
.menu .background {
  transform: translateZ(-150px) scale(1.3);
  background-size: 970px 405px;
  background-position: 0 0;
  background-repeat: no-repeat;
}
.menu.paralax {
  height: 600px;
  width: 970px;
  background-size: 100%;
  background-position: 50% 50%;
  position: absolute;
}
.menu .front {
  transform: scale(.25) translate3d(-1070px,720px,140px);
}
<html>
  <body>
    <div class="container">
      <div class="states">
        <div class="state menu">
          <div class="parallax">
            <div class="background"></div>
            <div class="ground">
              <div class="icon single"></div>
              <div class="icon online"></div>
            </div>
            <div class="front"></div>
          </div>
        </div>
        <div class="state table">
          <div class="decks player">
            <div class="hand">
              <div class="card skill"></div>
              <div class="card skill"></div>
            </div>
          </div>
          <div class="camera">
            <div class="map">
              <div class="row">
                <div class="spot">
                  <div class="card hero"></div>
                </div>
                <div class="spot">
                  <div class="card trees"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

标签: javascriptcss

解决方案


perspective我可以通过为每个视差场景创建单独的容器来解决此问题,而不是将它们全部放在states具有单个控件的 div 下。

所以基本上不是:

 /* on 'body' mousemove change '.states' perspective-origin */

现在我在做:

 /* on 'body' mousemove change '.current.state .parallax' perspective-origin */

它适用于 Chrome 和 Firefox,无需裁剪。当然,.state { transform-style: preserve-3d; }根本不需要。


推荐阅读