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>
Related
Is there any way to trigger a div outside of a div without using Javascript. I tried CSS combinators and couldn't get it to work. I'm not sure if I just did it wrong or it's not possible. If anyone knows a way to achieve this I would appreciate the help.
.wrapper{
display: flex;
flex-direction: row;
}
.overlay{
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background-color: #008CBA;
overflow: hidden;
width: 100%;
height:0;
transition: .5s ease;
opacity: 0.5;
}
.bottom:hover .overlay, .top:hover .overlay {
bottom: 0;
height: 100%;
}
.top{
position: relative;
width: 200px;
height: 200px;
margin: 25px 25px 0px 0px;
background-color: black;
}
.bottom{
height: 200px;
width: 200px;
background-color: green;
margin-top: 25px;
}
<div class="wrapper">
<div class="top">
<div class="overlay"></div>
</div>
<div class="bottom"></div>
</div>
Yes but to an extent. In this example I can rotate the second div in the html flow by hovering over the first div using ~.
#one {
position: absolute;
width: 100px;
height: 100px;
background: red;
}
#two {
position: absolute;
right: 10px;
width: 100px;
height: 100px;
background: blue;
}
#one:hover ~ #two{
animation: rotate 2s linear infinite;
}
#keyframes rotate {
to {transform: rotate(360deg)}
}
<div id="one"></div>
<div id="two"></div>
For your code if you place <bottom> before <top> in html you can hover over the green to make the overlay animate.
html
<div class="wrapper">
<div class="bottom"></div>
<div class="top">
<div class="overlay"></div>
</div>
</div>
CSS
.bottom:hover ~ .top .overlay{
bottom: 0;
height: 100%;
}
UPDATE:
.wrapper{
display: flex;
flex-direction: row-reverse;
width: min-content;
}
.overlay{
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background-color: #008CBA;
overflow: hidden;
width: 100%;
height:0;
transition: .5s ease;
opacity: 0.5;
}
.bottom:hover ~ .top .overlay{
bottom: 0;
height: 100%;
}
.top{
position: relative;
width: 200px;
height: 200px;
margin: 25px 25px 0px 0px;
background-color: black;
}
.bottom{
height: 200px;
width: 200px;
background-color: green;
margin-top: 25px;
}
<div class="wrapper">
<div class="bottom"></div>
<div class="top">
<div class="overlay"></div>
</div>
</div>
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>
I wish to include 4 divs inside a parent div in the following manner:
I could use fixed position and set right/left/top/bottom = 0 accordingly for each child div if they were not inside in a div, but right now, I can't figure out how to do this.
Here you go, but I'm not sure how this will fare in responsiveness since the parent has fixed sizes, but the child div should be able to adapt if the parent changes size. Some css can be combined, but I separated them all for reference
.parent {
width: 300px;
height: 300px;
position: relative;
border: 1px solid black;
}
.div1 {
position: absolute;
bottom: 0;
right: 0;
width: 80%;
height: 20%;
background-color: green;
}
.div2 {
position: absolute;
top: 0;
right: 0;
width: 20%;
height: 80%;
background-color: blue;
}
.div3 {
position: absolute;
top: 0;
left: 0;
width: 80%;
height: 20%;
background-color: red;
}
.div4 {
position: absolute;
bottom: 0;
left: 0;
width: 20%;
height: 80%;
background-color: brown;
}
<div class="parent">
<div class="div1">
DIV1
</div>
<div class="div2">
DIV2
</div>
<div class="div3">
DIV3
</div>
<div class="div4">
DIV4
</div>
</div>
Consider utilizing absolute positioning on nested div elements and offsetting their positions, within the containing element, appropriately and as required by declaring top, bottom, left and right properties respectively.
Code Snippet Demonstration
Note:
In the below demonstration, a containing element, with resizing properties, has been wrapped around the element in question, to demonstrate the responsive behaviour of this method.
Resize the element manually by clicking the icon, in the bottom-left corner of the containing element, and dragging vertically or horizontally.
* {
box-sizing: border-box;
font-family: arial;
}
.outer {
border: 3px solid black;
width: 100%;
height: 100%;
position: relative; /* required */
}
.outer-wrapper { /* purely for the sake of responsive demonstration */
padding: 10px;
resize: auto;
overflow: hidden;
border: 3px dashed gray;
width: 400px;
height: 400px;
}
.outer div {
position: absolute;
padding: 10px;
font-weight: bold;
font-size: 12px;
}
.outer div:nth-child(odd) {
width: 80%;
height: 20%;
}
.outer div:nth-child(even) {
width: 20%;
height: 80%;
}
.outer div:nth-child(1) {
background: #ed1c24;
left: 0;
top: 0;
}
.outer div:nth-child(2) {
background: #00a2e8;
right: 0;
top: 0;
}
.outer div:nth-child(3) {
background: #22b14c;
right: 0;
bottom: 0;
}
.outer div:nth-child(4) {
background: #b97a57;
left: 0;
bottom: 0;
}
<div class="outer-wrapper">
<div class="outer">
<div>Div 1</div>
<div>Div 2</div>
<div>Div 3</div>
<div>Div 4</div>
</div>
</div>
It will be helpful to you
.parent{
position: relative;
width: 100%;
height: 100vh;
border: 1px solid black;
}
.parent>div{
position:absolute;
text-align:center;
}
.one{
background-color: green;
bottom: 0;
right: 0;
width: 80%;
height: 20%;
}
.two{
background-color: blue;
top: 0;
right: 0;
width: 20%;
height: 80%;
}
.three{
background-color: red;
top: 0;
left: 0;
width: 80%;
height: 20%;
}
.four{
background-color: brown;
bottom: 0;
left: 0;
width: 20%;
height: 80%;
}
<div class="parent">
<div class="one"> Div1</div>
<div class="two">Div2</div>
<div class="three">Div3</div>
<div class="four">Div4</div>
</div>
I have divs with the same size on the same position. However they don't have a background so you don't see that the elements are in different containers.
The problem I have right now is that the hover event is only triggered on the element in the last container because it is layered on top of the other ones.
#main {
background: yellow;
width: 300px;
height: 300px;
position: absolute;
left: 30px;
top: 30px;
z-index: 1;
}
.out {
width: 300px;
height: 300px;
position: absolute;
left: 0;
top: 0;
background: none;
z-index: 5;
}
.in {
position: absolute;
width: 40px;
height: 40px;
z-index: 10;
opacity: 0.5;
}
.out:nth-of-type(1) .in {
top: 40px;
left: 40px;
background: green;
}
.out:nth-of-type(2) .in {
top: 120px;
left: 120px;
background: red;
}
.out:nth-of-type(3) .in {
top: 200px;
left: 200px;
background: blue;
}
.in:hover {
opacity: 1.0;
}
<div id="main">
<div class="out">
<div class="in">DIV 1</div>
</div>
<div class="out">
<div class="in">DIV 2</div>
</div>
<div class="out">
<div class="in">DIV 3</div>
</div>
</div>
Is it possible to force the hover event or do I have to put all the elements into the same container (which would be possible but not that good on the original website)?
I know that the explanation is not the best, but I think with the code you should understand. JSFiddle
I fixed it by adding pointer-events: none; to .out and pointer-events: auto; to .in. HTH !
I would put them in the same container if that is possible as you say.
Sorry I couldn't just comment to say that.
You can you put all these into the same parent element (.out) and use the :nth-child() selector to get the different colors and positions. Then the hover works:
#main {
background: yellow;
width: 300px;
height: 300px;
position: absolute;
left: 30px;
top: 30px;
z-index: 1;
}
.out {
width: 300px;
height: 300px;
position: absolute;
left: 0;
top: 0;
background: none;
z-index: 5;
}
.in {
position: absolute;
width: 40px;
height: 40px;
z-index: 10;
opacity: 0.5;
}
.out .in:nth-child(1) {
top: 40px;
left: 40px;
background: green;
}
.out .in:nth-child(2) {
top: 120px;
left: 120px;
background: red;
}
.out .in:nth-child(3){
top: 200px;
left: 200px;
background: blue;
}
.in:hover {
opacity: 1.0;
}
<div id="main">
<div class="out">
<div class="in">DIV 1</div>
<div class="in">DIV 2</div>
<div class="in">DIV 3</div>
</div>
</div>
I'm trying to replicate this, essentially:
So basically two 50% <div>'s side-by-side, with some form of absolute positioning (I assume) to achieve the left box to go over the top of the right box (the red line is just representing the middle of the viewport)
Any hints? Thanks :)
.container {
width: 500px;
height: 300px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
.box1 {
width: 100%;
height: 100%;
background-color: blue;
transform: skewX(-20deg) translateX(-40%);
position: absolute;
z-index: 10;
}
.box2 {
width: 100%;
height: 100%;
background-color: red;
z-index: 0;
}
Should be pretty simple with CSS3.
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
</div>
I offer a version without the transformation, using pseudoelement. It is faster and does not distort the text.
.container {
width: 500px;
height: 300px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
.box1 {
width: 50%;
height: 100%;
background-color: blue;
position: absolute;
left: 0;
}
.box1::after{
background: linear-gradient(to bottom right, blue 50%, transparent 0);
content: " ";
width: 20%;
height: 100%;
position: absolute;
left: 100%;
z-index: 1;
}
.box2 {
width: 50%;
height: 100%;
background-color: red;
position: absolute;
right: 0;
}
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
</div>
Try this
.wrapper {
overflow-x: hidden;
}
.outer {
position: absolute;
width: 2000px;
left: 50%;
bottom: 0;
margin-left: -1000px;
display: flex;
justify-content: center;
align-items: center;
}
.left__inner {
background: goldenrod;
padding: 24px 48px;
flex: 1;
transform: skew(45deg);
display: flex;
justify-content: flex-end;
}
.right__inner {
background: #222;
padding: 24px 48px;
flex: 1;
transform: skew(45deg);
}
.left__text,
.right__text {
transform: skew(-45deg);
span {
font-weight: 200;
font-size: 36px;
text-transform: uppercase;
}
}
.left__text {
color: #3c3c3c;
}
.right__text {
color: Goldenrod;
}
<div class="wrapper">
<div class="outer">
<div class="left__inner">
<div class="left__text">
<span> so skewy</span>
</div>
</div>
<div class="right__inner">
<div class="right__text">
<span>span much angle</span>
</div>
</div>
</div>
</div>
I would do it like this
this is just an example, not a ready-made solution ))
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
.container {
display: flex;
}
.container div {
width: 50%;
height: 200px;
position: relative;
}
.container .left:before {
content: '';
position: absolute;
right: 0;
top: 0;
height: 100%;
transform: skewY(-1.5deg);
background: inherit;
}