SayJeyHi
SayJeyHi

Reputation: 1841

Css transform in another transformed element

I am making some 3D translated card , which has image and title on it, the whole card has transform: rotateX(Xdeg) rotateY(Ydeg) , and working correctly with mouseover and mousemove.

The problem occurred when I want to add translate3d to title or button on the card , when mouse enter on card , translate3d will not work !

I use transform in another transformed element before, but it seems did not work when it applies on inline element style attribute(!), as I use js to produce inline transform style on .card-beautiful

 // https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/


(function() {
  // Init
  var container = document.getElementById("container"),
      inner = document.querySelector(".beatiful-card");

  // Mouse
  var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function(event) {
      var e = event || window.event;
      this.x = e.clientX - this._x;
      this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function(e) {
      this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
      this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
    },
    show: function() {
      return "(" + this.x + ", " + this.y + ")";
    }
  };

  // Track the mouse position relative to the center of the container.
  mouse.setOrigin(container);

  //----------------------------------------------------

  var counter = 0;
  var refreshRate = 10;
  var isTimeToUpdate = function() {
    return counter++ % refreshRate === 0;
  };

  //----------------------------------------------------

  var onMouseEnterHandler = function(event) {
    update(event);
  };

  var onMouseLeaveHandler = function() {
    inner.style = "";
  };

  var onMouseMoveHandler = function(event) {
    if (isTimeToUpdate()) {
      update(event);
    }
  };

  //----------------------------------------------------

  var update = function(event) {
    mouse.updatePosition(event);
    updateTransformStyle(
      (mouse.y / inner.offsetHeight / 2).toFixed(2),
      (mouse.x / inner.offsetWidth / 2).toFixed(2)
    );
  };

  var updateTransformStyle = function(x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg) perspective(1.1px)";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTranform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
  };

  //--------------------------------------------------------

  container.onmousemove = onMouseMoveHandler;
  container.onmouseleave = onMouseLeaveHandler;
  container.onmouseenter = onMouseEnterHandler;
})();
html, body {
  width: 100%;
  height: 100%;
}

body {
  width: 100%;
  min-height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f1f1f1;
  display: flex;
  justify-content: center;
  align-items: center;
}

#container {
  perspective: 25px;
}

.beatiful-card {
  display: flex;
  width: 400px;
  height: 250px;
  position: relative;
  border-radius: 20px;
  background: #fff;
  transition: transform 0.5s;
  -webkit-transition: transform 0.5s;
  box-shadow: 0 30px 35px -14px rgba(111, 208, 50, 0.58);
}
.beatiful-card:after, .beatiful-card:before {
  content: " ";
  position: absolute;
  bottom: -13px;
  left: 10px;
  right: 10px;
  margin: 0 5px;
  background: #b8bd8d4f;
  z-index: -3;
  height: 13px;
  border-bottom-left-radius: 14px;
  border-bottom-right-radius: 14px;
}
.beatiful-card:after {
  background: rgba(184, 189, 141, 0.25);
  height: 21px;
  bottom: -22px;
  right: 25px;
  left: 25px;
}
.beatiful-card .images {
  position: absolute;
  right: 0;
  top: 0;
  overflow: hidden;
  width: 55%;
  height: 100%;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
}
.beatiful-card .images img {
  width: 100%;
  filter: sepia(40%);
  height: 100%;
}
.beatiful-card .holderPart {
  position: relative;
  width: 45%;
}
.beatiful-card .holderPart svg {
  position: absolute;
  transform: rotate(270deg);
  left: 83%;
  top: 0;
  height: 100%;
  width: auto;
  z-index: 0;
}
.beatiful-card .holderPart .title {
  font-size: 22px;
  padding: 0 16px;
  font-family: "Roboto", tahoma, sans-serif;
  display: block;
  transition: -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
  transition: transform 0.4s ease, filter 0.4s ease;
  transition: transform 0.4s ease, filter 0.4s ease, -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
  -webkit-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  -webkit-transform: translate3d(0, 0, 1px);
  transform: translate3d(0, 0, 1px);
}
.beatiful-card .holderPart .callToActionButton {
  -webkit-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  -webkit-transform: translate3d(0, 0, 1px);
  transform: translate3d(0, 0, 1px);
  color: #fff;
  padding: 12px 11px 12px 24px;
  background: #978ed3;
  border-radius: 20px;
  font-family: "Roboto", tahoma, sans-serif;
  cursor: pointer;
  box-shadow: 0 6px 14px -4px rgba(54, 55, 149, 0.42);
  display: block;
  position: relative;
  left: 17px;
  top: 4px;
}
.beatiful-card .holderPart .callToActionButton:hover {
  background: #8378ca;
}
.beatiful-card .holderPart .callToActionButton:hover i {
  transform: scale(1.08);
}
.beatiful-card .holderPart .callToActionButton i {
  background: rgba(0, 0, 0, 0.5);
  font-family: Material-Design-Iconic-Font;
  padding: 9px 10px 8px 10px;
  float: right;
  border-radius: 100%;
  position: relative;
  transition: transform ease-in-out 0.3s;
  top: -7px;
  right: -6px;
}
.beatiful-card .holderPart p {
  height: 98px;
  overflow-y: hidden;
  text-overflow: ellipsis;
  font-weight: 200;
  padding: 0 16px;
  font-family: "Roboto", tahoma, sans-serif;
  font-size: 14px;
  position: relative;
  z-index: 1;
}
.beatiful-card .holderPart p:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 70%;
  height: 1.2em;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%);
}
<div id="container">
  <div class="beatiful-card">
    <div class="images"><img class="mainImage" src="https://rukminim1.flixcart.com/image/832/832/jbs96kw0/carpet-rug/v/3/f/carpetblu-03-supreme-home-collective-original-imaewgneqxtsvgfr.jpeg?q=70"/></div>
    <div class="holderPart">
      <h3 class="title">MyCode</h3>
      <p class="description">Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</p>
      <svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
        <path d="M0,100 C150,200 350,0 500,100 L500,00 L0,0 Z" style="stroke: none; fill:#fff;"></path>
      </svg>
      <div class="callToActionButton">Hi , Jeffreson<i class="zmdi zmdi-favorite"></i></div>
    </div>
  </div>
</div>

Code on Codepen. [sass and pug]

Upvotes: 0

Views: 1088

Answers (1)

Temani Afif
Temani Afif

Reputation: 272592

You need to add transform-style: preserve-3d; and remove the perspective you are adding at the end of the dynamic transform. It's useless since it's at the end.

The perspective defined in the container is already doing the job.

// https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/


(function() {
  // Init
  var container = document.getElementById("container"),
      inner = document.querySelector(".beatiful-card");

  // Mouse
  var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function(event) {
      var e = event || window.event;
      this.x = e.clientX - this._x;
      this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function(e) {
      this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
      this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
    },
    show: function() {
      return "(" + this.x + ", " + this.y + ")";
    }
  };

  // Track the mouse position relative to the center of the container.
  mouse.setOrigin(container);

  //----------------------------------------------------

  var counter = 0;
  var refreshRate = 10;
  var isTimeToUpdate = function() {
    return counter++ % refreshRate === 0;
  };

  //----------------------------------------------------

  var onMouseEnterHandler = function(event) {
    update(event);
  };

  var onMouseLeaveHandler = function() {
    inner.style = "";
  };

  var onMouseMoveHandler = function(event) {
    if (isTimeToUpdate()) {
      update(event);
    }
  };

  //----------------------------------------------------

  var update = function(event) {
    mouse.updatePosition(event);
    updateTransformStyle(
      (mouse.y / inner.offsetHeight / 2).toFixed(2),
      (mouse.x / inner.offsetWidth / 2).toFixed(2)
    );
  };

  var updateTransformStyle = function(x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg) ";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTranform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
  };

  //--------------------------------------------------------

  container.onmousemove = onMouseMoveHandler;
  container.onmouseleave = onMouseLeaveHandler;
  container.onmouseenter = onMouseEnterHandler;
})();
html, body {
  width: 100%;
  height: 100%;
}

body {
  width: 100%;
  min-height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f1f1f1;
  display: flex;
  justify-content: center;
  align-items: center;
}

#container {
  perspective: 25px;
}

.beatiful-card {
  display: flex;
  width: 400px;
  height: 250px;
  position: relative;
  border-radius: 20px;
  background: #fff;
  transition: transform 0.5s;
  -webkit-transition: transform 0.5s;
  box-shadow: 0 30px 35px -14px rgba(111, 208, 50, 0.58);
  transform-style: preserve-3d;
}
.beatiful-card:after, .beatiful-card:before {
  content: " ";
  position: absolute;
  bottom: -13px;
  left: 10px;
  right: 10px;
  margin: 0 5px;
  background: #b8bd8d4f;
  z-index: -3;
  height: 13px;
  border-bottom-left-radius: 14px;
  border-bottom-right-radius: 14px;
}
.beatiful-card:after {
  background: rgba(184, 189, 141, 0.25);
  height: 21px;
  bottom: -22px;
  right: 25px;
  left: 25px;
}
.beatiful-card .images {
  position: absolute;
  right: 0;
  top: 0;
  overflow: hidden;
  width: 55%;
  height: 100%;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
}
.beatiful-card .images img {
  width: 100%;
  filter: sepia(40%);
  height: 100%;
}
.beatiful-card .holderPart {
  position: relative;
  width: 45%;
}
.beatiful-card .holderPart svg {
  position: absolute;
  transform: rotate(270deg);
  left: 83%;
  top: 0;
  height: 100%;
  width: auto;
  z-index: 0;
}
.beatiful-card .holderPart .title {
  font-size: 22px;
  padding: 0 16px;
  font-family: "Roboto", tahoma, sans-serif;
  display: block;
  transition: -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
  transition: transform 0.4s ease, filter 0.4s ease;
  transition: transform 0.4s ease, filter 0.4s ease, -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
  -webkit-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  -webkit-transform: translate3d(0, 0, 1px);
  transform: translate3d(0, 0, 1px);
}
.beatiful-card .holderPart .callToActionButton {
  -webkit-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  -webkit-transform: translate3d(0, 0, 1px);
  transform: translate3d(0, 0, 1px);
  color: #fff;
  padding: 12px 11px 12px 24px;
  background: #978ed3;
  border-radius: 20px;
  font-family: "Roboto", tahoma, sans-serif;
  cursor: pointer;
  box-shadow: 0 6px 14px -4px rgba(54, 55, 149, 0.42);
  display: block;
  position: relative;
  left: 17px;
  top: 4px;
}
.beatiful-card .holderPart .callToActionButton:hover {
  background: #8378ca;
}
.beatiful-card .holderPart .callToActionButton:hover i {
  transform: scale(1.08);
}
.beatiful-card .holderPart .callToActionButton i {
  background: rgba(0, 0, 0, 0.5);
  font-family: Material-Design-Iconic-Font;
  padding: 9px 10px 8px 10px;
  float: right;
  border-radius: 100%;
  position: relative;
  transition: transform ease-in-out 0.3s;
  top: -7px;
  right: -6px;
}
.beatiful-card .holderPart p {
  height: 98px;
  overflow-y: hidden;
  text-overflow: ellipsis;
  font-weight: 200;
  padding: 0 16px;
  font-family: "Roboto", tahoma, sans-serif;
  font-size: 14px;
  position: relative;
  z-index: 1;
}
.beatiful-card .holderPart p:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 70%;
  height: 1.2em;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%);
}
<div id="container">
  <div class="beatiful-card">
    <div class="images"><img class="mainImage" src="https://rukminim1.flixcart.com/image/832/832/jbs96kw0/carpet-rug/v/3/f/carpetblu-03-supreme-home-collective-original-imaewgneqxtsvgfr.jpeg?q=70"/></div>
    <div class="holderPart">
      <h3 class="title">MyCode</h3>
      <p class="description">Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</p>
      <svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
        <path d="M0,100 C150,200 350,0 500,100 L500,00 L0,0 Z" style="stroke: none; fill:#fff;"></path>
      </svg>
      <div class="callToActionButton">Hi , Jeffreson<i class="zmdi zmdi-favorite"></i></div>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions