I have a layout like this:
<div class="parent">
<div class="wrapper">
<div class="child">
<h1>Sticky text</h1>
</div>
</div>
</div>
CSS:
.parent {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.wrapper {
width: 1024px;
display: block;
}
.child {
-webkit-transform: translateY(-80px);
-ms-transform: translateY(-80px);
transform: translateY(-80px);
transition: transform .5s ease;
z-index: 31;
position: fixed;
left: 0;
right: 0;
top: 100%;
}
Since parent has transform of 0 my child wont stay fixed. However if i remove parent transform the child get's sticked just fine. is there any way around this? without deleting the transform of the parent? Maybe flex?
Related
I'm working on a JavaScript game similar to "2048." It has a tabular display of "tiles" made up of several layers of divs. I'd like to make the selected tile "bounce" using a CSS animation. (The bouncing needs to be able to happen in each of the four cardinal directions: bounce up, down, left, or right, depending on the state of the game.)
My problem is that when I attach an animation, I see the content correctly bounce "in front of" tiles up and left of the selected one, but it incorrectly bounces "behind" the tiles to its right and below it. Here's a JSFiddle illustrating the problem:
https://jsfiddle.net/atqwc8er/2/
I'd like the bouncing blue tile "2" to show up in front of tile "3", the same way it already shows up in front of tile "1". Can anyone help me make it do that?
.tile {
position: absolute;
width: 50px;
height: 50px;
background-color: red;
}
.tile-inner {
text-align: center;
z-index: 10;
}
.tile-1-0 {
transform: translate(0px, 0px);
}
.tile-1-1 {
transform: translate(55px, 0px);
}
.tile-1-2 {
transform: translate(110px, 0px);
}
.selected .tile-inner {
background-color: blue;
animation: back-and-forth 0.5s infinite alternate;
z-index: 99; /* not working */
}
#keyframes back-and-forth {
from {
transform: translateX(-25px);
}
to {
transform: translateX(25px);
}
}
<div class="tile-container">
<div class="tile tile-1-0">
<div class="tile-inner">1</div>
</div>
<div class="tile tile-1-1 selected">
<div class="tile-inner">2</div>
</div>
<div class="tile tile-1-2">
<div class="tile-inner">3</div>
</div>
</div>
increase the z-index of .selected instead
.tile {
position: absolute;
width: 50px;
height: 50px;
background-color: red;
}
.tile-inner {
text-align: center;
z-index: 10;
}
.tile-1-0 {
transform: translate(0px, 0px);
}
.tile-1-1 {
transform: translate(55px, 0px);
}
.tile-1-2 {
transform: translate(110px, 0px);
}
.selected .tile-inner {
background-color: blue;
animation: back-and-forth 0.5s infinite alternate;
}
.selected {
z-index: 99;
}
#keyframes back-and-forth {
from {
transform: translateX(-25px);
}
to {
transform: translateX(25px);
}
}
<div class="tile-container">
<div class="tile tile-1-0">
<div class="tile-inner">1</div>
</div>
<div class="tile tile-1-1 selected">
<div class="tile-inner">2</div>
</div>
<div class="tile tile-1-2">
<div class="tile-inner">3</div>
</div>
</div>
Related question to get more details and understand why it cannot work with .title-inner: Why can't an element with a z-index value cover its child?
The z-index attribute should be added to the element at the same level, so pls add the z-index attribute to .title-1-1 instead of .title-inner
The code is from Bootstrap carousel, I wonder why without display:none, css3 transition not working? It should move from right to left.
Thanks! https://jsfiddle.net/25d3ga9j/11/
I want to remove .item{display:none}, and add visibility: hidden, then keep it working. It works in Firefox(transition-property: left),but not in Chrome(transition-property: transform;transform: translate3d...)
https://jsfiddle.net/zjmove/r8ejf5Lk/
$('.item').addClass('next')
$('.item')[0].offsetWidth // force reflow
$('.item').addClass('left')
.item {
height: 100px;
background: red;
display: none; //why with out display:none, transition not working?
}
.c {
overflow: hidden;
}
.item {
transition: transform 0.6s ease-in-out;
backface-visibility: hidden;
perspective: 1000px;
}
.item.next {
display: block;
transform: translate3d(100%, 0, 0);
left: 0;
}
.item.next.left {
transform: translate3d(0, 0, 0);
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class="c">
<div class='item'>
</div>
</div>
There is a few things going on here, where the first is whether the first script line might run before the DOM is ready $('.item').addClass('next')
The second, there is no time for the first class to finish its transition until the second gets added, but a delay might solve that.
Either way, and based on whether which comes first (may vary between browsers), you can get different result.
The below sample shows how it should be set up when not using display: none, which by the way should be avoid if possible
$(window).load(function() {
$('.item').addClass('left')
});
.c {
overflow: hidden;
}
.item {
transition: transform 0.6s ease-in-out;
backface-visibility: hidden;
perspective: 1000px;
transform: translate3d(100%, 0, 0);
height: 100px;
background: red;
}
.item.left {
transform: translate3d(0, 0, 0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="c">
<div class='item'>
</div>
</div>
I've got an image which will scale on hover. However, at the same time the image get's translated to -50% on both the X and Y axis, or in some cases, only on the X axis.
Is there a way to inherit the previous transform while still changing one of the values?
.container {
position: relative;
height: 400px;
width: 640px;
overflow: hidden;
}
img {
-webkit-transform: translate(-50%,-50%) scale(1);
transform: translate(-50%,-50%) scale(1);
position: absolute;
top: 50%;
left: 50%;
transition: 500ms;
}
img.special {
-webkit-transform: translateX(-50%) scale(1);
transform: translateX(-50%) scale(1);
top: 0;
}
img:hover {
-webkit-transform: translate(-50%, -50%) scale(1.1);
transform: translate(-50%, -50%) scale(1.1);
}
<div class="container">
<img src="http://www.lorempixel.com/640/400/nature" alt="test image" />
</div>
<div class="container">
<img src="http://www.lorempixel.com/640/400/abstract" class="special" alt="test image" />
</div>
TL:DR;
Is there a way to inherit the original transform settings, while still changing one of the values?
I'm not looking for answers adding extra css, classes or whatever. I'm just looking for a way to keep this as short as possible. I've already solved this using extra classes and CSS.
Is there a way to inherit the original transform settings, while still changing one of the values?
No, there is no way to do this in CSS. CSS transform property declarations (like all other properties) are not additive. The latest setting (or) the one which is more specific will completely override anything else specified and hence there is no chance to inherit some values and add on top of it.
The only alternative with pure CSS is to add an extra wrapper and apply one of the transforms to it. In this way, the img:hover styling (the scale) need not be repeated and can be left as common for all.
.container {
position: relative;
height: 400px;
width: 640px;
overflow: hidden;
}
.wrapper {
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
}
.special.wrapper {
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
top: 0;
}
.wrapper img {
transition: 500ms;
}
img:hover {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
<div class="container">
<div class="wrapper">
<img src="http://www.lorempixel.com/640/400/nature" alt="test image" />
</div>
</div>
<div class="container">
<div class="wrapper special">
<img src="http://www.lorempixel.com/640/400/people" alt="test image" />
</div>
</div>
The other way would be to use JavaScript, find out what is the current transform on the element, then append the extra transform on hover and apply it via inline styles.
I've come across a strange problem with the way Edge (and IE 11) handles my matrix3d transform. The page I'm working on has elements that already have an arbitrary transform applied to them (due to a plugin being used), however thanks to my manager I now need to apply a 180 degree rotation around the Y axis on top of this. Because of this, I could not simply use the rotateY() function as it replaced the old transform and moved the element, so I figured I'd need to use matrices. This works fine in Chrome and Firefox, but Edge doesn't seem to handle matrix3d in the same way.
Here's an example of using rotateY: http://codepen.io/anon/pen/wGqapy
(HTML)
<body>
<div class="flip-container">
<div class="front">
Test
</div>
</div>
</body>
(CSS)
.flip-container,
.front {
width: 320px;
height: 480px;
}
.front {
transition: 0.6s;
position: absolute;
top: 0;
left: 0;
z-index: 2;
background-color: green;
}
.flip-container:hover .front
{
transform: rotateY(180deg);
}
When you mouse over the element, it rotates around the Y axis in 3D space. And here's an example of using matrix3d, using the same matrix shown in the "computed CSS" tab in Edge: http://codepen.io/anon/pen/QNMbmV
(HTML)
<body>
<div class="flip-container">
<div class="front">
Test
</div>
</div>
</body>
(CSS)
.flip-container,
.front {
width: 320px;
height: 480px;
}
.front {
transition: 0.6s;
position: absolute;
top: 0;
left: 0;
z-index: 2;
background-color: green;
}
.flip-container:hover .front
{
transform: matrix3d(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1);
}
This, however, seems to spin around more than one axis. This does not occur in Firefox or Chrome. Am I supposed to use some magical vendor-specific CSS? I've been unsuccessful in searching SO or Google, so I hope someone has some insight!
Thanks in advance.
Matrices are very good for calculus, and for setting the transforms in an universal way. But aren't so good when you are transitioning from one state to the other.
a simple animation as
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
is impossible to set with matrices
Also, take into account that even using matrices, you can chain them with others transforms.
All that said, let's see an example of your rotation working on a previously transformed element
.flip-container,
.front {
width: 320px;
height: 480px;
}
.front {
transition: 0.6s;
position: absolute;
top: 0;
left: 0;
z-index: 2;
background-color: green;
/* transform: rotate(10deg); is equivalent to matrix(0.984808, 0.173648, -0.173648, 0.984808, 0, 0) */
transform: matrix(0.984808, 0.173648, -0.173648, 0.984808, 0, 0) rotateY(0deg);
}
.flip-container:hover .front {
transform: matrix(0.984808, 0.173648, -0.173648, 0.984808, 0, 0) rotateY(180deg);
}
<div class="flip-container">
<div class="front">
Test
</div>
</div>
When I use a webkit 3d transform on hover, only the top 50% of the hover area works, while the bottom 50% is unstable. I'm currently testing on Chrome (31.0.1650.63). Is it a bug? Is there any workaround?
Try to place your mouse on the top of the div and slowly bring it to the bottom.
HTML
<div class="hoverArea"></div>
<div class="flip">
<div class="front">front</div>
<div class="back">back</div>
</div>
CSS
.hoverArea, .flip, .front, .back {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.hoverArea {
z-index: 10;
}
.flip {
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
-webkit-perspective: 800;
z-index: 9;
}
.front {
background-color: #f00;
-webkit-backface-visibility: hidden ;
}
.back {
background-color: #f0f;
-webkit-transform: rotatex(-180deg);
-webkit-backface-visibility: hidden ;
}
.hoverArea:hover + .flip {
-webkit-transform: rotatex(-180deg);
}
http://jsfiddle.net/4P53y/
You can fix it by removing the .hoverArea element and instead apply the :hover event on the .flip element.
.flip:hover {
-webkit-transform: rotatex(-180deg);
}
Demo
If you want to still use the .hoverArea element then you can use transform:translateZ(1px); on .hoverArea to make it function correctly. It makes the browser render the element more carefully
.hoverArea {
z-index: 10;
-webkit-transform:translateZ(1px);
}
Demo