I've meet a render problem about transform 3D.
On the chrome(PC/Mac), it looks like below.
But on mobile, safari or chrome, I got below.
When I use only the transform 2D, this won't happen on mobile.
code here.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=0.5, user-scalable=no, minimum-scale=0.5, maximum-scale=0.5">
<meta name="format-detection" content="telephone=no">
<title>MIXER</title>
<style type="text/css">
html,
body {
height: 100%;
margin: 0 auto;
max-width: 750px;
position: relative;
font: 32px/40px sans-serif;
text-align: center;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
transition: background .5s;
}
* {
box-sizing: border-box;
}
*::-webkit-scrollbar {
display: none;
}
#canvas {
background: #FFF;
padding: 10%;
position: relative;
margin-bottom: 20px;
}
#canvas>div {
position: absolute;
outline: 1px solid transparent;
border: 2px solid #FFF;
}
</style>
<body>
<div id="canvas" style="height: 750px;">
<div id="0" style="width: 200px; height: 200px; line-height: 200px; top: 125px; left: 75px; background: rgb(236, 69, 69); color: rgb(0, 0, 0); font-size: 85px; font-weight: 300; font-family: fantasy; z-index: 100; transform: perspective(500px) rotateX(-10deg) rotateY(-20deg) rotateZ(5deg) scale3d(1, 1, 1) translate3d(20px, 38px, -3px);">1</div>
<div id="1" style="width: 200px; height: 200px; line-height: 200px; top: 125px; left: 275px; background: rgb(48, 46, 62); color: rgb(255, 255, 255); font-size: 104px; font-family: monospace; z-index: 500; transform: perspective(500px) rotateX(-8deg) rotateY(19deg) rotateZ(-9deg) scale3d(1, 1, 1) translate3d(-20px, 4px, 2px);">2</div>
</div>
</body>
</html>
I've tried adjust the z-index, but not work.
And tried adjust the translateZ, but because of the perspective, the cards will look too big or too small.
The result I'm doing is split letters in many cards, like this.
It's random and many, so adjust the translateZ maybe not a good way.
PS: I found a interest thing is, in mobile safari, the surface looks crossed, but if you press the bottom right button, it will start an animation, in that short animate moment, the surface is not crossed.
I think maybe on PC, the browser draw the div one by one, but on mobile, it looks all the 3D elements are in one layer and render once? but how to explain the above situation in safari animation?
Save my poor mobile view.
You should use prefixes in your CSS to make the transform understood well by browsers like template below
-webkit-transform: translate(-100%, 0);
-moz-transform: translate(-100%, 0);
-ms-transform: translate(-100%, 0);
-o-transform: translate(-100%, 0);
transform: translate(-100%, 0);
-webkit-transition: -webkit-transform 1s ease-in;
-moz-transition: -moz-transform 1s ease-in;
-o-transition: -o-transform 1s ease-in;
transition: transform 1s ease-in;
You have then to adapt this sample to your situation.
Related
So i made a simple button with a perspective pseudo element that flips on hover.
This works perfectly well on android and pc, but on iphone/ipad the text is only visible in the upper half.
Also tried adding a span for the text and position it above the stack, same result.
Does anyone know how to fix this?
Couldn't find a similar question on stack so far, but should be fixable i reckon.......
PS: i use scss, so it converts including -webkit and other variants..
This is how it looks on appetize.io (and real iphone):
.btn {
position: relative;
display: inline-block;
cursor: pointer;
padding: 12px 20px;
margin: 10px 10px;
text-decoration: none;
-webkit-perspective: 500px;
perspective: 500px;
color: #fff;
-webkit-transition: all .4s ease-in;
transition: all .4s ease-in;
z-index: 10;
line-height: 20px;
overflow: visible;
}
.btn:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: #f00;
border-radius: 12px;
left: 0;
-webkit-perspective: 500px;
perspective: 500px;
-webkit-transform: translateY(-50%) rotateX(45deg);
transform: translateY(-50%) rotateX(45deg);
min-height: 20px;
top: 50%;
z-index: -10;
-webkit-transition: all .4s ease-out;
transition: all .4s ease-out
}
.btn:hover:after {
color: #fff;
-webkit-transform: translateY(-50%) rotateX(-135deg);
transform: translateY(-50%) rotateX(-135deg);
background-color: #000
}
<div class="btn">this is unreadable on ios?</div>
The text is properly aligned in Chrome but as it goes in Safari the text messes up its position and touches the top of the container (text container)
Chrome: Chrome view
Safari: Safari view
As you can see in Safari, the text container (span) has its proper size but the text inside is touching the roof. I've tried things to solve this by messing the height, line height, position, etc but still no luck.
The current approach used in the image is I've made the span position absolute and align it in the center and it (span) is in the center but the text is not being aligned vertically. (Also tried the vertical-align property but no luck)
Are there any fix/workarounds for this?
Tech Stack: Gatsby with Tailwind + Modular sass
.linkButton {
padding-right: 30px;
padding-left: 8px;
position: relative;
background-color: rgb(85, 85, 85);
transition: 0.25s all ease-in-out;
display: flex;
line-height: 36px;
width: 180px;
min-height: 35px;
.text {
transition: 0.25s all ease-in-out;
height: 20px;
line-height: 20px;
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
&::after {
content: "";
background-color: #fff;
height: 12px;
width: 9px;
position: absolute;
top: 50%;
right: 9px;
transform: translateY(-50%);
clip-path: polygon(0 0, 100% 50%, 0 100%);
transition: 0.25s all ease-in-out;
z-index: 10;
}
&::before {
height: 100%;
width: 100%;
content: "";
position: absolute;
background-image: linear-gradient(to right, #4100a3 0%, #0d52ff 100%);
top: 0px;
left: 0px;
z-index: 5;
opacity: 0;
transition: 0.25s all ease-in-out;
}
&:hover {
width: 185px;
cursor: pointer;
.text {
transform: translate(4%, -50%);
-webkit-transform: translate(4%, -50%);
}
&::after {
transform: scale(1.25) translateY(-40%);
}
&::before {
opacity: 1;
}
}
}
<a href="/features">
<div class="index-module--linkButton--3DaPN mt-3 md:mt-12 mx-auto md:mx-0 flex items-center justify-center text-white">
<span class="index-module--text--QcmPb z-10">View all Features</span>
</div>
</a>
Solved! The issue was with font rendering as it differs between browsers, not some line-height issue...
This resolved my issue: Font Rendering / Line-Height Issue on Mac/PC (outside of element)
Final Edit: I've found the test website on the course. Chrome renders really weird on start. Safari, Firefox, IE works fine. I guess this is about Chrome after all. Don't know that I can do about it. Here is the test website if you want to try it yourself: https://natours.netlify.app/
I was following a course on Udemy and I've noticed that my button flashes on reload, but only does this on Chrome. What might be the reason for this? I don't think it's code related since it works fine on Edge, IE and Firefox.
Edit: Here are the HTML and CSS files. I tried opening the HTML file itsel/using express to server it, still makes no difference.
/*
COLORS:
Light green: #7ed56f
Medium green: #55c57a
Dark green: #28b485
color: #fc5764
anothercolor #fa78ca
*/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Lato", sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 1.7;
color: #777;
padding: 30px;
overflow-x: hidden;
}
.header {
height: 95vh;
background-image: linear-gradient( to right, rgba(126, 213, 111, 0.8), rgba(40, 180, 133, 0.8)), url(../img/hero.jpg);
background-size: cover;
background-position: top;
position: relative;
clip-path: polygon(0 0, 100% 0, 100% 70vh, 0 100%);
}
.logo-box {
position: absolute;
top: 40px;
left: 40px;
}
.logo {
height: 35px;
}
.text-box {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.heading-primary {
color: #fff;
text-transform: uppercase;
backface-visibility: hidden;
margin-bottom: 60px;
}
.heading-primary-main {
display: block;
font-size: 60px;
font-weight: 400;
letter-spacing: 35px;
animation-name: moveInLeft;
animation-duration: 1s;
animation-timing-function: ease-out;
}
.heading-primary-sub {
display: block;
font-size: 20px;
font-weight: 700;
letter-spacing: 17.4px;
animation-name: moveInRight;
animation-duration: 1s;
animation-timing-function: ease-out;
}
#keyframes moveInLeft {
0% {
opacity: 0;
transform: translateX(-100%);
}
80% {
transform: translateX(10px);
}
100% {
opacity: 1;
transform: translateX(0%);
}
}
#keyframes moveInRight {
0% {
opacity: 0;
transform: translateX(100%);
}
80% {
transform: translateX(-10px);
}
100% {
opacity: 1;
transform: translateX(0%);
}
}
#keyframes moveInBottom {
0% {
opacity: 0;
transform: translateY(100%);
}
100% {
opacity: 1;
transform: translateY(0%);
}
}
.btn:link,
.btn:visited {
text-transform: uppercase;
text-decoration: none;
padding: 15px 40px;
display: inline-block;
border-radius: 100px;
transition: all .2s;
position: relative;
backface-visibility: hidden;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
.btn:active {
transform: translateY(-1px);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.btn-white {
background-color: #fff;
color: #777
}
.btn::after {
content: "";
display: inline-block;
height: 100%;
width: 100%;
border-radius: 100px;
position: absolute;
top: 0;
left: 0;
z-index: -1;
transition: all .4s;
}
.btn-white::after {
background-color: #fff;
}
.btn:hover::after {
transform: scaleX(1.4) scaleY(1.6);
opacity: 0;
}
.btn-animated {
animation-name: moveInBottom;
animation-duration: 1s;
animation-timing-function: ease-out;
animation-fill-mode: backwards;
}
<link href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700,900" rel="stylesheet">
<header class="header">
<div class="logo-box">
<img src="img/logo-white.png" alt="Logo" class="logo">
</div>
<div class="text-box">
<h1 class="heading-primary">
<span class="heading-primary-main">Outdoors</span>
<span class="heading-primary-sub">is where life happens</span>
</h1>
Discover our tours
</div>
</header>
Possible issue
clip-path: polygon(0 0, 100% 0, 100% 70vh, 0 100%);
clip-path works with %, I didn't find anything about vh support.
Each browser user agent can solve this problem in a different way
Apperently, it's a bug in latest version of Chrome. Adding a dummy script tag right after the body fixes it.
<body>
<script>0</script>
...content...
</body>
css animation transform: rotate3d is working fine in chrome but in firefox and IE11. Its just moving from left to right onmousever in firefox but not flipping like how its working chrome and opera.
.box {
width: 100px;
height: 50px;
float: left;
background: #007bff;
text-align: center;
color: white;
font-size: 20px;
padding-top: 35px;
position: relative;
transition: 0.5s;
}
.box:hover {
transform: rotate3d(-10, -10, 1, 360deg) translate3d(100px, 0px, 0px);
transition: 0.5s;
}
<div class="box">
Hi!
</div>
Apply to the base state a similar transform, but with the rotation and translation set to zero: (tested only in FF)
.box {
width: 100px;
height: 50px;
float: left;
background: #007bff;
text-align: center;
color: white;
font-size: 20px;
padding-top: 35px;
position: relative;
transition: 0.5s;
transform: rotate3d(-10, -10, 1,0deg) translate3d(0px, 0px, 0px);
}
.box:hover {
transform: rotate3d(-10, -10, 1, 360deg) translate3d(100px, 0px, 0px);
}
<div class="box">
Hi!
</div>
I am learning CSS transitions and transformations. here is HTML:
<!DOCTYPE html>
<html>
<head>
<title> Transformatons and Transitions</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/n.css">
</head>
<body>
<div class="animate">animate</div>
<div class="animate">animate2</div>
<div class="different">different1</div>
<div class="different">different2</div>
</body>
</html>
and the CSS is:
div.different {
transform: translate(1000px,400px);
border-style: solid;
padding: 25px;
background-color: yellow;
display: block;
width: 125px;
transition:1s ease-in-out;
}
div.different:hover{
background-color: red;
-webkit-transform: rotate(300deg);
}
The rotate is not working properly. instead of just rotating, the element is moving back the original place it was. Instead of staying at (1000px,400px) the element is going back to (0px,0px)
How do I prevent its moving?
You have to use translate on hover too because browser interpret your hover transform as translate(0,0) rotate(300deg):
div.different {
-webkit-transform: translate(1000px, 400px);
-ms-transform: translate(1000px, 400px);
transform: translate(1000px, 400px);
border-style: solid;
padding: 25px;
background-color: yellow;
display: block;
width: 125px;
transition: 1s ease-in-out;
}
div.different:hover {
background-color: red;
-webkit-transform: translate(1000px, 400px) rotate(300deg);
-ms-transform: translate(1000px, 400px) rotate(300deg);
transform: translate(1000px, 400px) rotate(300deg);
}
Define both transformations in the same statement and change them accordingly:
div.different {
transform: rotate(0deg) translate(1000px,400px);
border-style: solid;
padding: 25px;
background-color: yellow;
display: block;
width: 125px;
transition:1s ease-in-out;
}
div.different:hover{
background-color: red;
-webkit-transform: rotate(300deg) translate(1000px,400px);
}
Fiddle: https://jsfiddle.net/quvLtwjt/1/
You were overriding the previous transform.
But, if you want to rotate the div from the current position and not the old position then you need to use transform-origin to redefine the new position and put both transformations in the same statement:
div.different {
transform: rotate(0deg) translate(1000px,400px);
border-style: solid;
padding: 25px;
background-color: yellow;
display: block;
width: 125px;
transition:1s ease-in-out;
transform-origin: 1000px 400px;
}
div.different:hover{
background-color: red;
-webkit-transform: rotate(300deg) translate(1000px,400px);
}
Fiddle: https://jsfiddle.net/quvLtwjt/