CSS box "flow"/stacking (see screenshot) - css

I'm having a hard time making boxes flow as illustrated in the attached screenshot. Seeing as I'm not even quite sure what this technique is called, it's making googling hard.
The boxes with be generated using jQuery's AJAX implementation if that makes a difference.
UPDATE:
Thanks Jonathan, that's close but it's apparent I haven't described the problem well enough. Each box contains a categoryHeading, and an unknown number of records (bookmarks) related to that heading -- might be two, might be 50.
Let's say I have six bookmark categories (boxes). Since users can enter as many or few bookmarks as they please into each category (which is also unlimited), I really don't know how big any of the boxes will be.
In the newly attached illustration, this is illustrated better, I hope.
I'd prefer not to be stuck with a fixed number of columns, since the container width depends on the screen resolution of the user.. so low resolution might only have room for two columns, while higher resolution/bigger browser width has room for five columns.
I can somehow mimick this using http://welcome.totheinter.net/columnizer-jquery-plugin/, but it's not perfect, and IF there's a strickly CSS way of doing it, that'd be much prefered.
Using the code Jonathan suggested, it would work well if each category contained about the same number of bookmarks and I was ok with using a fixed column layout, but when one category contains 50 bookmarks, while another one only contains three, a lot of space goes to waste.
See: Ole screenshot/illustration
See: New illustration

Nope. If you can't count on the number of columns there is no CSS-only solution (though it looks like there will be in CSS3 - a fun thought). You'll need JS.

It's nothing more than three master columns, with boxes within:
<div class="col1">
<div class="box1">Top Left Box</div>
<div class="box2">Middle Left Box</div>
<div class="box3">Bottom Left Box</div>
</div>
<div class="col2">
<div class="box1">Top Center Box</div>
<div class="box2">Middle Center Box</div>
<div class="box3">Bottom Center Box</div>
</div>
<div class="col3">
<div class="box1">Top Right Box</div>
<div class="box2">Middle Right Box</div>
<div class="box3">Bottom Right Box</div>
</div>
Then it's a matter of giving each box a specific height, and margin-bottom to all.
.col1, .col2, .col3 {
margin:10px 5px;
float:left;
width:100px;
}
.col1 div, .col2 div, .col3 div {
margin-bottom:10px;
}
.col1 .box1 {
height:100px;
}

Related

Responsive design broken

I'm making a website with bootstrap. Got an element from a theme and used it. The element is a picture on the left and text on the right. This also scales right on tablet and mobile.
Now i have changed the element to text on the left and a picture on the right. But with this part the responsive design doesn't work anymore. Can't figure out why.
This is the url click
On the parts where i changed the element the picture disappears when scaling to tablet or phone size
So I think that's a pretty nice web page. And I do understand why this example doesn't fit cleanly into a JSfiddle, nor can it easily be pushed into a minimal example.
I do see the issue with disappearing image when you go to a narrow display device. So I'm thinking your issue lies here...
<style type="text/css">
.no-padding.img-2 {
background: url(http://fakeimg.pl/300/) scroll center no-repeat;
background-size: cover;
position: absolute;
height: 100%;
}
.no-padding.img-3 {
background: url(http://fakeimg.pl/300/) scroll center no-repeat;
background-size: cover;
height: 560px;
}
</style>
Image-2 is your image pushed left implementation, Image-3 is your image pushed right implementation. They definitely don't have the same CSS... And I think the same issue is there with your matching block text as well. Position: Absolute, Height:100% vs fixed pixel height will result in odd output.
I also don't understand the choice of classes between the left / right elements:
<div class="col-sm-6 no-padding img-2 ">
vs
<div class="col-sm-6 col-sm-offset-6 no-padding gray">
Why the .col-sm-offset-6 even there at all? Reference here. The .col-sm-offset-X class forces things to go to an offset, in this case it pushes the element to the right side of the screen, BUT if you have even one width pixel issue, then it pops the element over and down, and that can get ugly. Why not just let everything float?
Short answer.
Lose the .col-sm-offset-6 Clean up the CSS for images (lose the position: absolute ) Works fine in my browser.
Edit. Ouch. I didn't see the comment from #AndyHolmes until just now. I was busy testing and writing this answer. Looks like he beat me by one minute.
I think that accepted answer, unfortunately, doesn't identify the real problem with your layout, and introduces even bigger problems itself, like a need for manual setting of heights of image containers.
(I've replicated original issue in this JSFiddle)
Your problem can be reduced to the issue of setting equal heights on two adjacent floated columns. This is kind of well-known problem in a design world, and this topic is tackled in this post by Chris Coyer.
I get to the conclusion that you could take a slightly different approach to that problem. By going with mobile first, you could make your life easier and reduce the amount of code. You build basic 1 column layout first, and the only thing you need to assume here is height of your image containers.
Since this is 1 column layout it is better to fix height of images here, as they do not depend on height of the adjacent columns.
To increase a size of your viewport, you'll use media queries to set up a breakpoint where 1 column layout becomes 2 column layout with both columns set next to each other. Now this is the point where you problem of same height columns comes in. On one hand you want your background image container to grow vertically in the same way as other column's content grow.
This is where flexbox come to the rescue if you only want to use it. What it does is it equals both columns heights automatically, which relieves you from setting up each image containers heights manually, and this is great I think. You are getting a flexible, fluid and mobile-first layout, with the minimal amount of code (and no dependency on bootstrap, which is always a bonus in my opinion), which can fit any given amount of content.
I simplified and replicated the desired layout in this minimal JSFiddle, so feel free to adapt it to your needs.
.row {
display: block;
overflow:hidden;
background: #f0f0f0;
width:100%;
margin-bottom:10px;
}
.bgImg,
.text {
width:100%;
}
.bgImg {
background: url("http://placehold.it/350x150") no-repeat center center;
background-size: cover;
height: 150px;
}
h4 {
margin-top:0;
}
#media (min-width: 768px) {
.row {
display:flex;
}
.bgImg,
.text {
width:50%;
float:left;
}
.bgImg {
height: initial;
}
}
<section class="row">
<div class="bgImg"></div>
<article class="text">
<h4>Blah</h4>
<p>Some nonsense</p>
</article>
</section>
<section class="row">
<article class="text">
<h4>Blah</h4>
<p>Some nonsense</p>
<p>Some nonsense</p>
<p>Some nonsense</p>
<p>Some nonsense</p>
<p>Some nonsense</p>
<p>Some nonsense</p>
</article>
<div class="bgImg"> </div>
</section>
<section class="row">
<div class="bgImg"></div>
<article class="text">
<h4>Blah</h4>
<p>Some nonsense</p>
<p>Some nonsense</p>
<p>Some nonsense</p>
</article>
</section>

Floating divs, equal height - fill space with additional div without overflow

I have two div-columns of different height which I like to have the same height. I achieved this using the padding-margin hack with the following css for my div-columns:
.lane1 {
padding-bottom: 800px;
margin-bottom: -800px;
}
The html is displaying a flow-diagram. I would like to have a line from the end of each lane to the bottom of the two-lane part to have a continuous diagram.
I tried to achieve this with an additional div with class .LineFilling that is a line going down, but I don't know how heigh the line should be. So I put
position: absolute;
overflow: hidden;
in the .lane1-class and made the .LineFilling-element of height 600px, but that doesn't work, since the overflow is displayed. Is there a way to have the .LineFilling-element extend to the end of the lane? Or extend further but the overflow being cut?
Thanks for help.
EDIT: I posted the code online here: Click here to see code
Yes it is possible with pure css.
I have used display table-row and table-cell properties to achieve it.
HTML:
<div class="parent">
<div class="child">
<p>line 1</p>
</div>
<div class="child">
<p>line 1</p>
<p>line 2</p>
<p>line 3</p>
<p>line 4</p>
</div>
</div>
CSS:
.parent{display:table-row;}
.child{display:table-cell;border:1px solid #ccc;padding:10px;}
p{margin:5px 0;}
See fiddle.
Update: probable solution DEMO
Pure CSS solution
Here is a DEMO of that solution.
In this DEMO, you see multipple Rows,
each Row can have a variable number of columns without stating anything in the markup, and without fixing any width. (the width is always divided evenly between the columns).
Each column is called ElementsHolder, and can have any number of Elements you want.
all the column in a row will always have the same height, and the last arrow in the row will fill that space.
In the DEMO you can see 3 Rows.
The First Row has the starting point, so no stretch needed there.
The Second Row has 3 ElementsHolder, without stating anything special in the markup, 2 of them will stretch to fill the gap.
The Third Row has 2 ElementsHolder, behave as expected.
notice that the stretching works regardless of the Elements height. (some of them have 2 or 3 lines of text, and it works perfectly)
If you want to use that technique, you only have to implement the other kind of boxes and arrows (Curve etc..)
The solution is done by using the new CSS flex model.
the direction is set via flex-direction: row;,
Each row has ElementsHolders that gets equal width.
each one of those ElementsHolder is also a flex box, but this time his direction is opposite (flex-direction: column;).
the child's of ElementsHolder are Elements & Arrows, I dont want them to have equal height, but to span excatly the natural height. except the last arrow, that should span the rest of the container.
all of that is achieved using the flex property with the appropriate values.
More about the flex-model can be found HERE
I don't know if I really understand what you need. I've tried the following
Adding a new absolute element in the laneContainer with height: 100% โ€‹โ€‹
#straightLine {
background-color: #FFBF80;
height: 100%;
left: 104px;
position: absolute;
width: 3px;
z-index: 5;
}
Plus some small modifications to some other objects, you'll find them in the fiddle...
http://jsfiddle.net/RRupc/9/
Is something like that what you want?
Rather than adding another div to fill the space, wouldn't it be easier to add a class to the div on the left column, and style that to fill any spacing/line requirements you have?
So you could have:
HTML:
<div class="twoColumn">
<div class="column">
<div class="step doubleRow">
<p>One step covering two rows here</p>
</div>
</div>
<div class="column">
<div class="step">
<p>Single size step</p>
</div>
<div class="step">
<p>Single size step</p>
</div>
</div>
</div>
have you seen these 2 plugins?
jQuery Isotope
jQuery Mansonry
Eventually there is a solution for you!?
Take a look.
FlexBox could be worth a look too.
if you are ok with IE10 +
Auto Align Heights (CSS)
align-items: stretch
Good Reads here and here
Cheers,
Rob

Stack divs on top of each other in 2 rows without whitespace

I really need your help on this one:
Right now I have divs just on top of each other, filled dynamically with diverse contents so the heights are changing.
What I want to do now is to place them in 2 rows. With a fixed width and "float:left" this kinda works already.
My english is not the very best so pls take a look at my example picture first:
As you can see there is this whitespace because of the third div which doesn't start right beneath the first div because of div number 2 which CAN BE higher as the first div.
I now wonder if there is a possibility to automatically position those divs higher so that there is no whitespace (they always should start right beneath the picture which is above wouth the whitespace, left or right).
LIKE THIS:
I hope you kinda understand what I mean :D Thanks in advance for replys!
EDIT:
Code-Example:
<div id="content">
<div class="xyz">BLABLA</div>
<div class="xyz">BLABLA<br>morebla!<br>EVEN MORE BLA</div>
<div class="xyz">BLABLA</div>
</div>
<style>
#content {
width: 648px;
}
.xyz {
width: 303px;
float: left;
border:1px solid black;
}
</style>
Remeber, heights are always different!
jQuery masonry makes your life a lot easier.. don't reinvent the wheel, especially when you're facing a classic css problem.
this will do it...
<div id="content">
<div class="column1" id="left">
<div id="div1">...</div>
<div id="div3">...</div>
</div>
<div class="column2" id="left">
<div id="div2">...</div>
<div id="div4">...</div>
</div>
</div>
Then just style column2 styles by defining widht values in your css.
Thanks,
#leo.

Effect of overflow:auto on floated divs

Short version: Why does overflow:auto cause a div to the right of a left floated div not to wrap its text around the left floated div? (Bonus: Is this an acceptable way to accomplish a column effect?)
Long version...
I have two divs that I wish to be next to each other, and displayed as columns. The div on the left has a specific width and height. And the div on the left is shorter than the div on the right. However, I do not want the text in the right div to wrap under the left div.
Here was my first attempt...
<div>
<div style="border:1px solid grey;
width:100px;
height:100px;
float:left;">
Div on the left.
</div>
<div>
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>
...I knew the text in the right div would wrap under the left div. And it did.
Then I remembered a page I had created that had a column effect. I had copied and pasted it from I know not where. All it did was assign overflow:auto to the div on the right. It looks like this...
<div>
<div style="border:1px solid grey;
width:100px;
height:100px;
float:left;">
Div on the left.
</div>
<div style="overflow:auto">
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>
Voila, the right divs text no longer wrapped under the first (left) div! The second (right) div appeared as a column.
So, I read everything I could find on overflow:auto and found no mention of why I should see this behaviour. Can anyone explain it to me?
Also, is this an acceptable way to achieve a column effect?
overflow: auto (or anything but visible) causes your second div to create a new block formatting context. This means the text within that div is now in its own formatting context, rather than sharing the same one as your first, left-floating div (which is the containing block of both divs), and so it is no longer allowed to flow around the first div.
Floats also generate their own BFCs, but that doesn't exactly relate to the matter at hand. It does however also prevent reflow, achieving a column effect, as shown in the other answers.
Is this an acceptable way of creating a column effect? I don't know, but it does seem unconventional. You can just float the second div as well instead for the reason mentioned above (although even that, in favor of upcoming true layout modes like flexbox and grids, is now seen as a browser compatibility hack these days, but is the best we've got for the time being).
Remember that inline content is designed to be able to flow naturally around floated content; see CSS2.1, ยง9.5 Floats.
Remember also that the purpose of overflow is to control content overflow in a box with a limited size. That it causes a box to create a new BFC, influencing floats as a result, is but a side effect, the reason for which is explored here. It's a lengthy read, but it includes a bit about preventing reflow, which I'll quote here for ease of reference:
And so, this change was brought about in CSS2.1, documented here. Now if you apply an overflow value other than visible only to the second box, what a browser does is push the entire box aside to make way for the float, because the box now creates a new block formatting context that encloses its contents, instead of flowing around the float. Here's what it looks like with overflow: auto for example:
Note that there is no clearance; if the second box had clear: left or clear: both it would be pushed down, not to the side, regardless of whether it established its own BFC.
By the way, yes, this means your clearing div needs to be there if you want to always clear the first div.
To get the divs next to each other they both will need a float and fit in the surrounding div.
Example:
<div style="width:200px;">
<div style="width:100px; float:left;">
content
</div>
<div style="width:100px; float:left;">
content
</div>
</div>
If you want the outlining div to grow with the largest div place overflow:hidden; to the div.. If that div doesnt have a height with it then it will scale with the larges div.
Preview:
http://jsfiddle.net/WzVBE/
Remove float:left from the first div.
<div>
<div style="border:1px solid grey; width:100px; height:100px;">
Div on the left.
</div>
<div style="overflow:auto; ">
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>โ€‹
DEMO
You can try this
<div style="width:800px; background-color:#CCC">
<div style="width:300px; height:100px; float:left; background-color:#CCC">
Div on the left.
</div>
<div style="height:100px; float:left; width:500px; background-color:#999">
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>

Display:table for IE7?

I've a several columns in CSS, with float:left property to align them horizontally. But as it float in the left side, I can't center all the divs.
So I found that if I wrap my columns with another div with display:table property, all works perfectly... but not in IE7 (idd, this property is not supported -.-).
Does anybody has a hack or trick for this?
Here is my code:
<div style="display:table">
<div style="float:left">A column</div>
<div style="float:left">A column</div>
<div style="float:left">A column</div>
<div style="float:left">A column</div>
</div>
Hm, why are you having a float: left on your leftmost div? I think that will cause some trouble. Do you have any css? You should have margin-left: auto and margin-right: auto on your outer div. Take a look on this page, there's all the details. Seems like you might have to add br-tags or similar too
if you use display:table; on the parent dic, you should have display:table-row; and display:table-column;-elements in it - and floating doesn't make any sense in that case. please take a look at this or ask google for more information.
(if you want to display a table, why don't you use the table-element? In cases where tables are used for layout, thats a bad practice, but doing the same sh*** by substituting table-crap for divitis doesn't make it better)
EDIT: if you just want to display your divs side by side and centered, you could simply try to use display:inline; or display:inline-block; (but the last will make problems in IE, too) - and remove that senseless display:table; on the parent-div

Resources