I am trying to fill a wrapper (600x600px) when hovering over smaller boxes inside it. For a box in the top left corner, it is easily done using regular transition-timing-function, but when trying to enlarge in other directions, I have gotten stuck.
So I have the following:
#allbox {
background: #bbb;
width: 600px;
height: 600px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0
}
with boxes:
div.box1 {
position: absolute;
top: 0%;
left: 0%;
}
div.box2 {
position: absolute;
top: 0%;
left: 37.5%;
}
For transition I use:
#div1 {-webkit-transition-timing-function: linear;}
#div1 {transition-timing-function: linear;}
div.box1:hover {
width: 600px;
height: 600px;
}
But I am unable to figure a good way to do it for the following box.
Here is a sample using z-index keeping the hovered on top.
#allbox {
background: #bbb;
width: 600px;
height: 300px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0
}
#allbox div {
position: absolute;
z-index: 1;
top: 0%;
width: 33.33%;
height: 50%;
transition: left 0.5s linear, width 0.5s linear, height 0.5s linear, z-index 1s linear;
}
div.box1 {
left: 0;
background: blue;
}
div.box2 {
left: 33.33%;
background: red;
}
div.box3 {
left: 66.66%;
background: green;
}
#allbox div:hover {
z-index: 2;
left: 0;
width: 100%;
height: 100%;
transition: left 0.5s linear, width 0.5s linear, height 0.5s linear, z-index 0s linear;
}
<div id="allbox">
<div class="box1">
</div>
<div class="box2">
</div>
<div class="box3">
</div>
</div>
I think we just add "left: 0;" to the hover state.
div.box2:hover {
left: 0;
width: 600px;
height: 600px;
}
Hope this help you.
Related
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>
I found a code to animate the underline of a link but I would like to be on the other direction, as we read (left to right) which is actually the opposite. Here is a JSFiddle
.sliding-u-l-r-l-inverse {
display: inline-block;
position: relative;
padding-bottom: 3px;
}
.sliding-u-l-r-l-inverse:before {
content: '';
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 3px;
width: 100%;
transition: width 0s ease;
}
.sliding-u-l-r-l-inverse:after {
content: '';
display: block;
position: absolute;
right: 0;
bottom: 0;
height: 3px;
width: 100%;
background: blue;
transition: width .8s ease;
}
.sliding-u-l-r-l-inverse:hover:before {
width: 0%;
background: blue;
transition: width .8s ease;
}
.sliding-u-l-r-l-inverse:hover:after {
width: 0%;
background: transparent;
transition: width 0s ease;
}
<div class="sliding-u-l-r-l-inverse">
I want it to slide on the other direction.
</div>
Change the value declaration of left and right.
i.e. .sliding-u-l-r-l-inverse:before consist of left:0 change that to right:0 and same in other pseudo selector :after right:0 to left:0. This changes the direction and makes line to start from left to right.
.sliding-u-l-r-l-inverse {
display: inline-block;
position: relative;
padding-bottom: 3px;
}
.sliding-u-l-r-l-inverse:before {
content: '';
display: block;
position: absolute;
right: 0;
bottom: 0;
height: 3px;
width: 100%;
transition: width 0s ease;
}
.sliding-u-l-r-l-inverse:after {
content: '';
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 3px;
width: 100%;
background: blue;
transition: width .8s ease;
}
.sliding-u-l-r-l-inverse:hover:before {
width: 0%;
background: blue;
transition: width .8s ease;
}
.sliding-u-l-r-l-inverse:hover:after {
width: 0%;
background: transparent;
transition: width 0s ease;
}
<div class="sliding-u-l-r-l-inverse">
I want it to slide on the other direction.
</div>
.sliding-u-l-r-l-inverse {
display: inline-block;
position: relative;
padding-bottom: 3px;
}
.sliding-u-l-r-l-inverse:before {
content: '';
display: block;
position: absolute;
right: 0;
bottom: 0;
height: 3px;
width: 100%;
transition: width 0s ease;
}
.sliding-u-l-r-l-inverse:after {
content: '';
display: block;
position: absolute;
left: 0; /* changed from 'right' */
bottom: 0;
height: 3px;
width: 100%;
background: blue;
transition: width .8s ease;
}
.sliding-u-l-r-l-inverse:hover:before {
width: 0%;
background: blue;
transition: width .8s ease;
}
.sliding-u-l-r-l-inverse:hover:after {
width: 0%;
background: transparent;
transition: width 0s ease;
}
<div class="sliding-u-l-r-l-inverse">
I want it to slide on the other direction.
</div>
How can I transition a HTML div with an absolute position (right: 0; bottom: 0px) to another edge (left: 0px; top: 0px;).
I have tried the following code, however, transition with absolute elements only seems to work when using either left/top, or right/bottom.
What is the preferred way to do that in HTML5?
var ele = document.getElementById("my-box");
ele.addEventListener("click", function() {
ele.classList.toggle("clicked");
});
.box {
position: absolute;
top: 0px;
right: 0px;
width: 100px;
height: 100px;
background-color: red;
transition: all 0.7s ease;
}
.box.clicked {
top: auto;
bottom: 0px;
left: 0px;
right: auto;
}
<div class="box" id='my-box'>
</div>
You should keep using the top and right on the clicked below. Just use a calc to position them like below
var ele = document.getElementById("my-box");
ele.addEventListener("click", function() {
ele.classList.toggle("clicked");
});
.box {
position: absolute;
top: 0px;
right: 0px;
width: 100px;
height: 100px;
background-color: red;
transition: all 0.7s ease;
}
.box.clicked {
top: calc(100% - 100px);
right: calc(100% - 100px);
}
<div class="box" id='my-box'>
</div>
change your .clicked class as
.box.clicked {
transform:translate(calc(-100vw + 100px) ,calc(100vh - 100px))
}
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.
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