I have a layout that requires a list of items to be organized into two vertical columns. The items are in a single list of <div>
s, with the markup also being re-purposed for mobile, so I don't want to modify the structure.
The problem I have here is that each item has an expanding content area which the user can toggle, and when this content is expanded the vertical space for that column needs to expand downward with the other column staying fixed.
Right now I have a basic solution with floated items, but when I expand the content areas the vertical space expands in both columns instead of just the one.
Here's a link to an example of the functionality as I have it now, and below is a screenshot of what the desired behavior should be.
Is it possible to style this to support the required behavior? Or am I going to have to modify the structure of items in order to get this to work? Thanks in advance for your help!
Absolutely positioned page elements will not affect the position of other elements and other elements will not affect them, whether they touch each other or not. There are four valid values for the float property. Left and Right float elements those directions respectively.
4. What happens to a parent of a "Float"? Parents don't care much about their "Float" children, except that they shouldn't go out of their left or right boundaries. Typically a block element of unspecified height increases its height to accommodate its child elements, but that isn't the case for "Float" children.
The float property specifies whether an element should float to the left, right, or not at all. Note: Absolutely positioned elements ignore the float property! Note: Elements next to a floating element will flow around it.
Clearing Floats The footer should sit below both the sidebar and main content. To clear a float, add the clear property to the element that needs to clear the float. This is usually the element after the floated element. The clear property can take the values of left , right , and both .
Your premise is flawed. Document structure flows left-to-right, top-to-bottom. You will need to make some change to the structure... Easiest would be adding two containers for a left column and a right column. Otherwise, you're in for some tricky absolute positioning markup, and a little funky jquery, which I can only suggest with the addition of some unique IDs for each of the panels.
I would, personally, add ids such as panel1
through panel4
per your example, then use this javascript (or similar) as a jumping off point:
for(var i=1; i<=4; i++) {
$('#panel'+i).css('left', function(index) {
if(i%2 == 0) return "120px";
else return "0px";
});
}
$('.more').click(function(e) {
e.preventDefault();
$(this).parent().children('p').toggle();
var id = $(this).parent().attr("id");
switch( id ) {
case 'panel1':
console.log("panel1 found");
$('#panel3').css('top', function(index) {
var buffer = $('#'+id).height() + 20 + "px";
return buffer;
});
break;
case 'panel2':
$('#panel4').css('top', function(index) {
var buffer = $('#'+id).height() + 20 + "px";
return buffer;
});
break;
default: break;
}
});
With the default values in the css for those panels:
#panel1 { top:0px; }
#panel2 { top:0px; }
#panel3 { top:56px; }
#panel4 { top:56px; }
The less you tweak the html, the more work you'll create in javascript.
edit:
Proposed alternate Javascript to remove need to alter HTML, assuming two elements per row. Since we know the row to be the problem...
var ct = 1
$('#container > div').each(function(index, domEle) {
$(domEle).attr('id', 'panel'+ct);
$('#panel'+ct).css({
'position': 'absolute',
'left' : function(index, value) {
if(ct%2 == 0) return "120px";
else return "0px";
},
'top' : function(index, value) {
return (56 * Math.floor(ct/3)) + "px";
}
});
ct++;
});
$('.more').click(function(e) {
e.preventDefault();
$(this).parent().children('p').toggle();
var id = $(this).parent().attr("id");
switch( id ) {
case 'panel1':
$('#panel3').css('top', function(index) {
var buffer = $('#'+id).height() + 20 + "px";
return buffer;
});
break;
case 'panel2':
$('#panel4').css('top', function(index) {
var buffer = $('#'+id).height() + 20 + "px";
return buffer;
});
break;
default: break;
}
});
Now no changes need be made to the HTML, though you'll want to redo the click function to handle repositioning of elements after a click. I would make life easy and hide all .more
items before expanding a new box, since it would mean having to calculate the heights of all elements above, but how much work you want to make is your business.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With