Fixed-width, flexible-height css grid - html

NOTE This is similar to this post, however there is a strict no-javascript requirement and the answer should be responsive (i.e there is not a fixed number of columns).
I would like to style several fixed width, variable height boxes using no javascript such that they form a kind of fluid grid. This jsfiddle yields the picture below. This is essentially just the following css:
div {
float: left;
margin: 1em;
border: 1px solid #999;
width: 150px;
}
I'd like for the only vertical empty space to be the margins. In terms of the screenshot above, I'd like for the tops of 5 and 6 to move upwards to 1em from the bottom of 1 and 2, respectively.

it's not possible by using pure CSS because any how you have to know the current position of div so if you really wanna do this then you have to re position the <div> either using " margin-top " property of css or using jQuery like these jqueryhouse.com/jquery-grid-plugins

Related

Floating backgrounds with different height nicely

I have a bunch of floating dynamic divs with different heights.
Fiddle
I want to float the divs nicely, so in the example 14,15,16 should come before 10, and then 17,18,19 should come after.
Any ideas on how I can achieve this?
Thanks :)
.blankspot div {
float: left;
border-right: solid 1px #fff;
border-bottom: solid 1px #fff;
box-sizing: border-box;
margin: 0;
padding: 0;
background: #fed;
display: inline-block;
vertical-align: top;
height: 50px;
width: 100px;
}
EDIT:
Sorry, can see my description is a bit off.
Here's a pic of what I want to achieve
My own research on this issue, tells me that a solution to the problem would result in third party code or some nasty ninja tricks.
If, like in your picture, you can control the width of the outer div to enclose 7 boxes per row then you can mess about with the margins to get the boxes to flow more neatly.
Updated fiddle: http://jsfiddle.net/g4o8rukz/3/
The reason you need to know the number of boxes per row is because you need to know which box will need shifting in the row below. If box 10 is selected to double in size then it's box 15 in the row below that needs dynamically updating with the class neighbourBelow in order to push its neighbours across in the same row.
You need to apply this +5 offset with JavaScript so you could number your boxes with something like this:
<label data-index="10">
<div>10</div>
</label>
Then it's selectedBox.attr('data-index') + 5 to determine the data-index of the box that needs its margin adjusting. This is jQuery syntax but I'm sure you get the idea.
Make the following change and your highlight box will fit the parent
width: 100px;
height: 50px;
background-color: #f0a;
I am not still clear what you wanted to tell regarding before after. If you want to appear 10 after 15 then move the rearrange just your divs. Something like the jsfiddle here http://jsfiddle.net/johirbuet/g4o8rukz/2/

Layout and floating div problems

So, I have this layout looks like this
As you can see there, the div is floating/aligned to the right side perfectly but on the left side there's a gap between it, how do I clear the gap?
DIV CSS:
.thread-list{
width: 40%;
background-color: #fff;
padding: 10px;
border-style:solid;
border-width:1px;
border-color:#F0F0F0;
margin-bottom: 3px;
margin-right: 10px;
margin-bottom: 10px;
overflow: auto;
float: left;
}
NOTE: The div is showing content dynamically (from database), and I can't make the div in 2 separated columns.
Sorry, if I'm being not clear enough.
DEMO
If you float multiple elements & one of the div has larger height then others, then these types of effect are created (the one you showed in your screenshot).
Solution 1: clear float left from 1st element of each row using :nth-child(2n+1) in your case its ..2n.. cuz you have 2 elements in one row.
Add this css in your style-sheet:
.thread-list:nth-child(2n+1){
clear:left;
}
Solution 2: Solution 1 will align all the div's but there will still be a negative space beneath, if you dont want that then you have to use plugins like Masonry Layout, this effect can not be achieved with pure css.

List items with alternating heights messing rows

I am having trouble with a list which has items with alternating heights based on the content. This causes the rows to break as seen here: http://jsfiddle.net/PYRGb/ Try re-sizing the display view to see the effect.
What i would ideally like is for the list item to continue to the next row with space enough to make a row without hitting the edge of the above row. Is this possible?
I know i have mentioned 'rows' and a table could be a solution but I
am using lists to keep the display fluid and adaptable to a range of
devices.
Only solution i have found is to set a min-height that i am certain
content will not overflow like so: http://jsfiddle.net/PYRGb/1/ But i
really cannot predict the amount of content in the list items and
would like the list item to adapt height if possible.
EDIT: Just a note, if you see the resize the display to have 3 columns, you can see the effect I need but it doesn't work in other situations. (Not sure if this is the same in all browsers, I am using Chrome 26)
Thanks
remove the float and make the li display as inline-block with vertical align top.
http://jsfiddle.net/stevendwood/PYRGb/2/
ul li{
width: 100px;
padding: 10px;
margin: 0 0 20px 20px;
border: 1px solid red;
background: #eaeaea;
display: inline-block;
vertical-align: top;
}
You can set vertical align to middle or whatever you prefer.

HTML/CSS: 3 columns, variable sides and fixed centered middle column

My problem is with the header. So I basically have 3 columns of divs. I want the middle one to have a constant width of 980px, and then I want the left of the header to extend to the end of the browser window with a blue background color. As for the right of the header, I want that to extend to the end of right side of the browser with a black background color. It kind off looks like this:
<------------------------------[blue][center header][black]---------------------------->
I've done my research and all I could find so far are two columns with a fixed left column with the right column filling up the rest of the space. I wonder how this can be applied to my problem?
Would it be like:
<div style="width:100%;">
<div style="display:table-cell; background-color:blue;"></div>
<div style="width: 980px;">my header</div>
<div style="display:table-cell; background-color:black;"></div>
</div>
Thank you!
A simple solution - basicaly using your exact stying, but putting another block in the central table-cell element, something like this span here:
<div class="wrapper">
<div class="left"></div>
<div class="center"><span>my header</span></div>
<div class="right"></div>
</div>
I moved all the inline style to a separate CSS block and used class selectors:
.wrapper {
display:table;
width:100%;
}
.left {
display:table-cell;
width:50%;
background-color:blue;
}
.right {
display:table-cell;
width:50%;
background-color:black;
}
.center {
display:table-cell;
}
.center span {
display:inline-block;
width:900px;
}
here is a jsfiddle
and here I made the center much narrower for a better illustration: jsfiddle
Hope this helps =)
Unfortunately there isn't a super smooth way of doing this that is also has wide cross compatibility support. There is a CSS spec for display called flex or flexbox which would do what you want beautifully and elegantly, but it has very limited support at the moment. Here is some resources on flexbox for your perusal...
http://css-tricks.com/old-flexbox-and-new-flexbox/
In the meantime, you can achieve the layout you want with some basic CSS jiggery-pokery that will get you what you want, but it requires absolute positioning your middle div.
Heres the JSFiddle: http://jsfiddle.net/CW5dW/
Here's the CSS:
.left {
width: 50%;
height: 300px;
float: left;
padding-right: 160px;
box-sizing: border-box;
background: red;
}
.right {
width: 50%;
height: 300px;
float: right;
padding-left: 160px;
box-sizing: border-box;
background: blue;
}
.middle {
position: absolute;
width: 300px;
height: 300px;
left: 50%;
padding: 10px;
margin-left: -150px;
box-sizing: border-box;
background: orange;
}
What is going on here you might ask?
Basically, we are taking the div with class middle and removing it from the flow of the document. This allows us to float our left div left, and our right div right, with widths of 50% in order to fluidly take up ALL space of the browser.
We then tell the middle div to take up 300px of space (in your case 980), and we tell it to go 50% of the total width of your browser from the left. This doesn't center it though, because its calculated from the left edge of your div. So we give it a negative margin space of half it's width, to sort of "move" that left edge to the center of the div.
Then, since we know the middle div has a width of 300px (in your case 980), we can then say that the left div should have some padding on its right edge greater than or equal to half the middle divs width, in my example that's 150px, and I added 10px more so text couldn't come right to the edge of the div, so 160px total. We do the same for the right div but for it's left side. This limits the content of those two divs from falling underneath our middle div.
This answer is not an "answer" as such - it's an extended comment to #Michael's post. I have, however, posted another answer - a jQuery solution.
Regarding #Michael's answer (which is a very tidy solution indeed) there is a tiny issue that if you remove your height declaration (which the OP undoubtedly will) then the backgrounds for the various columns become exposed - this method relies on the backgrounds all levelling out at their bottom edge in order to make the design coherent. If the OP's design doesn't have backgrounds behind the columns then this solution should be fine. If backgrounds are required (which they might be judging by the question wording) then it could be awkward. Two solutions to this...
a simple javascript that scans the page for column length, finds the longest, and matches all shorter ones to the maximum.
The other (and probably better) solution is to drop a background into your with the columns already on it (it only needs to be 1px high I guess) - just make sure the central white band is 980px wide and the side columns extend off a thousand or so pixels to accommodate even the largest of browsers
OK, here's my solution. This will present a "common or garden" three column fixed width layout to all users and then adjust it for users with javascript enabled (which, let's face it, is the vast majority of users). The benefits of this solution are that the layout will behave like any ordinary 3 solumn layout without the quirks you can experience from using more advanced CSS tweaks like absolute positioning and fixed heights.
Fiddle here... http://jsfiddle.net/vuary/
You should be able to see what's going on with the HTML and CSS... it's basic stuff. The jQuery is pretty straight forward too:
$(document).ready(function(){
// find the width of the browser window....
var docuWidth = $(window).width();
// find the width of the central column as set by the CSS...
// (you could hard code this as 980px if desired)
var centerWidth = $('#center').width();
// figure out how many pixels wide each side column should be...
sideColWidth = (docuWidth-centerWidth) / 2;
// then set the width of the side columns...
$('#left,#right').css({
width:sideColWidth+'px'
});
})
EDIT
Converted the jQuery to a function that is called when the document is ready, and again if the viewport is resized... just in case:
http://jsfiddle.net/aKeqf/

Div within a Div

I've got this problem, I've placed a div within a div, I've positioned the "title" to be height 50, and then "navbar" below it, so I've put height 100% though the thing is, its not staying within the div, its actually straying away from and out of the div and making a scrollbar appear.
I would love "site" to hog the walls and then all the other div fit in that div.
<div id="site">
<div id="title">TitleBar</div>
<div id="navbar">NavBar</div>
<div id="frame">FrameBar</div>
</div>
body{
margin: 0;
}
#site{
position:absolute;
width: 100%;
height: 100%;
*border: 1px solid #333;
}
#title{
border: 1px solid #333;
height: 50;
}
#navbar{
border: 1px solid #c38a8a;
width: 200;
height: 100%;
}
I've found an image that shows something similar.
http://img176.imageshack.us/img176/4637/picture1zb1.png
that's because 100% height actually means "use the same height as the container".
But I didn't quite get all your requirements for this layout, if your navbar is a navigation bar, it should be designed in a way that allows scrollbars to appear when the content is too big.
But I think you're going for the wrong structure to accomplish this, is there any actual reason you want a wrapper div? I've created a fiddle on this, check if this is closer to what you wanted: http://jsfiddle.net/6g6HV/2/
This other one is yours, in case you wanna play with it: http://jsfiddle.net/yq8PS/3/
Edit: Adding the javascript solution to the answer http://jsfiddle.net/6g6HV/9
You can make divisions in HTML appear side by side to each other by adding a float property to the css.
#navbar{
border: 1px solid #c38a8a;
width: 200px;
height: 100%;
float: left;
}
Additionally, always add the 'px' unit after a size. Modern browsers assume you mean px, but older ones might not.
There isn't a good way to prevent the overlapping when you have a sidebar that is a set pixel width. To achieve the liquid width (or fluid width) style, you would have to add negative 200px margin on the left to the #frame (to counter sidebar). Then, add another divsion inside the #frame to do the styling for that portion. This is how I have achieved the look on my web site, and it's also the solution used in the previous default Drupal theme (Garland).
#frame{
margin-left: -200px;
}
IN this context, 100% for the Navbar doesn't mean the remaining height but 100% of the visible heigth of the parent; so if the parent has a height of 400px then Navbar will also have an height of 400px. If you add to this size the height of the title bar, you get a total value greater than the size of the parent; therefore the appearance of the scolling bar.
While there is usually no problem with the width to make it appears to fill the whole length of a screen, it's very difficult in HTML & CSS to do the same with the height as they have not been designed for this sort of thing; especially with an imbricated structure (div inside div).
Some people will use Javascript to get the size of the screen (browser) and compute the size of their objects accordingly but I don't know if you can do the same with a pure HTML/CSS solution; especially if you want to have your solution compatible accross many browsers.
For more info, take a look at http://www.tutwow.com/htmlcss/quick-tip-css-100-height/