Reputation: 4098
I am building a simple push-down effect which affects the position of two containers. So far I have managed to achieve a near-desired effect using fixed
positioning for the hidden container while changing its position to a relative
for the opened state.
I want to apply a smooth transition to the blue main
div, which is being pushed down by the hidden div with a class of .sub-header
. How can I bypass the choppy rearrangement of the containers and is there a more elegant way of doing this instead of switching positioning on click? (e.g. fixed
to a relative
in this case)
Currently, when I switch the positioning from fixed
to a relative
as expected - there is a gap being produced, which is the .sub-header
's height.
NOTE: The heights of the current divs are fixed values, but I need this to be able to handle dynamic changes in the
.sub-header
height.NOTE: This should be achieved by adding a custom class, not using jQuery's nested effects like
.slideToggle
etc.
Here is the Fiddle.
And the simple jQuery function needed for the Fiddle share:
$('.trigger').click(function() {
$('.sub-header').toggleClass('opened');
}).stop();
Upvotes: 1
Views: 93
Reputation: 11291
Correct me if I misunderstood your question, but I guess there's much simpler approach to what you're trying to achieve. Try changing corresponding classes in your CSS code:
.sub-header {
background: gainsboro;
height: 0;
-webkit-transition: height .3s linear;
transition: height .3s linear;
}
.opened {
height: 150px;
}
Here's the fiddle. My approach does not cover all bases, as you can see there is still text visible in the hidden container, which is going to need some additional workaround in your js or css, but I guess it is simpler than yours, considering that your .sub-container
has fixed height
.
EDIT
For non fixed height, there is workaround in my approach:
.sub-header {
background: gainsboro;
height: auto;
max-height: 0px;
-webkit-transition: max-height .3s linear;
transition: max-height .3s linear;
}
.opened {
max-height: 400px;
}
but it still needs to be adjusted - when you set .opened
's max-height
to the lower value, transition
is going to be slower. It is not perfect, thought it covers cases, where .sub-container
s' heights are relatively similar.
Upvotes: 1
Reputation: 1725
please check this out. we can use margin for styling and keep position the same relative
$('.trigger').click(function() {
$('.sub-header').toggleClass('opened');
}).stop();
body {
font-family: 'Helvetica Neue', 'Helvetica', Arial, sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
}
header,
.sub-header,
main {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
flex-direction: column;
font-weight: bold;
text-transform: uppercase;
color: #fff;
transition: all .5s ease-in-out;
}
header {
height: 100px;
background: tomato;
z-index: 1000;
position: relative;
}
.sub-header {
height: 150px;
background: gainsboro;
transform: translateY(-200%);
left: 0;
right: 0;
z-index: 10;
/*play with position and margin*/
position: relative;
margin-bottom:-200px;
}
.opened {
transform: translateY(0%);
margin-bottom:0;
}
main {
height: 250px;
background: deepskyblue;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<header>Header content <a href="#" class="trigger">TRIGGER</a></header>
<div class="sub-header">
<p>Sub Header content</p>
</div>
<main>Main Content</main>
Upvotes: 0
Reputation: 7015
Make position: relative;
and do margin top for animating
$('.trigger').click(function() {
$('.sub-header').toggleClass('opened');
}).stop();
body {
font-family: 'Helvetica Neue', 'Helvetica', Arial, sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
}
header,
.sub-header,
main {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
flex-direction: column;
font-weight: bold;
text-transform: uppercase;
color: #fff;
transition: all .5s ease-in-out;
}
header {
height: 100px;
background: tomato;
z-index: 1000;
position: relative;
}
.sub-header {
height: 150px;
background: gainsboro;/*
transform: translateY(-200%);*/
margin-top:-150px;
left: 0;
right: 0;
z-index: 10;
position: relative;
}
.opened {/*
transform: translateY(0%);*/
margin-top:0;
}
main {
height: 250px;
background: deepskyblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>Header content <a href="#" class="trigger">TRIGGER</a></header>
<div class="sub-header">Sub Header content</div>
<main>Main Content</main>
Update:-
As to get -100%
you have make it float and set all width to 100%
$('.trigger').click(function() {
$('.sub-header').toggleClass('opened');
}).stop();
body {
font-family: 'Helvetica Neue', 'Helvetica', Arial, sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
}
header,
.sub-header,
main {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
flex-direction: column;
font-weight: bold;
text-transform: uppercase;
color: #fff;
transition: all .5s ease-in-out;
}
header {
width:100%;
height: 100px;
background: tomato;
z-index: 1000;
position: relative;
}
.sub-header {
height: 150px;
width:100%;
background: gainsboro;/*
transform: translateY(-200%);*/
margin-top:-100%;
left: 0;
right: 0;
z-index: 10;
float:left;
}
.opened {/*
transform: translateY(0%);*/
margin-top:0;
}
main {
width:100%;
height: 250px;
background: deepskyblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>Header content <a href="#" class="trigger">TRIGGER</a></header>
<div class="sub-header">Sub Header content</div>
<main>Main Content</main>
Upvotes: 2