Reveal a div with dynamic height underneath another div inside a container? - javascript

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>

Related

How to keep rotated banner text vertically centred, despite length of string?

As part of a project, I need to have a banner/strip of text over the corner of our images, only showing as much of the container as there is text (give or take a bit of padding). But the length of the string varies, which means the means I can't simply use top/left as you usually would.
This picture shows the desired end goal:
Here is the core HTML/CSS but I can't figure out how to make this responsive in the way it needs to be? Is there a CSS solution or is probably JS with math?
<div class="image">
<img src="image.jpg">
<div class="banner">
<span class="banner-text">Banner Text</span>
</div>
</div>
<style>
.image {
position:relative;
}
.banner {
position: absolute;
width: 100%;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
}
</style>
you can try to move down the text before rotation taking into account its length using the way vertical padding is calculated when percentage is used.
here is a few example : (see comment in css)
figure {position:relative;
overflow:hidden;}
figcaption {
position:absolute;
top:0;
padding:0.5em 3em 0.5em 2em;/* tune padding here*/
background:linear-gradient(to top, green 2.25em, transparent 2.25em);/* draw only one line average background*/
transform:rotate(-45deg);
transform-origin:bottom left;
box-sizing:border-box;/* include padding and border*/
min-width:150px;/* tune this to have a minimal width and way down*/
}
/* push me down */
figcaption:before {
content:'';
display:inline-block;
padding-top:90%/* 90% of my parent's width which i figcaption*/
}
<figure>
<img src="http://dummyimage.com/300x128">
<figcaption>caption </figcaption>
</figure>
<figure>
<img src="http://dummyimage.com/300x128">
<figcaption>caption text</figcaption>
</figure>
<figure>
<img src="http://dummyimage.com/300x128">
<figcaption>longer caption text</figcaption>
</figure>
<figure>
<img src="http://dummyimage.com/300x128">
<figcaption>bit longer caption text</figcaption>
</figure>
<figure>
<img src="http://dummyimage.com/300x300">
<figcaption>tiny bit longer caption text</figcaption>
</figure>
here is an animated demo to show the padding effect in action , for ribbons on the left and on the right side
figure {
position: relative;
overflow: hidden;
display: inline-block;
margin:0;
}
.left figcaption {
position: absolute;
top: 0;
padding: 0.5em 3em 0.5em 2em;
/* tune padding here*/
background: linear-gradient( to top, green 2.2em, transparent 2.25em);
/* draw only one line average background*/
transform: rotate(-45deg);
transform-origin: bottom left;
box-sizing: border-box;
/* include padding and border*/
min-width: 150px;
/* tune this to have a minimal width and way down*/
/* animation for demo */
animation: txtin 2s steps(4) alternate infinite;
word-spacing: 2em;
color: white
}
/* push me down */
.left figcaption:before {
content: "";
display: inline-block;
padding-top: 94%;
/* 90% of my parent's width which i figcaption*/
}
.right figcaption {
position: absolute;
top: -3.5em;
right: -6em;
padding: 0.5em 4em;
/* tune padding here*/
background: green;
/* draw only one line average background*/
transform: rotate(45deg);
transform-origin: bottom left;
box-sizing: border-box;
/* include padding and border*/
min-width: 12.5em;
/* tune this to have a minimal width and way down*/
overflow: hidden;
/* demo */
animation: txtin 2s steps(4) alternate infinite;
word-spacing: 2em;
color: white
}
#keyframes txtin {
to {
text-indent: -21em;
color: yellow
}
}
<figure class="right">
<img src="http://dummyimage.com/300x300/0af/&text=right_ribbon_of_any_length">
<figcaption>ribbon animated demo</figcaption>
</figure>
<figure class="left">
<img src="http://dummyimage.com/300x300/0df/&text=left_ribbon_of_any_length">
<figcaption>ribbon animated demo</figcaption>
</figure>
After a little bit of digging I found the following solution.
.parent {
overflow: hidden;
/* required */
width: 50%;
/* for demo only */
height: 250px/* some non-zero number */
;
margin: 25px auto;
/* for demo only */
border: 1px solid grey;
/* for demo only */
position: relative;
/* required for demo*/
}
.ribbon {
margin: 0;
padding: 0;
background: rebeccapurple;
color: white;
padding: 1em 0;
position: absolute;
top: 0;
right: 0;
transform: translateX(30%) translateY(0%) rotate(45deg);
transform-origin: top left;
}
.ribbon:before,
.ribbon:after {
content: '';
position: absolute;
top: 0;
margin: 0 -1px;
/* tweak */
width: 100%;
height: 100%;
background: rebeccapurple;
}
.ribbon:before {
right: 100%;
}
.ribbon:after {
left: 100%;
}
<div class="parent">
<h4 class="ribbon"> Hello Special</h4>
</div>
<div class="parent">
<h4 class="ribbon">Very Special Sale Today</h4>
</div>

Slide Up Transition

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>

Hovering a div over another Div where the contents will remain

So, what I want to do is position 2 divs side by side. When I hover over the left div, I want it to expand its width to the full page, while covering the right div. When I hover over the right div, I want to expand the width -100% so it covers the left div. I got them to both sit side by side as well as for the left div to transition to the right 100% and the right div to expand to the left -100%. The main problem I am having is that it will show 100% of the div on either side that it expands to. Here is my code.
As of now I am only using CSS properties, but let me know if some javascript will work better.
HTML code
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
CSS Code
#narrow {
margin-top: 100px;
padding-top: 20px;
float: right;
width: calc(100% - 50%);
height: 400px;
background: lightblue;
transition: width 2s;
z-index: -1000;
}
#narrow:hover {
width: 100%;
}
#wide {
margin-top: 100px;
padding-top: 20px;
float: left;
width: calc(100% - 50%);
background: lightgreen;
height: 400px;
transition: width 2s;
position: absolute;
z-index: 1000;
}
#wide:hover {
width: -100%;
}
Here we go! position: fixed and z-index!
#narrow {
padding-top: 20px;
float: right;
width: 50%;
height: 400px;
background: lightblue;
transition: width 2s;
z-index: 0;
position:fixed;
right:0;
}
#narrow:hover {
width: 100%;
z-index: 1;
}
#wide {
padding-top: 20px;
width: 50%;
background: lightgreen;
height: 400px;
transition: width 2s;
position:fixed;
left:0;
z-index: 0;
}
#wide:hover {
width: 100%;
z-index: 1;
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
Another solution: position both divs absolute, both with a 0 z-index. with one of the having a right: 0; Then, set the width and z-index on hover.
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
#narrow {
margin-top: 100px;
padding-top: 20px;
Float: right;
width: 50%;
height: 400px;
background: lightblue;
transition: width 2s;
Z-index: 0;
Position: absolute; right: 0;
}
#narrow:hover {
width: 100%;
Z-index: 1;
}
#wide {
margin-top: 100px;
padding-top: 20px;
float: left;
width: 50%;
background: lightgreen;
height: 400px;
transition: width 2s;
position: absolute;
Z-index: 0;
}
#wide:hover {
width: 100%;
Z-index: 1;
}
I added some of the common elements to a panel class. Setting your parent as relative gives the child panels a common starting point. Setting the panels as absolute will allow you to position them on the left and right of the window. Adding a z-index of 2 to the panel that is being hovered over brings it over the non-hovered panel.
<div id="parent">
<div class="panel" id="wide">Wide (rest of width)</div>
<div class="panel" id="narrow">Narrow (200px)</div>
</div>
#parent {
position:relative;
width:100%;
height:400px;
overflow:hidden;
}
.panel {
margin-top:100px;
padding-top:20px;
height:100%;
width:50%;
z-index:1;
}
#narrow {
position:absolute;
right:0;
top:0;
background: lightblue;
transition: width 2s;
}
#narrow:hover {
width: 100%;
z-index:2;
transition: width 2s;
}
#wide {
position:absolute;
left:0;
top:0;
background: lightgreen;
transition: width 2s;
}
#wide:hover {
width:100%;
z-index:2;
transition: width 2s;
}

CSS translateY to animate slide down behind a parent element

I'm trying to use transformY to animate the sliding down of an element when you click on a link in the header. The issue i'm having is that the element being displayed is nested a few levels deep and this is what I think is causing the problem - I need the element to slide down from behind the parent elements. Setting z-index doesn't appear to work in this context. I've created a JS Fiddle below - grateful for any help! In this demo, the green parent container should be sitting on top of the yellow hidden element.
jQuery('.test-link').on('click', function(e) {
e.preventDefault();
jQuery('.container').toggleClass('active');
});
.outer-container {
background: green;
width: 100%;
position: relative;
z-index: 5;
}
.container .hidden-content {
transition: all 0.2s ease;
transform: translateY(-100%);
position: absolute;
z-index: -1;
z-index: 1;
width: 100vw;
left: 0;
right: 0;
background: yellow;
}
.test-link {
margin-left: 100px;
display: block;
position: relative;
z-index: 3;
width: 200px;
background: red;
}
.container.active .hidden-content {
transform: translateY(0%);
}
.other-content {
position: relative;
z-index: 4;
background: blue;
}
.test-content {
position: relative;
z-index: 5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="outer-container">
<div class="test-content">
<div class="container">
TEST LINK
<div class="hidden-content">
<h1>My Hidden Content</h1>
<h1>My Hidden Content</h1>
</div>
</div>
</div>
<div class="other-content">
<h2>This should be overlaid by the sliding out content</h2>
</div>
</div>
You can do that with a negative z-index
jQuery('.test-link').on('click', function(e) {
e.preventDefault();
jQuery('.container').toggleClass('active');
});
.another-container {
position: relative;
z-index: 1;
}
.outer-container {
background: green;
width: 100%;
position: relative;
}
.container .hidden-content {
transition: all 0.2s ease;
transform: translateY(-100%);
position: absolute;
background: yellow;
z-index: -1;
}
.test-link {
display: block;
position: relative;
width: 200px;
background: red;
}
.container.active .hidden-content {
transform: translateY(0%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="another-container">
<div class="outer-container">
<div class="test-content">
<div class="container">
TEST LINK
<div class="hidden-content">
<h1>My Hidden Content</h1>
<h1>My Hidden Content</h1>
</div>
</div>
</div>
</div>
</div>
<div>yellow box should be on top</div>

Button activated div slide goes under instead of over

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/

Categories