"position: fixed" not woking when parent has the "transform" CSS property - css

In my project I have screen which should ease-in from right side of the screen so for that thing I have used transform: translateX(100%) and then changing that to transform: translateX(0%). it works fine I able to achieve the ease-in effect but in that screen I have action button which has css property of Position: Fixed;Bottom: 0px; but this is not working I mean its not sticking in the bottom of the screen.
Here is my JSfiddle : https://jsfiddle.net/sureshpattu/a1seze4x/
Html:
<header>
Heading
</header>
<div class="page__popup page__popup--ease-in-right page__action-btn--visible" style="height: 382px;">
<div class="container">
</div>
<button class="js-action-btn">
SELECT ROOMS
</button>
</div>
Css:
header {
background: #fff;
height: 60px;
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
z-index: 10;
box-shadow: 2px 2px 10px #000;
}
.container {
height: 382px;
}
.page__popup {
position: absolute;
top: 100vh;
z-index: 8;
display: block;
overflow-y: scroll;
max-height: 100vh;
width: 100%;
height: 0;
background: #ffffff;
.js-action-btn {
position: relative;
bottom: -50px;
transition: all 0.25s ease-in-out;
}
//Themes
&--ease-in-bottom {
&.visible {
transition: height 0.25s ease-in-out;
top: 54px;
right: 0;
bottom: 0;
left: 0;
}
}
&--ease-in-right {
transform: translateX(100%);
height: 100vh;
top: 60px;
&.visible {
transition: transform 0.25s ease-in-out;
transform: translateX(0);
}
}
}
.page__action-btn--visible {
.js-action-btn {
background: red;
width: 100%;
height: 30px;
position: fixed;
bottom: 0;
z-index: 10;
box-shadow: 0 7px 4px 10px rgba(0, 0, 0, .12);
}
}

This is not a bug.
Take a look at the spec: The Transform Rendering Model
Specifying a value other than ‘none’ for the ‘transform’ property
establishes a new local coordinate system at the element that it is
applied to.
So according to the spec: the element with fixed positioning will become relative to the element with the transform - not the viewport
As a workaround you could:
1) Use transitions (eg. on the left property) instead of transform (translateX)
2) Remove the position:fixed button from the container which uses transforms

Related

Smooth CSS Transform Scale on rectangle, keeping an even border

I have an absolutely positioned div that I want to have slowly increase in size (5s transition) on hover, to become a "border" for a relative-positioned div on top of it:
<div class="rectangle">
<div class="background"></div>
<div class="content">blah</div>
</div>
Styles (vendor prefixes removed for readability):
.rectangle {
position: relative;
}
.background {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.content {
height: 800px;
width: 200px;
}
Transitioning the overall .background size results in choppy animation but an even border:
.rectangle:hover .background {
width: calc(100% + 40px);
height: calc(100% + 40px);
top: -20px;
left: -20px;
right: -20px;
bottom: -20px;
transition: 5s linear all;
}
Transitioning a border is choppy animation, but (obviously) an even border
.rectangle:hover .content {
border: 20px solid red;
transition: 5s linear all;
}
Transitioning a transform-scale is smooth, but results in a larger top and bottom "border" because it is a rectangle:
.rectangle:hover .background {
transition: 5s transform;
transform: scale(1.1);
}
Any way to either get transform-scale to keep even dimensions, or any other way to create this effect?
You can try using box shadow as a border to achieve smooth transitions.
.rectangle {
position: relative;
width: 300px;
height: 300px;
top: 100px;
left: 30%;
}
.background {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.background::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 0 0 0px #000;
transition: 5s linear box-shadow;
}
.content {
height: 300px;
width: 200px;
}
.rectangle:hover .background::before {
box-shadow: 0 0 0 20px #000;
transition: 5s linear box-shadow;
}
<div class="rectangle">
<div class="background"></div>
<div class="content">blah</div>
</div>

How can I put pseudo element behind parent?

I looked for solutions and tried all the suggestions from this SO, but I failed all of that.
I wanna make a border as peseudo element behind parent.
.member__profile-container {
flex-basis: 50rem;
position: relative;
z-index: 4;
}
.member__profile {
padding-top: 150%;
background-image: url('../images/irene.jpg');
background-repeat: no-repeat;
background-position: center;
background-size: cover;
box-shadow: 0 -1rem .5rem 1rem rgba(0,0,0,0.3);
margin-right: 4rem;
transform: rotate(-5deg) translateX(-10%);
animation: expand 1s ease .5s forwards;
}
.member__profile:before {
content: ' ';
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
border: 10px solid white;
transform: rotate(-5deg) translateX(-10%);
animation: expand 1s ease .5s forwards;
}
<div class="member__profile-container">
<div class="member__profile"></div>
</div>
Result is like below, but border must be behind parent.
NOT WORKING EXAMPLE
To make it work I had to modify your html a bit. Because of the transformation in .member__profile a stacking context is created at this level and since the ::before element is a descendant of his element, z-index will only move the pseudo element inside .member__profile.
HTML
<div class="member__profile-container">
<div class="member__profile"></div>
<!-- moved the pseudo-element to a sibling element -->
<!-- removing 'the transform' inside .member__profile and
keeping the pseudo element would also work -->
<div class="member__undercover"></div>
</div>
CSS
.member__profile-container {
/* creating a stacking context on the parent */
position: relative;
z-index: 1;
flex-basis: 50rem;
/* added color to make position clearer */
background-color: green;
}
.member__profile {
position: relative;
padding-top: 150%;
background-image: url('../images/irene.jpg');
/* added color to make position clearer */
background-color: red;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
box-shadow: 0 -1rem .5rem 1rem rgba(0, 0, 0, 0.3);
margin-right: 4rem;
transform: rotate(-5deg) translateX(-10%);
z-index: 0;
}
.member__undercover {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
border: 10px solid white;
transform: rotate(-5deg) translateX(-10%);
/* added color to make position clearer */
background-color: blue;
z-index:-1;
}
By using "position: relative; z-index: 1;" on the container I create a stacking context on this level and can reorder freely it's children with z-index.
If you use z-index without creating a stacking context in the container then you will be using a stacking context somewhere else where one has been created in your document, or ultimately the body if none exist before.
If you want the border behind the container not the profile, you just need to move
"position: relative; z-index: 1;" up one parent (not copy it, move it).
To understand more about the stacking context : MDN, The stacking context
You need to apply a negative z-index value to the pseudo-element.
e.g. z-index: -6
Working Example:
div {
width: 100px;
height: 180px;
margin: 20px 60px;
background-color: rgb(255, 0, 0);
}
div::after {
content: '';
position: absolute;
top: -6px;
left: 2px;
z-index: -6;
width: 100px;
height: 180px;
margin: 20px 60px;
border: 6px solid rgb(0, 0, 0);
transform: rotate(-30deg);
}
<div></div>
Further Reading:
https://developer.mozilla.org/en-US/docs/Web/CSS/z-index
Try adding a negative z-index to your pseudo element.
Eg.
.yourclass:: pseudoelement {
z-index: -1;
}

Why translateZ working not working on hover?

When I hover over the image, the transition works fine except for the fact that the front image (that of a rotating lock) only translates 20px in Z direction when the mouse is removed from that image. I want the rotating lock image to be 20px in front always.
Also, why does the rotating lock image becomes slightly smaller just after I hover the image?
body {
margin:0;
width: 100%;
height: 100%;
}
.maincircle {
width: 200px;
height: 200px;
position: relative;
margin-left: 200px;
margin-top: 10px;
border-radius: 50%;
border: 1px solid black;
perspective: 600px;
transform-style: preserve-3d;
}
.door {
background-color: gray;
border-radius: 100%;
height: 200px;
margin: 0;
position: relative;
width: 200px;
transition: .5s linear;
transform-style: preserve-3d;
transform-origin: 0 50%;
transition: transform 2s 0.5s;
}
.door:before {
background-color: gray;
background-image: linear-gradient(hsla(0,0%,100%,.25), hsla(0,0%,0%,.25));
border-radius: 100%;
content: '';
height: 200px;
left: 0;
position: absolute;
top: 0;
width: 200px;
transform: translateZ(-5px);
}
.door:after {
background-color: gray;
background-image: linear-gradient(hsla(0,0%,100%,.25), hsla(0,0%,0%,.25));
bottom: 0;
content: '';
left: 100px;
position: absolute;
top: 0;
width: 5px;
z-index: -10;
transform: rotateY(-90deg);
transform-origin: 100% 50%;
}
.maincircle:hover .door {
transform: rotateY(-110deg);
}
.maincircle:hover .locker {
transform: rotate(90deg);
}
.locker {
background-image: url("https://irp-cdn.multiscreensite.com/806e9122/dms3rep/multi/tablet/CombinationLock-1000x1000.png");
position: absolute;
top: 25px;
left: 25px;
background-size: 100% 100%;
border-radius: 100%;
width: 150px;
height: 150px;
transform: translateZ(20px);
transition: transform 0.5s;
}
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="maincircle">
<div class="door">
<div class="locker"></div>
</div>
</div>
</body>
</html>
Question 1: (I want the rotating lock image to be 20px in front always)
It is because transform settings are not additive in nature. When you specify the transform during the :hover as give below,
.maincircle:hover .locker {
transform: rotate(90deg);
}
it overwrites the transform: translateZ(20px) that is specified within the default state (which is the setting under .locker selector) and so the translation in Z-axis is lost whenever the element is being hovered. It gets applied back only when the :hover is off (that is, the element returns to default state as specified in .locker selector).
In order to always have the translation in Z-axis, translateZ(20px) should be added to the transform stack within :hover selector also like below:
.maincircle:hover .locker {
transform: rotate(90deg) translateZ(20px);
}
body {
margin:0;
width: 100%;
height: 100%;
}
.maincircle {
width: 200px;
height: 200px;
position: relative;
margin-left: 200px;
margin-top: 10px;
border-radius: 50%;
border: 1px solid black;
perspective: 600px;
transform-style: preserve-3d;
}
.door {
background-color: gray;
border-radius: 100%;
height: 200px;
margin: 0;
position: relative;
width: 200px;
transition: .5s linear;
transform-style: preserve-3d;
transform-origin: 0 50%;
transition: transform 2s 0.5s;
}
.door:before {
background-color: gray;
background-image: linear-gradient(hsla(0,0%,100%,.25), hsla(0,0%,0%,.25));
border-radius: 100%;
content: '';
height: 200px;
left: 0;
position: absolute;
top: 0;
width: 200px;
transform: translateZ(-5px);
}
.door:after {
background-color: gray;
background-image: linear-gradient(hsla(0,0%,100%,.25), hsla(0,0%,0%,.25));
bottom: 0;
content: '';
left: 100px;
position: absolute;
top: 0;
width: 5px;
z-index: -10;
transform: rotateY(-90deg);
transform-origin: 100% 50%;
}
.maincircle:hover .door {
transform: rotateY(-110deg);
}
.maincircle:hover .locker {
transform: rotate(90deg) translateZ(20px);
}
.locker {
background-image: url("https://irp-cdn.multiscreensite.com/806e9122/dms3rep/multi/tablet/CombinationLock-1000x1000.png");
position: absolute;
top: 25px;
left: 25px;
background-size: 100% 100%;
border-radius: 100%;
width: 150px;
height: 150px;
transform: translateZ(20px);
transition: transform 0.5s;
}
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="maincircle">
<div class="door">
<div class="locker"></div>
</div>
</div>
</body>
</html>
Question 2: (Why does the rotating lock image becomes slightly smaller just after I hover the image?)
I am putting this at the last (even below the code) because I know by now you'd have guessed why it became smaller. It becomes smaller because the element is losing the translateZ(20px) and so it is going farther away from your eye. Any object that goes farther away from the eye will look smaller.

CSS3 Animation - Change image on 'underside' of an animated element

I am using CSS3 animation to have a door element open on hover. If you take a look at the url below: http://www.superfreebingo.com/advent-lp/
When you hover over a box the css animation will begin showing you content beneath.
I would like to modify the 'underside' of the door that opens, you will notice at the moment you just see the front image in reverse..
Will it be a case of timing another animation on the background image itself to coincide with the point the door 'flips' over?
So what you are looking for is backface-visibilty. Set that to the .box img.
Now add an element below that image, here I just added a pseudo-element, positioned it absolute with z-index: -1;.
You could also just set a div or image as a child of .box, works just as well.
/* CSS needed for your affect */
.box img {
backface-visibility: hidden;
}
.box::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #FF0;
z-index: -1;
}
/* Rest of the markup */
article {
display: inline-block;
width: 6em;
height: 6em;
margin: .5em;
perspective: 850px;
}
article:hover .box {
transition: .5s ease-in;
transform: rotateY(-97deg);
transform-origin: 0 50%;
perspective-origin: 0;
}
.box {
position: relative;
transition: all .3s;
transform-origin: 0 50%;
text-align: center;
background-size: cover;
box-shadow: 0 0 40px 0 rgba(0, 0, 0, .15);
transform-style: preserve-3d;
perspective: 850px;
cursor: pointer;
}
.box, .present {
width: 100%;
height: 100%;
}
.box img, .present img {
width: 100%;
height: 100%;
}
.present {
position: absolute;
z-index: -1;
top: 0;
left: 0;
box-shadow: 0 0 40px 0 rgba(0, 0, 0, .15), inset 0 0 30px 20px rgba(0, 0, 0, .4);
}
.present a {
display: block;
width: 100%;
height: 100%;
}
<article>
<div class="box">
<img src="http://i.stack.imgur.com/wheDD.jpg">
</div>
<div class="present">
<a href="#">
<img src="http://i.stack.imgur.com/EXU8x.jpg">
</a>
</div>
</article>

Hide on :hover, DIV over DIV

I have a DIV on top of another DIV.
What I want to achieve is hide the DIV on top to be able to access the DIV below.
I've tried opacity, but since the top DIV is still there, just transparent, It won't allow me to interact with the content of the DIV below.
I've also tried display:none;, visibility: hidden; and z-index. None of those would work.
How do I achieve this with CSS3, so I can also use a transition?
HTML:
<li class="panel-box">
<div class="front box-style"> </div>
<div class="back"> </div>
</div> </li>
CSS:
.panel-box {
margin: 5px;
padding: 0;
display: inline-block;
clear: none;
float: left;
width: 310px;
height: 200px;
position: relative;
}
.box-style {
background-color: red;
}
.front {
width: 310px;
height: 200px;
z-index: 5;
opacity: 0;
display: block;
position: absolute;
top: 0;
left: 0;
}
.front:hover {
opacity: 0;
display: none;
}
.back {
width: 310px;
height: 200px;
background-color: rgba(57, 54, 55, 0.95);
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
Thanks a bunch.
I've put together a bit of a workaround that seems to do some of this, but it will likely fail miserably on IE.
Tested and works reasonably on Chrome… YMMV :)
It uses a combination of z-index and sibling selectors to allow the front/back divs to swap places in the stacking context.
I had to swap places with front/back to use the CSS sibling selectors. I don't claim this is a perfect example, but perhaps it'll get the ideas flowing.
Basically what is happening here is:
As the mouse enters - trigger .front:hover
front z-index goes to -1 triggering .back:hover
back z-index immediately goes to 100 keeping it on top of the stack
sibling selector back:hover + front keeps the front opacity at 0
When the mouse transitions out, this all reverses
The reverse transition is not very smooth - haven't quite figured out if that can be fixed yet.
Demo
CSS
.panel-box {
margin: 5px;
padding: 0;
display: inline-block;
clear: none;
float: left;
width: 310px;
height: 200px;
position: relative;
}
.front {
width: 310px;
height: 200px;
padding: 10px;
z-index: 5;
opacity: 1;
display: block;
position: absolute;
background-color: red;
top: 0;
left: 0;
-webkit-transition: opacity .5s ease;
}
.front:hover {
opacity: 0;
z-index: -1;
}
.back {
width: 310px;
height: 200px;
padding: 10px;
color: white;
background-color: rgba(57, 54, 55, 0.95);
position: absolute;
top: 0;
left: 0;
z-index: 0;
opacity: 0;
-webkit-transition: opacity .5s ease;
}
.back:hover + .front {
opacity: 0;
}
.back:hover {
z-index: 100;
opacity: 1;
}
HTML
<li class="panel-box">
<div class="back">content goes here</div>
<div class="front box-style"></div>
</li>

Resources