I have the following setup:
<div class="" style="height: 400px !important;
width: 100% !important;
overflow: hidden;">
<div class="" style="height: 400px !important;
width: 100% !important;
background-color: red;">
</div>
<div class="" style="height: 400px !important;
width: 100% !important;
background-color: blue;">
</div>
</div>
So there's a div, which has a certain height. There are two divs inside it which have the same height, which means that their height together is twice as much as their container div. Overflow is hidden, so only the first div is showing.
I now want to wait for the user to hover, then animate and move the second div up, so that the second div is hiding the first div now. On unhover, I want to revert the whole thing.
How would I do something like this, am I on the right track?
You can use CSS transforms for this. When hovering the container div a transform is applied to the inner divs.
The transition rule is used to show the change in position when a hover starts and stops.
.container {
height: 400px;
overflow: hidden;
}
.container:hover .inner-2 {
transform: translateY(-100%);
}
.inner {
height: 100%;
transition: transform .6s ease-in-out;
}
.inner-1 {
background-color: rgba(255,0,0,.5);
}
.inner-2 {
background-color: rgba(0,0,255,.5);
}
<div class="container">
<div class="inner inner-1"></div>
<div class="inner inner-2"></div>
</div>
JSFiddle
It's worth noting that this method is much less processor intensive than the answers suggesting absolute positioning the element or changing its margin and will also result in a much smoother transition.
Sources: https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/ and https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/
Yes, you are on the right track. I would advise to not use inline styles though, but instead use classes and CSS markup.
You can use for example the margin for offsetting. This can be animated using CSS transitions.
I show this below.
.parent {
height: 100px;
overflow: hidden;
}
.parent:hover .child:first-child {
margin-top: -100px;
}
.child {
height: 100px;
transition: margin-top 1s;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
<div class="parent">
<div class="child red">
</div>
<div class="child blue">
</div>
</div>
To achieve this you can use CSS alone. If you wrap the child divs in another div which has it's margin-top animated when the container div is hovered, something like this:
.container {
height: 400px;
width: 100%;
overflow: hidden;
position: relative;
}
.child {
height: 400px;
width: 100%;
}
.slide {
margin-top: 0;
transition: margin 0.3s;
}
.container:hover .slide { margin-top: -400px; }
.child.red { background-color: red; }
.child.blue { background-color: blue; }
<div class="container">
<div class="slide">
<div class="child red"></div>
<div class="child blue"></div>
</div>
</div>
Alternatively you can just shrink the height of the first div, but this can cause overflow issues, depending on what the content of that element is:
.container {
height: 400px;
width: 100%;
overflow: hidden;
position: relative;
}
.child {
height: 400px;
width: 100%;
transition: height 0.3s;
}
.container:hover :first-child { height: 0; }
.child.red { background-color: red; }
.child.blue { background-color: blue; }
<div class="container">
<div class="child red"></div>
<div class="child blue"></div>
</div>
Its hard to reach nice animation when you overflow container, code below just swap them on hover:
CSS
Default state
div>div:first-child {
display: block;
}
div>div:last-child {
display: none;
}
Hover state
div:hover>div:first-child {
display: none;
}
div:hover>div:last-child {
display: block;
}
Alternative height rising
div {
position: relative;
}
div>div:first-child {
position: absolute;
left: 0;
top: 0;
}
div>div:last-child {
left: 0;
bottom: 0;
position: absolute;
height: 0 !important;
z-index: 1;
transition: height .5s linear;
}
div:hover>div:last-child {
height: 400px !important;
}
<div class="" style="height:400px !important; width:100% !important; overflow:hidden;">
<div class="" style="height:400px; width:100% !important; background-color: red;">
</div>
<div class="" style="height:400px; width:100% !important; background-color: blue;">
</div>
</div>
Here's a working
Fiddle
HTML
<div class="container" style="height:400px !important; width:100% !important; overflow:hidden;">
<div class="top" style="height:400px !important; width:100% !important; background-color: red;">
</div>
<div class="bottom" style="height:400px !important; width:100% !important; background-color: blue;">
</div>
</div>
CSS
.container:hover .bottom{
top: -400px;
}
.bottom{
position: relative;
top: 0px;
transition-property: top;
transition-duration: 1s;
}
The bottom div inside the container is relatively positioned and moves to the top when the container has the hover state.
Related
I'm working on trying to get a div to slide up from the bottom. So far it works ok as I can get the div to show and hide when I need to by adding a class of open-drawer to the element that I'm trying to get to slide up. But I'm not sure how I can get it to animate and slide up from the bottom.
Not sure if I need to adjust something within the transition or what.
Here's what I got so far:
$(".drawer-link").click(function(e) {
var vdata = $(this).data("id");
$(".drawer[data-id=" + vdata + "]").addClass("open-drawer");
e.preventDefault();
});
$(".close").on("click", function(e) {
$(".drawer").removeClass("open-drawer");
e.preventDefault();
});
body {
padding: 20px;
}
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
background: #0c1f3f;
padding-top: 90px;
overflow-y: scroll;
transition: top 0.5s ease;
color: white;
opacity: 0;
}
.wrapper {
width: 100%;
max-width: 1140px;
margin: 0 auto;
}
.open-drawer {
top: 150px;
opacity: 1;
}
.close {
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a class="drawer-link" href="#" data-id="drawer-01">Link To Show Drawer</a>
</div>
<div class="drawer" data-id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a class="close" href="#">Close The Drawer</a>
</div>
</div>
Link to demo (CodePen): https://codepen.io/ultraloveninja/pen/qzVQLp
Three examples: jQuery, pure JS, and pure HTML+CSS
Toggle animate panel using jQuery and .toggleClass()
Use transform: translateY at 100% and on click the class .is-open will animate to 0.
No need for extra special classes, use what you already have, a data-*
attribute: data-drawer="#drawer-01" (notice the ID # selector!)
Also, make sure to use id="drawer-01" as the drawer selector.
Use jQuery's .toggleClass()
Animating transform is always a better idea than animating non-accelerable properties like top, bottom etc etc
$("[data-drawer]").on('click', function(e) {
e.preventDefault();
$($(this).data("drawer")).toggleClass("is-open");
});
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0c1f3f;
overflow-y: scroll;
color: white;
/* Initial transforms */
opacity: 0;
transform: translateY(100%);
transition: 0.5s ease;
}
.drawer.is-open {
opacity: 1;
transform: translateY(0);
}
<div>
Link To Show Drawer
</div>
<div class="drawer" id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a data-drawer="#drawer-01" href="#!">Close The Drawer</a>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Toggle animate panel in pure JavaScript and .classList.toggle()
If you don't want to use jQuery only because of such a simple task, here's in vanilla JavaScript:
const toggleDrawer = (evt) => {
evt.preventDefault();
document.querySelector(evt.target.getAttribute('data-drawer')).classList.toggle('is-open');
}
document.querySelectorAll('[data-drawer]').forEach(btn => btn.addEventListener('click', toggleDrawer));
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0c1f3f;
overflow-y: scroll;
color: white;
/* Initial transforms */
opacity: 0;
transform: translateY(100%);
transition: 0.5s ease;
}
.drawer.is-open {
opacity: 1;
transform: translateY(0);
}
Link To Show Drawer
<div class="drawer" id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a data-drawer="#drawer-01" href="#!">Close The Drawer</a>
</div>
</div>
Toggle animate panel in pure HTML + CSS and a hidden checkbox
Need support for no-JS environment? Here you go
.drawer-button {color: blue; cursor: pointer;}
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0c1f3f;
overflow-y: scroll;
color: white;
/* Initial transforms */
opacity: 0;
transform: translateY(100%);
transition: 0.5s ease;
}
.drawer-toggler:checked+.drawer {
opacity: 1;
transform: translateY(0);
}
<label class="drawer-button" for="drawer-01">SHOW DRAWER</label>
<div>Other HTML here...</div>
<input id="drawer-01" class="drawer-toggler" type="checkbox" hidden>
<div class="drawer">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<label class="drawer-button" for="drawer-01">CLOSE DRAWER</label>
</div>
</div>
If you're able to give the .drawer a fixed height, then you can change the bottom property to initially be negative that amount.
Be sure to also add the opacity to the transition, otherwise it will instantly hide instead of fading out gently.
$(".drawer-link").click(function(e) {
var vdata = $(this).data("id");
$(".drawer[data-id=" + vdata + "]").addClass("open-drawer");
e.preventDefault();
});
$(".close").on("click", function(e) {
$(".drawer").toggleClass("open-drawer");
e.preventDefault();
});
body {
padding: 20px;
}
.drawer {
position: fixed;
height: 150px;
bottom: -150px;
width: 100%;
left: 0;
background: #0c1f3f;
padding-top: 90px;
overflow-y: scroll;
transition: bottom 0.5s ease, opacity 0.5s ease;
color: white;
opacity: 0;
}
.wrapper {
width: 100%;
max-width: 1140px;
margin: 0 auto;
}
.open-drawer {
bottom: 0px;
opacity: 1;
}
.close {
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a class="drawer-link" href="#" data-id="drawer-01">Link To Show Drawer</a>
</div>
<div class="drawer" data-id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a class="close" href="#">Close The Drawer</a>
</div>
</div>
So, I have a box of content that has a title and a description, which are positioned at the bottom of the div. Initially, the description is hidden. What I'm trying to do is when you hover over the div, the title should move up and reveal the description, which has a dynamic height.
Here's what I have now: https://codepen.io/tayanderson/pen/qJrmXE
The problem is that it wouldn't display correctly if the description was 1 line or 3 lines. The title div should move up depending on the size of the description div.
Here's an example of what I'm trying to do
HTML
<div class="grid-item" style="background-image: url(https://source.unsplash.com/WLUHO9A_xik/1600x900);">
<div class="title">Title</div>
<div class="desc">Lorem ipsum dolor sit amet, consectetur</div>
</div>
CSS
.grid-item {
height:300px;
background-size: cover;
width:300px;
position: relative;
overflow: hidden;
color: #fff;
.title {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
padding: 0 20px;
}
.desc {
position: absolute;
bottom: 0;
transform: translateY(100%);
padding: 5px 20px;
}
&:hover .title {
bottom: 30%;
}
&:hover .desc {
transform: translateY(0%);
}
}
It this what you meant?
.inner, .inner:hover .grid-item.inner {
-webkit-transition:all linear 0.2s;
transition:all linear 0.2s;
}
.inner {
background: #afa;
width: 300px;
overflow: hidden;
position: absolute;
}
.grid-item:hover .inner{
margin-top: -100px;
}
<a class="grid-item" href="{{ .Permalink }}" style="background-image: url(images/recipes/{{.Params.image}})">
<div class="inner"><h3 class="title is-3">{{.Title}}</h3></div>
<div class="content"><p class="grid-item-blurb">{{.Description}}</p></div>
</a>
Note that I reversed the order of the inner elements.
.body {
background: #aaf;
height: 100px;
width: 300px;
overflow: hidden;
}
.inner, .content {
transition: all linear 0.2s;
}
.content {
height: 100%;
}
.inner {
background: #afa;
transform: translateY(100%);
top: 100%;
}
.body:hover .inner,
.body:hover .content {
transform: translateY(-100%);
}
<div class="body">
<div class="content">
Blue is a viewport (<body>, visible part of a page), which content should be compressed upon green slide-in
</div>
<div class="inner">Green is variable-height text which slides in on viewport hover</div>
</div>
I have a container and in the container are two sections, both at 50% width. In the right side container is an image. I want the left and right boxes to both be the same height at all times and the image to always be 50% width at all times as well.
I cannot figure out how to always keep the image at full height and width of the container without completely making the image look awful. Even if some parts of the image are cut out, that would be fine.
How can I go about doing this?
html, body {
margin: 0;
padding: 0;
}
#box-container {
width: 100%;
height: auto;
}
#box1, #box2 {
width: 50%;
height: 500px;
display: inline-block;
}
#box1 {
background: blue;
}
#box2 {
}
#box2 img {
width: 100%;
height: auto;
}
<div id="box-container">
<div id="box1">
</div><div id="box2">
<img src="http://optimumwebdesigns.com/images/demolition1.jpg" alt="">
</div>
</div>
you have to give the image height:100%; and width:auto; and to the container overflow:hidden;
html, body {
margin: 0;
padding: 0;
}
#box-container {
width: 100%;
height: auto;
overflow:hidden;
}
#box1, #box2 {
width: 50%;
height: 500px;
display: inline-block;
}
#box1 {
background: blue;
}
#box2 {
}
#box2 img {
width: auto;
height: 100%;
}
<div id="box-container">
<div id="box1">
</div><div id="box2">
<img src="http://optimumwebdesigns.com/images/demolition1.jpg" alt="">
</div>
</div>
I believe flex could make it. You could use bootstrap row class, like this:
div class="row" style="display:flex;"
and then, instead of box1 and box2, use the classes div class="col-md-6" for each one (they fit half [50%] of the div that contains it). Give it a try. Sorry for the poor english.
#box1, #box2 {
width: 50%;
height: 500px;
display: inline-block;
overflow: hidden;
}
#box2 img {
/* width: 100%; */
height: 100%;
}
I think this is, what you want to achieve
<style>
.boxes{
width:50%;
float:left;
border:1px solid black;
box-sizing:border-box;
height:1000px;
}
img{
max-width:100%;
}
#sectionOne{
background-image:url("http://optimumwebdesigns.com/images/demolition1.jpg");
}
</style>
<div id="wrapper">
<div class="boxes" id="sectionOne">
<!-- <img src="http://optimumwebdesigns.com/images/demolition1.jpg"> -->
</div>
<div class="boxes">
THis is the noather Div
</div>
</div>
Comment out the the #serctionOne part and un comment the <img> tag for another version.
Let's say I have four images inside a div. they all have a width of 5.5%
[_o__o__o__o_]
I want to use javascript to change the target that is moused over (hovered on), and have it look like this:
[_o__O__o__o_]
so I made the width of the target increase
however it also pushes the other elements to the side instead of staying where they are so it's more like:
[_o___O___o__o_]
I don't know how to make the other elements stay exactly where they are instead of being pushed.
The issue is that YES I am successfully able to alter the width.
BUT changing the width of one element pushes the surrounding elements to the respective right and left.
jsbin: https://jsbin.com/zujutamazo/edit?html,css,js,output
You can use flexbox for this one:
.wrapper {
display: flex;
display: -webkit-flex;
display: -moz-flex;
width: 400px;
background-color: red;
}
.item {
position: relative;
width: 25%;
height: 200px;
}
.circle {
position: absolute;
bottom: 20px;
left: 50%;
-webkit-transform: translate(-50%, -50%);
background: white;
width: 20px;
height: 20px;
border-radius: 50%;
transition: all .3s;
}
.item1 { background-color: blue; }
.item2 { background-color: red; }
.item3 { background-color: orange; }
.item4 { background-color: yellow; }
.item:hover .circle{
background-color: black;
height: 40px;
width: 40px;
}
<div class="wrapper">
<div class="item item1">
<div class="circle"></div>
</div>
<div class="item item2">
<div class="circle"></div>
</div>
<div class="item item3">
<div class="circle"></div>
</div>
<div class="item item4">
<div class="circle"></div>
</div>
</div>
As I was explaining, you need to set a higher z-index to "be above" the non-hovered boxes. And set negative left-right margins, equivalent to the additional width from hovering to prevent everything from moving around.
Below is a working example, with percentages.
body {
width: 300px;
height: 100px;
}
.myClass {
width: 20%;
height: 50%;
position: relative;
z-index: 1;
float: left;
}
.myClass:hover {
width: 30%;
height: 70%;
z-index: 10;
margin: 0 -5%;
}
body .myClass:nth-child(1) {
background-color: red;
}
body .myClass:nth-child(2) {
background-color: green;
}
body .myClass:nth-child(3) {
background-color: blue;
}
body .myClass:nth-child(4) {
background-color: yellow;
}
<html>
<head>
</head>
<body>
<div class="myClass"></div>
<div class="myClass"></div>
<div class="myClass"></div>
<div class="myClass"></div>
</body>
</html>
I was trying to build an interface where when you click a button a full sized div with all it's content fills up the whole screen. There are two sliding divs, it works one way, but the other way the div slides under the first div.
I was attempting to use toggle - and switch to a css that increases the DIVS width property to take over the screen.
Is there a way to accomplish this? Here is my code and a fiddle at the bottom:
HTML:
<div class="container">
<div class="left">
<div class="one">
<a href="#"><div class="openone">
<div class="vertical-text-one">OPEN ONE</div>
</div></a>
ONE</div></div>
<div class="right">
<div class="two">
<a href="#"><div class="opentwo">
<div class="vertical-text-two">OPEN TWO</div>
</div></a>TWO
</div></div>
<div class="header" >
TOP
</div>
</div>
Javascript:
$(document).ready(function(){
$('.openone').click(function(e){
$('.left').toggleClass('clicked');
});
$('.opentwo').click(function(e){
$('.right').toggleClass('clicked');
});
});
CSS snippet:
.left{
background-color: #06C;
width:50%;
height: 100%;
overflow:hidden;
float:left;
z-index: 1;
transition: width 1s;
}
.left.clicked {
width: 98%;
background-color: #06C;
z-index: 100;
}
.right{
background-color: #3AD;
float:right;
width:50%;
height: 100%;
z-index: 1;
transition: width 1s;
}
.right.clicked {
width: 98%;
background-color: #3AD;
z-index: 100;
overflow: hidden;
}
.two{
position:absolute;
top: 110px;
}
.one{
position:absolute;
top: 110px;
}
.openone {
position: relative;
height: 50%;
width:200px;
background-color: #06C;
left: 101%;
}
.opentwo {
position: relative;
height: 50%;
width:200px;
background-color: #3AD;
left: 0px;
}
http://jsfiddle.net/hmyLrzta/19/
Just expand your coding with this:
$(document).ready(function(){
$('.openone').click(function(e){
$('.left').toggleClass('clicked');
$('.right').toggleClass('hidden');
});
$('.opentwo').click(function(e){
$('.right').toggleClass('clicked');
$('.left').toggleClass('hidden');
});
});
CSS:
.hidden {
display: none;
}
This will render the not active panel invisible using display: none;
http://jsfiddle.net/hmyLrzta/21/