How to smoothly stretch div with position absolute? - html

I can't smoothly stretch left-top div to 100vh height and 100vw width.
Box .btn smoothly going as I wanted, but whole background (div .red) has some kind of lag and goes smoothly only in the end.
Any tips, please? :)
#keyframes stretchIn {
0% {
height: 50vh;
width: 50vw;
z-index: 0;
}
100% {
height: 100vh;
width: 100vw;
z-index: 1;
}
}
body {
background: #999;
margin: 0;
padding: 0;
overflow: hidden;
}
body .red,
body .blue,
body .green,
body .yellow {
position: absolute;
z-index: 0;
height: 50vh;
width: 50vw;
}
body .red {
top: 0;
left: 0;
background: #a04951;
transition: 1s;
}
body .red:hover {
animation: stretchIn 5s both;
}
body .red .btn {
position: relative;
width: 50px;
height: 50px;
background: #fff;
top: 45%;
left: 45%;
}
body .blue {
background: #c06c84;
top: 0;
right: 0;
}
body .green {
bottom: 0;
left: 0;
background: #6c5b7b;
}
body .yellow {
bottom: 0;
right: 0;
background: #355c7d;
}
<div class="red">
<div class="btn"></div>
</div>
<div class="blue"></div>
<div class="green"></div>
<div class="yellow"></div>
Codepen

I'm starting z-index with hover instead of starting with animation.
#keyframes stretchIn {
to {
height: 100vh;
width: 100vw;
}
}
body {
background: #999;
margin: 0;
padding: 0;
overflow: hidden;
}
.red,
.blue,
.green,
.yellow {
position: absolute;
z-index: 0;
height: 50vh;
width: 50vw;
}
.red {
top: 0;
left: 0;
background: #a04951;
}
.red:hover {
animation: stretchIn 5s both;
z-index: 1;
}
.red .btn {
position: relative;
width: 50px;
height: 50px;
background: #fff;
top: 45%;
left: 45%;
}
.blue {
background: #c06c84;
top: 0;
right: 0;
}
.green {
bottom: 0;
left: 0;
background: #6c5b7b;
}
.yellow {
bottom: 0;
right: 0;
background: #355c7d;
}
<div class="red">
<div class="btn"></div>
</div>
<div class="blue"></div>
<div class="green"></div>
<div class="yellow"></div>

#dgknca is right in a sense of putting your red div to the front. Your div is not lagging, it just starts to stretch behind other divs (note, it comes first in the order, hence is "covered" by elements that come after it). You can either use z-index or change the order of the elements:
#keyframes stretchIn {
0% {
height: 50vh;
width: 50vw;
z-index: 0;
}
100% {
height: 100vh;
width: 100vw;
z-index: 1;
}
}
body {
background: #999;
margin: 0;
padding: 0;
overflow: hidden;
}
body .red,
body .blue,
body .green,
body .yellow {
position: absolute;
z-index: 0;
height: 50vh;
width: 50vw;
}
body .red {
top: 0;
left: 0;
background: #a04951;
transition: 1s;
}
body .red:hover {
animation: stretchIn 5s both;
}
body .red .btn {
position: relative;
width: 50px;
height: 50px;
background: #fff;
top: 45%;
left: 45%;
}
body .blue {
background: #c06c84;
top: 0;
right: 0;
}
body .green {
bottom: 0;
left: 0;
background: #6c5b7b;
}
body .yellow {
bottom: 0;
right: 0;
background: #355c7d;
}
<div class="blue"></div>
<div class="green"></div>
<div class="yellow"></div>
<div class="red">
<div class="btn"></div>
</div>

Related

Animated element not visible outside of parent container in Firefox

I have a animated div that flies to the top right corner of the viewport.
However, because of the overflow properties it not visible outside of parent container in Firefox. It is perfectly visible in Chrome.
Element behind the scrollbar in Firefox:
Element correctly above the parent in Chrome:
How can I make it work in Firefox as well? If overflow-y: auto is removed from .container the issue doesn't appear anymore, but that's not a viable solution as I need the scrollable content.
Here is an example. You can check that it produces the desired behaviour in Chrome, but not in Firefox:
.app {
overflow: hidden;
}
.container {
width: 260px;
max-height: 400px;
background: blue;
left: 10px;
right: 10px;
top: 10px;
position: fixed;
z-index: 500;
overflow-y: auto;
}
.wrapper {
height: 250px;
padding: 10px;
margin: 5px;
background: yellow;
top: 5px;
position: sticky;
}
.content {
height: 600px;
margin: 5px;
background: orange;
}
#keyframes fly-to-top {
10% {
top: 150px;
right: 80%;
width: 50px;
}
30% {
top: 120px;
right: 70%;
width: 45px;
}
60% {
top: 75px;
right: 40%;
width: 40px;
}
100% {
top: 10px;
right: 160px;
width: 35px;
}
}
.animated {
position: fixed;
right: unset;
top: 165px;
width: 50px;
background: red;
color: white;
animation: fly-to-top linear 2s forwards;
display: flex;
align-items: flex-start;
}
<div class="app">
<div class="container">
<div class="wrapper">
<div class="animated">
Text
</div>
</div>
<div class="content">
Lorem ipsum
</div>
</div>
</div>
Try this splution:
.wrapper position set to fixed
.content is shifted down with transform: translateY()
In the .wrapper class, i was add pointer-events: none;, because
if cursor is on the .wrapper block without this property, mouse
wheel cann't scroll the content, scroll work only when drag the
scroll bar.
.app {
overflow: hidden;
}
.container {
width: 260px;
max-height: 400px;
background: blue;
left: 10px;
right: 10px;
top: 10px;
position: fixed;
z-index: 500;
overflow-y: auto;
}
.wrapper {
display: flex;
height: 250px;
padding: 10px;
margin: 5px;
background: yellow;
/* top: 5px; */
position: fixed; /* changed */
/* calculate '.container' width - scroll-track-width(12px-17px) - '.wrapper' padding(left, right) - margin(left, right) */
width: calc(260px - 12px - 20px - 10px);
z-index: 5;
pointer-events: none; /* mouse wheel work with this property */
}
.content {
height: 600px;
margin: 5px;
background: orange;
/* calculate '.wrapper' properties to shift '.content' down */
/* height + padding(top, bottom) + margin-bottom */
transform: translateY(calc(250px + 20px + 5px));
}
#keyframes fly-to-top {
10% {
top: 150px;
right: 80%;
width: 50px;
}
30% {
top: 120px;
right: 70%;
width: 45px;
}
60% {
top: 75px;
right: 40%;
width: 40px;
}
100% {
top: 10px;
right: 160px;
width: 35px;
}
}
.animated {
position: fixed;
right: unset;
top: 165px;
width: 50px;
background: red;
color: white;
animation: fly-to-top linear 2s forwards;
display: flex;
align-items: flex-start;
z-index: 100;
}
<div class="app">
<div class="container">
<div class="wrapper">
<div class="animated">
Text
</div>
</div>
<div class="content">
Lorem ipsum
</div>
</div>
</div>
Edited after comment:
You can take the animated element out of its parent (i.e. the element which has overflow: hidden), on a higher level in the HTML code - as a sibling to the container. I did that in the snippet below, and also added a z-index that places the animated element above the container:
.app {
overflow: hidden;
}
.container {
width: 260px;
max-height: 400px;
background: blue;
left: 10px;
right: 10px;
top: 10px;
position: fixed;
z-index: 500;
overflow-y: auto;
}
.wrapper {
height: 250px;
padding: 10px;
margin: 5px;
background: yellow;
top: 5px;
position: sticky;
}
.content {
height: 600px;
margin: 5px;
background: orange;
}
#keyframes fly-to-top {
10% {
top: 150px;
right: 80%;
width: 50px;
}
30% {
top: 120px;
right: 70%;
width: 45px;
}
60% {
top: 75px;
right: 40%;
width: 40px;
}
100% {
top: 10px;
right: 160px;
width: 35px;
}
}
.animated {
position: fixed;
right: unset;
top: 165px;
width: 50px;
background: red;
color: white;
animation: fly-to-top linear 2s forwards;
display: flex;
align-items: flex-start;
z-index: 501;
}
<div class="app">
<div class="container">
<div class="wrapper">
</div>
<div class="content">
Lorem ipsum
</div>
</div>
<div class="animated">
Text
</div>
</div>

Animation when hovering object-fit: contain <img>

On mouse hover, animated span tags beneath an img work fine when the img isn't using object-fit: contain like below:
body {
height: 100%;
width: 100%;
margin: 0
}
.container {
max-width: 600px;
position: relative;
text-align: center;
width: 100%;
}
.product {
position: relative;
width: 150px;
}
img.content {
background: white;
height: auto;
margin: 8%;
position: relative;
width: 84%;
vertical-align: middle;
z-index: 5000;
}
.product:hover .effect-1,
.product:hover .effect-2 {
display: block;
}
.effect-1,
.effect-2 {
border-radius: 30%;
display: none;
mix-blend-mode: multiply;
height: 84%;
opacity: 1;
position: absolute;
width: 84%;
z-index: 3000;
}
.effect-1 {
animation: rotate 1.8s linear infinite;
background: cyan;
}
.effect-2 {
animation: rotate 1.2s linear reverse infinite;
background: #e7a9ff;
}
.placeholder {
width: 84%;
height: auto;
visibility: hidden;
}
#keyframes rotate {
0% {
top: 0;
left: 8%;
}
25% {
top: 8%;
left: 0%;
}
50% {
top: 16%;
left: 8%;
}
75% {
top: 8%;
left: 16%;
}
100% {
top: 0;
left: 8%;
}
}
<body>
<div class="container">
<p>Hover image please</p>
<div class="product">
<img class="content" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
<span class="effect-1"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
<span class="effect-2"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
</div>
</div>
</body>
But when the img is using object-fit: contain the animated spans take up the entire area:
body {
height: 100%;
margin: 0;
}
.container {
max-width: 600px;
position: relative;
text-align: center;
width: 100%;
height: 100%;
min-height: 700px;
}
.product {
height: 100%;
position: absolute;
}
.content {
background: white;
margin: 8%;
position: relative;
width: 84%;
height: 100%;
vertical-align: middle;
z-index: 5000;
object-fit: contain;
}
.product:hover .effect-1,
.product:hover .effect-2 {
display: block;
}
.effect-1,
.effect-2 {
border-radius: 30%;
display: none;
mix-blend-mode: multiply;
height: 84%;
opacity: 1;
position: absolute;
width: 84%;
z-index: 3000;
}
.effect-1 {
animation: rotate 1.8s linear infinite;
background: cyan;
}
.effect-2 {
animation: rotate 1.2s linear reverse infinite;
background: #e7a9ff;
}
.placeholder {
width: 84%;
height: auto;
visibility: hidden;
}
#keyframes rotate {
0% {
top: 0;
left: 8%;
}
25% {
top: 8%;
left: 0%;
}
50% {
top: 16%;
left: 8%;
}
75% {
top: 8%;
left: 16%;
}
100% {
top: 0;
left: 8%;
}
}
<body>
<div class="container">
<div class="product">
<span class="effect-1"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
<span class="effect-2"><img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg"></span>
<img class="content" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
</div>
</div>
</body>
How do you make these hover effects apply only to the area around the image (not the entire area) when using object-fit: contain? The image must remain vertically centered using object-fit.
Is this what you wanted? The image is centered between the animated divs.
The reason why your image is larger in the second example you've given is because you've changed your CSS there. You've changed the height/width values of .container, .product etc, so the children elements are showing up larger, because they inherit these values.
I've changed max-width and min-height in .container to reduce the overall size. And the width of .content should be less than the width of the effect divs
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
}
.container {
max-width: 300px;
/* This is new */
position: relative;
text-align: center;
width: 100%;
height: 100%;
min-height: 300px;
/* This is new */
}
.product {
height: 100%;
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
}
.content {
display: flex;
align-self: center;
background: white;
margin: 0 auto;
position: relative;
width: 65%;
/* This is new */
object-fit: contain;
/* This is new */
}
.product:hover .effect-1,
.product:hover .effect-2 {
display: flex;
}
.effects {
position: absolute;
}
.effect-1,
.effect-2 {
border-radius: 30%;
display: flex;
mix-blend-mode: multiply;
height: 84%;
opacity: 1;
position: absolute;
width: 84%;
z-index: 3000;
visibility: visible;
}
.effect-1 {
animation: rotate 1.8s linear infinite;
background: cyan;
}
.effect-2 {
animation: rotate 1.2s linear reverse infinite;
background: #e7a9ff;
}
.placeholder {
width: 84%;
height: auto;
visibility: hidden;
object-fit: contain;
display: flex;
margin: 0 auto;
align-self: center;
position: relative;
}
#keyframes rotate {
0% {
top: 0;
left: 8%;
}
25% {
top: 8%;
left: 0%;
}
50% {
top: 16%;
left: 8%;
}
75% {
top: 8%;
left: 16%;
}
100% {
top: 0;
left: 8%;
}
}
<body>
<div class="container">
<div class="product">
<span class="effects">
<img class="placeholder" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
<span class="effect-1"></span>
<span class="effect-2"></span>
</span>
<img class="content" src="http://www.petsworld.in/blog/wp-content/uploads/2014/09/Golden-Retriever-Puppies-in-basket.jpg">
</div>
</div>
</body>

expand div and covering other div

Anyone can help me figure out how to do this. I'm trying to expand the div when hover, but I cannot expand it from center for the b and c div, and d from right, and I trying to overlay the other div when expand instead of pushing it.
The transform:scale() method cannot be use, because I will change the background with image later. I also trying to avoid using jQuery. Thanks in advance.
body {
background-color: grey;
margin: 0;
padding: 0;
}
.displaybox {
background-color: pink;
width: 100%;
height: 500px;
z-index: -1;
}
.box1, .box2, .box3, .box4 {
width: 25%;
height: inherit;
display: block;
float: left;
z-index: 1;
}
.box1 {
background-color: green;
}
.box2 {
background-color: blue;
}
.box3 {
background-color: red;
}
.box4 {
background-color: purple;
}
.box1:hover, .box2:hover, .box3:hover, .box4:hover {
width:100%;
z-index: 0;
transition: 1s ease;
}
<div class="displaybox">
<div class="box1">a</div>
<div class="box2">b</div>
<div class="box3">c</div>
<div class="box4">d</div>
</div>
You can do this with css transitions but I think the mouse out animation is poor as it loses it's z-index too early (so you do not see the right side animating backwards):
body {
background-color: grey;
margin: 0;
padding: 0;
}
.displaybox {
display:flex;
background-color: pink;
width: 100%;
height: 500px;
position: relative;
}
.box {
display: block;
position: absolute;
top: 0;
bottom: 0;
width:25%;
transition: 1s ease;
}
.box:hover {
left: 0;
width:100%;
z-index:1;
}
.box1 {
background-color: green;
left: 0;
}
.box2 {
background-color: blue;
left: 25%;
}
.box3 {
background-color: red;
left: 50%;
}
.box4 {
background-color: purple;
left: 75%;
}
<div class="displaybox">
<div class="box box1">a</div>
<div class="box box2">b</div>
<div class="box box3">c</div>
<div class="box box4">d</div>
</div>
Instead I would probably use a js animation instead (below is a simple jQuery animation):
var $boxes = $('.box');
$boxes.hover(function() {
var $this = $(this);
$this.stop().css('z-index', 2).animate({ // change z-index before animation and animate width to 100 % and move to the left
width: '100%',
left: 0
});
},
function() {
// mouse out animation
var $this = $(this);
$this.stop().css('z-index', 2).animate({ // make highest z-index and shrink back to 25% moving left to original place
width: '25%',
left: $boxes.index($this) * 25 + '%'
}, function() {
$this.css('z-index', 1); // change z-index back after animation
});
});
body {
background-color: grey;
margin: 0;
padding: 0;
}
.displaybox {
display:flex;
background-color: pink;
width: 100%;
height: 500px;
position: relative;
}
.box {
display: block;
position: absolute;
top: 0;
bottom: 0;
width:25%;
}
.box1 {
background-color: green;
left: 0;
}
.box2 {
background-color: blue;
left: 25%;
}
.box3 {
background-color: red;
left: 50%;
}
.box4 {
background-color: purple;
left: 75%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="displaybox">
<div class="box box1">a</div>
<div class="box box2">b</div>
<div class="box box3">c</div>
<div class="box box4">d</div>
</div>
You can achieve the effect with absolute positioning. Setting the left and right values to 0 will make the div expand out to the edges. I used percentages on the left and right values instead of a 25% width and I had to put a higher z-index value on the hover state to get the current div to jump to the front right away.
body {
background-color: grey;
margin: 0;
padding: 0;
}
.displaybox {
background-color: pink;
width: 100%;
height: 500px;
z-index: 0;
}
.box1, .box2, .box3, .box4 {
height: inherit;
z-index: 0;
position: absolute;
transition: 1s ease;
}
.box1 {
background-color: green;
left: 0;
right: 75%;
}
.box2 {
background-color: blue;
left: 25%;
right: 50%;
}
.box3 {
background-color: red;
left: 50%;
right: 25%;
}
.box4 {
background-color: purple;
left: 75%;
right: 0;
}
.box1:hover, .box2:hover, .box3:hover, .box4:hover {
z-index: 10;
left: 0;
right: 0;
}
<div class="displaybox">
<div class="box1">a</div>
<div class="box2">b</div>
<div class="box3">c</div>
<div class="box4">d</div>
</div>
A solution is to animate the background by using a pseudo element overflowing:
body {
background-color: grey;
margin: 0;
padding: 0;
}
.displaybox {
background-color: pink;
width: 100%;
height: 500px;
z-index: -1;
overflow:hidden;
}
.box {
width: 25%;
height: inherit;
display: block;
float: left;
z-index: 1;
position:relative;
background-color:var(--c);
transition:z-index 1s 1s;
}
.box:before {
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
z-index:-1;
background-color:var(--c);
transition:1s left,1s right;
}
.box:hover {
z-index:2;
transition:z-index 0s;
}
.box:hover::before {
left:-100vw;
right:-100vw;
}
<div class="displaybox">
<div class="box box1" style="--c:green">a</div>
<div class="box box2" style="--c:blue">b</div>
<div class="box box3" style="--c:red">c</div>
<div class="box box4" style="--c:purple">d</div>
</div>

Two floating divs over an image

Alright so I got 1 div that is float left and one with float right, now for some reason I cannot make them go to the side where they should be. They are kinda now both overlapping eachother
* {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
}
html, body {
width: 100%;
height: 100%;
}
#main {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
#main img {
width: 100%;
height: 100%;
}
#page_left, #page_right {
width: 50%;
height: 100%;
background-color: red;
position: absolute;
left: 0px;
top: 0px;
z-index: 1000;
}
<div id="main">
<img src="img/background.jpg"/>
<div id="page_left"></div>
<div id="page_right"></div>
</div>
I also tried using a method with display inline block but it didnt work out so well
Try this with your additional css
CSS
#page_left, #page_right {
width: 50%;
height: 100%;
background-color: red;
position: absolute;
top: 0px;
z-index: 1000;
}
#page_left {
left: 0;
}
#page_right {
right: 0;
}
#page_left, #page_right {
width: 50%;
height: 100%;
background-color: red;
position: absolute;
top: 0px;
z-index: 1000;
}
remove left: 0px
OR
remove position: absolute
#page_left, #page_right {
width: 50%;
height: 100%;
background-color: red;
z-index: 1000;
}
the overflow in happened because you given left:0px and position:absolute for both the divs,I'm solved this and and added the snippet below.
* {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
}
html, body {
width: 100%;
height: 100%;
}
#main {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
#main img {
width: 100%;
height: 100%;
}
#page_left, #page_right {
width: 50%;
height: 100%;
background-color: red;
position: absolute;
top: 0px;
z-index: 1000;
}
#page_left{
left: 0px;
}
#page_right{
background-color:green;
float:right;
position: absolute;
right: 0px;
}
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<div id="main">
<img src="img/background.jpg"/>
<div id="page_left">
</div>
<div id="page_right">
</div>
</div>
</body>
</html>

CSS transition, collapsing width/height to center of div

Below is my effort.
http://liveweave.com/i1qkNw
Below is also my code
.container {
display: inline-block;
position: relative;
border: 1px solid green;
}
.middle {
position: relative;
width: 300px;
height: 250px;
background: black;
}
.door {
position: absolute;
width: 300px;
height: 250px;
background: red;
top: 0;
left: 0;
opacity: 0.5;
transition: .5s;
transform-origin: center center;
}
.container:hover .door {
transition: .5s;
opacity: 0;
width: 0;
height: 0;
}
<div class="container">
<div class="middle"></div>
<div class="door"></div>
</div>
What i want to do is, when user hovers over container, I want the door div's width/height to be zero. As you can see, I am achieving this effect but it disappears to upper left corner. Is there any way I can make it disappear to its center?? Like the width and height are reduced till its center and disappear.
Kindly guide me how to achieve this effect.
You have to set top / bottom / left / right values to 50%.
.container {
display: inline-block;
position: relative;
border: 1px solid green;
}
.middle {
position: relative;
width: 300px;
height: 250px;
background: black;
}
.door {
position: absolute;
width: 300px;
height: 250px;
background: red;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.5;
transition: .5s;
transform-origin: center center;
}
.container:hover .door {
transition: .5s;
opacity: 0;
top: 50%;
bottom: 50%;
left: 50%;
right: 50%;
width: 0;
height: 0;
}
<div class="container">
<div class="middle"></div>
<div class="door"></div>
</div>