Collapsible panel and space filling - javascript

I have a div which contains three more divs. The first one is a toolbar that can be collapsed (red in the example). It has a fixed height. The second one (black) has to fill all the remaining space, and must expand if the red one is collapsed. The third one (green) is in fact a button attached to the bottom of the red div. When the user clicks on it, it collapses or expands the red div.
<div id="container">
<div id="tools">
</div>
<div id="hider">
</div>
<div id="work-area">
</div>
</div>
I made an example on jsfiddle : https://jsfiddle.net/gpoa8s92/3/
I don't see how to make the black div take all the remaining space. I tried using a flexbox, and it works, but the green div isn't attached to the bottom of the red div anymore.
Is there a solution using ass less javascript as possible ?
Thank you !

I think your solution can be achieved with flexbox, just put tools and work area as siblings and for first set static height, flex-grow: 0 and flex shrink: 0, and for work area set height: 100%, flex-grow: 1 and flex shrink: 1.
This will make tools to occupy 100px and work area remaining place.
Since the toggle button is part of tools you can put it inside it, and move it outside using position: absolute and top: 100%, and give tools position: relative to stick toggle button to its bottom.
Now you can create a class for tools that set its height: 0 and animate it with CSS transitions.
Then on toggle button click, you can toggle a class on tools and it should be as you wanted.
Toggling tools height could be done without javascript- it would be a bit confusing but more accessible, here's an example of that: https://codepen.io/morganfeeney/pen/KiBty
Prepared an example for you - I've used BEM methodology for naming elements and cached used elements as variables.
const $toggleButton = $('.js-tools-toggle');
const $toggleContent = $('.js-tools-root');
const collapsedClass = 'tools--collapsed';
$toggleButton.on('click', function() {
$toggleContent.toggleClass(collapsedClass);
})
.container {
display: flex;
flex-direction: column;
height: 400px;
background-color: blue;
}
.tools {
transition: height 250ms ease-in-out;
position: relative;
display: flex;
flex-direction: column;
height: 100px;
}
.tools--collapsed {
height: 0px;
}
.tools__content {
height: 100%;
background-color: green;
overflow: hidden;
}
.tools__action {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
height: 20px;
background-color: red;
}
.work-area {
background-color: black;
flex: 1 1 auto;
height: 100%;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="tools js-tools-root">
<div class="tools__content"> Content of tools</div>
<div class="tools__action js-tools-toggle">
toggle
</div>
</div>
<div class="work-area">
content of work area
</div>
</div>

Related

How would I create a div container with three divs in a row where the divs on both sides expand away from the center when an event is triggered?

I want to create a div that has three nested divs touching each other in a row. I want the div at the center of this container to have a constant width. While I want the left div's width to expand to the left(i.e. not pushing the other two divs in the container to the right) on hover and stay expanded on click. I want the same thing to happen to right div's width except it expands to the right. All the nested divs would have content in them some of the content not completely visible until the div expands.
This would be the general idea:
When Neither is Hovered -->
enter image description here
When One Is Hovered -->
enter image description here
When They Are Both Clicked -->
enter image description here
The problem is I haven't been able to figure out a way to do this or find out if there is a tutorial or something that would be helpful in accomplishing this. I have tried googling how to create this, and in all honesty was not to sure exactly what to search up but nothing has really helped me get both divs expanding the way I want. I would appreciate any help in finding a tutorial or any implementation that might work.
So far I have been able to get this far in terms of coding it in HTML and CSS, but have been stuck for a while with no attempt being closer than this. I would need this to be on top of other elements on a page in my webpage hence the z-index, and positioning is so that I could move it to my desired place on the webpage. I am able to get the right div to expand how I want easily as that is the default behavior but when I try to get the left div and right div to both expand I have been stuck. I have gotten the left div to expand at one point but that led to the right div not working. So right now this is the closest I have gotten both expand properly but the left div is under the center div instead of beside it.
I added a bit of a yellow background in the images to give an idea of positioning
Result on Webpage No Hover -->
enter image description here
Result on Webpage On Hover Of Left Div-->
enter image description here
Result on Webpage On Hover Of Right Div-->
enter image description here
HTML-->
<div class="sliding-window">
<div class="left-wing">
</div>
<div class="middle-box">
<h3>Content</h3>
</div>
<div class="right-wing">
</div>
</div>
CSS-->
.sliding-window{
display: flex;
flex-direction: row;
/* justify-content: center; */
z-index: 25;
position: absolute;
top: 30%;
left: 35%;
width: 850px;
}
.middle-box{
left: 250px;
border: 1px red solid;
text-align: center;
height: 300px;
width: 250px;
border-radius: 10%;
background-color: grey;
}
.left-wing{
border: 1px violet solid;
height: 250px;
/* float: left; */
position: relative;
float: left;
left:200px;
margin-top: 25px;
margin-bottom: 25px;
width: 50px;
background-color: grey;
}
.right-wing{
left:450px;
border: 1px green solid;
height: 250px;
margin-top: 25px;
margin-bottom: 25px;
width: 50px;
background-color: grey;
}
.right-wing:hover{
width: 200px;
}
.left-wing:hover{
width: 200px;
/* margin-left: -200px; */
}

css square limit size and position to parent div

I am trying to get a square to have a limited size and stay within the bounds of the parent div and scale cleanly. I can get one or two of these, but not all.
Setup is I have a main div, two column divs on the left, and a div that takes up the remaining space on the right. I would like the div on the right to contain the square and the bounds of the square stay within the parent div. I can get it to stay put if I don't use the padding-bottom to keep it square, but then the pic of the item looks horrible.
Take a look at my js bin. The pathway to hit the square is:
Weapons -> item b1 -> click on it to make it stay
The padding-bottom pushes it way down and outside of the parent div and blows the bottom out of the whole thing.
css
.itempanel{
display: block;
align-items: center;
position: relative;
}
.itemcontainer{
position: relative;
top: 30%;
height: 60%;
width: auto;
margin-left: auto;
margin-right: auto;
}
.itemdisplay{
display:none;
flex-direction: column;
width: 60%;
padding-bottom: 60%;
margin-left: auto;
margin-right: auto;
position: relative;
align-items: center;
overflow: hidden;
}
/* .itemdisplay::after{
content: " ";
display: block;
padding-bottom: 100%;
} */
html
<div class="itempanel">
<div class = "itemcontainer">
<div id="itemdisplay" class="itemdisplay">
<img id="itemimg" class="itemimg" src=""></img>
<div id="itemdesc" class="itemdesc">
<div id="itemtitle" class="itemtitle"></div>
<div id="itembody" class="itembody"></div>
<a id="itemclick" class="itemclick" href="">Click To Place Order</a>
</div>
</div>
</div>
</div>
Thanks for any help!
*little bit of background - girlfriend wants a skyrim wedding so building out a website for rsvp and stuff. Belethor's shop is going to be setup to help those not so nerdy shop for cheap cosplay outfits. Everything else works just like I want it, but the itempanel/itemcontainer/itemdisplay is not in the display area how I want it.
figured it out. The psuedo element has to be opposite what padding you are using. For instance, using this worked like I expected it to. it's always the simple things...
.itemdisplay::after{
content: " ";
display: block;
padding-top: 100%;
I see that you have created a class .bottommenu but I don't see it being applied anywhere on your HTML or JavaScript. If you want to display two rows using Flex-box and you are not quite sure of the height of your images or content, you could set that parent container to have a height: auto and on your child container you could use the align-self: flex-end to handle the positioning of items, and on your parent use the justify-content or align-content to your liking. Something like this:
div .parent {
display:flex;
height: auto;
min-width: 300px;
}
div .child {
align-self: center;
width: 100%;
min-height: 50%;
height: auto;
margin: 0 auto;
}
Hope that helps.

make a div fit into whitespace if possible, else grow in size

my question is rather complicated.
In my layout i have a left column and a right column. For example 30% and 70% width. below them there is another item, now theres the challenge:
if my 30% column is higher than the 70% column the "challengeblock" should fill on the right side.
if the right side is the higher one the "challengeblock" should be on the bottom with 100% width.
Here I made an example:
https://jsfiddle.net/by6tkg7L/
The green one should fit on the right in this code.
I tried it with
flex-grow
in this case, but also had a try with grid (not to experienced there so seems like I need to read some more first)
I´m also open for masonary layouts like with isotope, but found no way so far to make it fill OR make it grow depending on the rest.
I would ofcourse prefer a CSS-only way and would like to avoid calculating with JS.
Tahnks in advance
Css only solution. Working fiddle: https://jsfiddle.net/by6tkg7L/1/
To be able to see it working you have to change height of the blue block (class .right_top).
I only modified the css, i used block and inline-block on the child elements (with float: left) and i've set flex only on the question element setting a min-width and a max-width instead of a static width.
CSS:
.wrapper{
display: block;
width: 100%;
flex-wrap: wrap;
flex-direction: row;
}
.left{
background-color: red;
height: 500px;
width: 30%;
display:inline-block;
float:left;
}
.right_top{
background-color: blue;
height: 500px;
width: 70%;
display:inline-block;
float:left;
}
.question{
min-width: 70%;
width: auto;
max-width: 100%;
background-color: green;
height: 300px;
display:flex;
}
HTML:
<div class="wrapper">
<div class="left">
</div>
<div class="right_top">
</div>
<div class="question">
</div>
</div>

Positioning below absolutely positioned divs

I have two <div>s with absolute position. One is displayed and the other is display: none on load. When the link on the visible one is clicked it is moved and the other is displayed.
I have a third <div> with link that I would like to display directly below these. Since they’re both position: absolute I have not been able to find a way to do this. I have found various solutions, but most of them are workarounds for using absolute position. Since my <div>s need to show ontop of each other I unfortunately can’t remove the absolute positioning.
As such I have tried various combinations of position: absolute and position: relative on the three <div>s, but so far nothing has worked.
JSFiddle with my problem: https://jsfiddle.net/dagz9tLw/1/
<div> with id linkbar is the one that needs to be at the bottom.
The other two <div>s don’t have a set height so margin-top won’t work. linkbar also needs to be just below the <div>s and not right at the bottom of the page.
I experienced that using a div acting as a buffer is quite useful and easy to implement for this purpose. You just set it above your div#linkbar and adjust it's height on load and when the div#front get's repositioned:
$("#topBuffer").css("height", $("#front").offset().top + $("#front").height());
$("#showLink").click(function() {
if (!$("#back").is(":visible")) {
$("#back").show();
$("#front").animate({
'marginLeft': "+=30px"
});
$("#front").animate({
'marginTop': "+=20px"
});
$("#topBuffer").animate({
'height': "+=20px"
});
}
return true;
});
.front {
width: 400px;
display: block;
border: 2px solid #000000;
text-align: center;
position: absolute;
margin-top: 20px;
z-index: 10;
background-color: white;
}
.back {
display: none;
width: 400px;
border: 2px solid #000000;
text-align: center;
position: absolute;
z-index: 1;
margin-top: 20px;
background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="front" class="front">
<a id="showLink" href="javascript:void(0);">front</a>
</div>
<div id="back" class="back">
back
</div>
<div id="topBuffer"></div>
<div id="linkbar">
test
test
test
</div>

Put two 100% width divs side-by-side

So if I want to have two divs, each of 100% of the entire page, side by side, given that the wrapper has overflow:hidden, how should I go about implementing it?
I have tried using inline-block but it did not work.
I have tried using float too but it caused errors.
I want the second div to be hidden so I can change it's left as an animation, sort of like a slide.
Thanks in advance!
If I've understood you correctly, you can achieve what you're after using inline-block. You just have to be a little careful with white space (i.e. you need to make sure you've got no white space between the two child div elements). I've stopped the divs from wrapping by setting white-space: nowrap;.
<div class="foo">
<div> woo woo !</div><div> woo woo !</div>
</div>
.foo {
overflow: hidden;
white-space: nowrap;
}
.foo > div {
display: inline-block;
vertical-align: top;
width: 100%;
background: aqua;
}
.foo > div + div {
background: lime;
}
Try it out at http://jsfiddle.net/8Q3pS/2/.
Edit: Here's an alternative implementation using position: absolute;: http://jsfiddle.net/8Q3pS/5/. That way you'll be able to animate the second one into view using left. Note that you'll need to set a height on the parent div.
.foo {
position: relative;
width: 100%;
height: 1.5em;
overflow: hidden;
}
.foo > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
background: aqua;
}
.foo > div + div {
left: 100%;
background: lime;
}
This should be purely a matter of positioning one of the divs off the page using absolute positioning and transitioning the left property using either hover state or javascript.
Hover the red div.
Codepen Example
Could you not set max-width to 100%, not set the actual width and float them side by side? With both overflow:hidden, as they expand it should create horizontal scrollbars.

Categories

Resources