I just stumbled upon a very strange behavior when working with transform: translate3d().
As long as I use only the translate3d() property everything works exactly as translate(). But if I combine the this with scale3d() the behavior changes.
See the attached exmple to see whats happening.
Why are the results different? Anyone any idea?
.wrapper {
margin-top:10px;
display:flex;
width: 650px;
justify-content: space-between;
box-shadow: 0px -30px 0px black inset;
}
.translate,
.translate3d,
.translatey {
width: 30%;
height: 100px;
font-size: 24pt;
}
.translate {
will-change: transform, scale;
transform: scale(0.75) translate(0px, -22.5px);
background-color:lightcoral;
}
.translate3d {
transform: translate3d(0, -22.5px, 0) scale3d(0.75, 0.75, 0.75);
background-color:lightblue;
}
.translatey {
transform: scale(0.75) translateY(-22.5px);
background-color:springgreen;
}
<div class="wrapper">
<div class="translate">
translate
</div>
<div class="translate3d">
translate3d
</div>
<div class="translatey">
translatey
</div>
</div>
Related
I should think that as the content behind a backdropped element moves, the element's background color adapts to appear as if the content was shining through it. In this example, it's not the case:
What's wrong? Tested this on Safari 12.0.3, macOS Mojave 10.14.3.
.container {
width: 100%;
height: 150px;
overflow-y: scroll;
}
.block {
height: 50px;
margin: 10px;
}
.block:nth-child(1) {
margin-top: 30px;
background-color: red;
}
.block:nth-child(2) {
background-color: green;
}
.block:nth-child(3) {
background-color: blue;
}
.glass {
position: absolute;
background-color: rgba(255, 255, 255, 0.3);
top: 0;
width: 25%;
border: 1px solid black;
height: 100%;
}
.clear {
left: 55%;
}
.frosted {
left: 20%;
background-color: rgba(255, 255, 255, 0.5);
-webkit-backdrop-filter: blur(20px);
backdrop-filter: blur(20px);
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
<div id="app">
<div class="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="glass clear"></div>
<div class="glass frosted"></div>
</div>
</div>
I noticed it DID refresh for me after I made the screen smaller and scrolled the page. But didn't update when scrolling the example (regardless of the screen size)
So it appears that the paint is causing the issue and not the implementation. This also makes me wonder if the device capabilities might be partly at fault. I'm using a 13" 2017 MBP so no discrete GPU.
Have you tried forcing GPU acceleration? To do so add this to the element:
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
Safari still seems buggy with translateZ(0) so use the above instead.
Edit: The above didn't seem to solve the problem. Consider adding will-change (docs) since that's supported by Safari. Not sure if filters are a valid change object but I believe 'scroll-position' can be used. I should note that this is a nuclear option so be careful.
I create two squares with z translate and put in perspective-origin in css.
This is the link to jsbin: https://jsbin.com/bebucum/edit?html,output.
Following is the most relevant CSS:
.container {
-webkit-perspective: 700;
-webkit-perspective-origin: 450px 000px;
}
.square:nth-child(1) {
-webkit-transform: translateZ(100px);
}
.square:nth-child(2) {
background: yellow;
-webkit-transform: translateZ(-200px);
}
Most of the output makes sense to me. However there is one part I do not quite understand.
I think the yellow square should be below the blue one, as its translateZ is negative. But the output is the other way around.
Can someone help me understand this behavior?
To achieve correct 3d positioning, you need to set
transform-style: preserve-3D;
I have also removed webkit prefixes, they aren't necesary now.
.container {
perspective: 700px;
perspective-origin: 450px 0px;
transform-style: preserve-3D;
}
.square {
background: blue;
position: relative;
top: 300px;
left: 300px;
height: 100px;
width: 100px;
}
.square:nth-child(1) {
transform: translateZ(100px);
}
.square:nth-child(2) {
background: yellow;
transform: translateZ(-200px);
}
<div class="container">
<div class="square">
</div>
<div class="square">
</div>
</div>
So I have the basic setup for a CSS flip in this fiddle here: http://jsfiddle.net/6r82fzk6/
What this is: A CSS 3D Flip (container, card, front & back elements) with child elements on the front & back. The flip occurs on :hover for demonstration.
What I'm trying to achieve: To get the back element to transition slower than everything else. So by the time the card flips and the back side is visible, the child element of the back face (#be) is halfway through its transition.
What I have so far: Code snippet below. You may open the JSFiddle link to see it in action. Its the black gradient element I'm aiming to delay.
#container {
perspective: 800px;
position: relative;
width: 300px;
height: 300px;
margin: 1px auto;
}
#card {
transform-style: preserve-3d;
transition: all 1s ease-in-out;
position: relative;
}
#container:hover #card {
transform: rotateY(180deg);
}
#front,
#back {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 300px;
backface-visibility: hidden;
transform-style: preserve-3d;
}
#front {
background: red;
z-index: 2;
}
#back {
transform: rotateY(180deg);
background: blue;
}
#fe,
#be {
position: absolute;
top: 20px;
left: 20px;
transform: translateZ(50px);
}
#fe {
width: 50px;
height: 50px;
background: gold;
box-shadow: 0 0 4px black;
}
#be {
width: 260px;
height: 260px;
box-shadow: 0 4px 8px -2px rgba(0, 0, 0, 0.6), 0 1px 3px whitesmoke inset;
background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) 100%);
}
<!-- Outside container -->
<div id="container">
<!-- Card being flipped -->
<div id="card">
<!-- Front face -->
<div id="front">
<!-- Front Child element -->
<div id="fe"></div>
</div>
<!-- Back face -->
<div id="back">
<!-- Back Child element -->
<div id="be"></div>
</div>
</div>
</div>
To clarify: This is not production code, its more for testing and understanding. I'm exploratory like that.
You can not do it in you current setup.
This is because you are not moving the front or the back, but the container.
If you want them to move differently, you have to move them directly instead of the container
#container:hover #front {
transform:rotateY(180deg);
}
#container:hover #back {
transform:rotateY(360deg);
}
#front {
transition:all 1s ease-in-out;
}
#back {
transition:all 2s ease-in-out;
}
demo
I looked around but can't find any good resources for doing higher level animations (like card flip, cubes, etc). Like a ???:CSS :: jQuery:JS.
I know of transit but I'm looking for something that has more functionality and animations built in.
Have you thought about using Animate.css? Seems pretty good. Another good one seems like CSS3 Animations and for stuff like card-flipping, CSS3 Playground.
An edited version of this one: http://css3.bradshawenterprises.com/flip/:
JSfiddle: http://jsfiddle.net/PnUHr/1/
CSS
#f1_container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#f1_container {
-webkit-perspective: 1000;
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 1.0s linear;
transform-style: preserve-3d;
transition: all 1.0s linear;
}
#f1_container:hover #f1_card {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
box-shadow: -5px 5px 5px #aaa;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.face.back {
display: block;
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
box-sizing: border-box;
color: white;
text-align: center;
background-color: #aaa;
}
HTML
<div id="f1_container">
<div id="f1_card" class="shadow">
<div class="front face">
<img src="Cirques.jpg"/>
</div>
<div class="back face center">
<img src="Cirques.jpg" style="transform:scaleX(-1), transform:scaleY(-1)"/>
</div>
</div>
</div>
All credits go to the original created (see link). I've just removed the padding that was on the back-facing <div> and added a mirrored background of the front-facing image.
For Mozilla/Gecko browsers you need to add the -moz-* prefixes too. Same for Opera (-o-*) and Internet Explorer (-ms-*`).
Direct image link: http://css3.bradshawenterprises.com/images/Cirques.jpg
Effeckt.css is STILL work in progress but look very promising– a pattern libary of multiple sources.
I began working on a react project which heavily utilises blur effect.
It takes the icon added to a div and it puts it as a background and blurs it.
Therefore, every section that has different icon has different colorfull background.
I have attached the image because I believe I explained it poorly:
I am not sure what part of code to attach so I will put the react component and css affecting it here:
React Component
import React from 'react';
import './Object.css';
const Jobs = ({ employer, description, descriptionList, image }) => {
return (
<div>
<section className="object-container">
<div className="container">
<div className="object">
<div className="row">
<div className="col-sm-8">
<h3 className="employer">
{employer}
</h3>
<div className="description">
{description}
</div>
<ul className="description-list">
{descriptionList.map(item => <li>{item}</li>)}
</ul>
</div>
<div className="image-container">
<div className="col-sm-4">
<img className="image" src={image} alt="logo" />
</div>
</div>
</div>
</div>
</div>
<div className="object__bg" id="object__bg" style={{ backgroundImage: `url(${image})` }}>
</div>
</section>
</div >
);
}
export default Jobs;
CSS
#font-face {
font-family: 'Neon Online';
src: url(I_am_online_with_u.ttf) format('truetype'),
url(I_am_online_with_u.woff) format('woff');
}
.object {
padding: 40px;
background-color: rgba(53, 53, 53, 0.45);
border-radius: 20px;
box-shadow: 0px 3px 28px 1px rgba(0,0,0,0.75);
color: white;
display: flex;
align-items: center;
transform: scale(1);
transition: all 0.15s ease-in;
/*
This is used for improving performance with blur filter.
Why does it work, I have no idea...
*/
backface-visibility: hidden;
perspective: 1000;
transform: translate3d(0,0,0);
transform: translateZ(0);
}
.object:hover {
box-shadow: 0px 3px 32px 1px rgba(0,0,0,0.9);
background-color: rgba(53, 53, 53, 0.55);
transform: scale(1.01);
transition: all 0.31s ease-out;
}
.object-container {
position: relative;
padding: 40px;
/*
This is used for improving performance with blur filter.
Why does it work, I have no idea...
*/
backface-visibility: hidden;
perspective: 1000;
transform: translate3d(0,0,0);
transform: translateZ(0);
}
.object__bg {
position: absolute;
z-index: -1;
top: 0;
left: -10vw;
right: 0;
margin: auto;
width: 120vw;
min-height: 100px;
height: 100%;
filter: blur(150px) saturate(2) hue-rotate(0deg);
background-position: center center;
background-size: cover;
background-color: #353535;
transition: all 1.5s ease-out;
}
.object__bg:hover,
.object__bg:focus {
filter: blur(150px) saturate(2.6) hue-rotate(180deg);
transition: all 3s ease-in;
}
.image-container {
display: flex;
align-items: center;
justify-content: center;
}
.image {
width: 200px;
}
I thought of canvas and svg filters because I read a few times that it's blur effect improves performance significantly.
Unfortunately, after trying it a few times I just didn't manage to get it working with React.
I have also tried adding backface visibility to the elements overlaying the blur which helped (probably because it forces GPU to do the work instead of CPU, I am not sure).
So, is there any current alternative that could help me with a website that utilises blur this heavily?