Flexible div positioning - css

I have several divs on a page that all have the same width but different heights. They are all in one div, the #note1PreviewDiv. They all share the class .note, which has the following css code (among other):
.note{
width: 160px;
padding: 10px;
margin: 10px;
background: #e3f0ff;
float: left;
}
I thought with float: left; they would all automatically align so that they are well aligned among each other.
Here's a preview of what it looks like:
Current state http://posti.sh/img/ist.png
And here's what the positioning should be like:
Desired state http://posti.sh/img/soll.png
I think you get the idea. Somehow it seems to me the height of the leftmost div pushes the other divs in the second row to the right - but that's only guessing.
Thanks for your help!
Charles

You're not going to be able to do this easily with CSS only.
CSS3 has a new feature called column layout, but browser support is not great. IE9 and below don't support it.
See http://designshack.net/articles/css/masonry/ and the last example for CSS3 solution.
Have a look at these js / jQuery options for easier implementation and browser support:
masonry
isotope
vanilla masonry which doesn't need jQuery.
wookmark

The kind of lay out you want is really difficult (not possible?) without going for a column based approach and adding additional block elements to represent each column. This obviously won't work with a flexible number of columns if you want a dynamic layout based on screen size.
That said, you could always use JavaScript to dynamically place elements into columns, and get it to match the screen size.

Is the height of the parent container given a fixed value? If it is, try setting the height of the parent container to auto, and the overlow propery to hidden.

Related

CSS percentage width resize based on window

This probably was answered somewhere, but I can't find it :s
My question is about dynamic resizing of divs based in percentages.
Please look at code example below for the examples and possible solutions I made.
I ask if there is a better way to do resizing?
More detailed explanation:
Say I am writing a plugin that people can insert in their pages. (Imagine login form).
I go ahead and design the plugin's divs. I use media queries to achieve desired look for different devices. I work on a div straight inside of a 'body' element.
I use percentages for design (I like percentages). Say I set div to 80% width.
Now I give this plugin to the user. User goes ahead and puts the plugin's div inside of another
div that is 100px in width. Now everything looks awful. (80% of 100px is not a lot [80px]).
And of course I want user to put my plugin inside of whatever small-width divs that he have.
The solutions I saw so far to this problem was to create a holder div of certain width - say hardcode 300px. (ex - jQuery UI's Datepicker div; Meteor's login widget div). And then code to it always knowing the 300px width that I set before is not going to change.
But I don't know how good of a solution this is.
Moreover if I decide to go with hard-coding width, my plugin would need width of ~ 1000px. Because I want div to resize with media queries.
And if I go with hard-coding width (say holder div of 1000px width) and put it on a page, the page will have horizontal scrolling. And you cannot simply hide holder div (parent div) and have child to show at the same time. So this requires setting position:relative for holder (parent) div, putting it outside of window, and use same for child div - position:relative with same offset in opposite direction of parent offset.
I hope I am being clear so far and have not confused you!
A code example to illustrate what I am talking about:
http://jsbin.com/ifawez/18/edit
#cimmanon's comment cleared things out for me.
The problem is with lack of HTML/CSS "tools" available at the moment. Since responsiveness came into play fairly recently there are not a lot of CSS-native tools to accommodate changes in dimensions.
For instance media-queries exclusively work with width of window/document and not of other elements such as divs.
The solution I currently employ is using Javascript to determine width of a div and resize accordingly.
What I resize is the number of columns I want to display (I use Multi-Column module as suggested by cimmanon) which is pretty stable on webkit browsers. Since it is all done in Javascript (and jQuery's Sizzle) I keep an array of sizes like so:
var widthArray = [
{min:0, max:250, columns:1, secondary:false},
{min:251, max:350, columns:1, secondary:true },
{min:351, max:479, columns:1, secondary:true },
//more div sizes
];
// more code here
$(element).css({
"column-count": object.columns,
"-moz-column-count": object.columns,
"-webkit-column-count": object.columns
});
This is sort of like media-queries, but allows to work with width of html elements, not screen size alone.
Additionally I follow the way jQuery UI displays its components: using position relative/absolute.
.outer_div {
position: relative;
}
.inner_div_with_elements {
position: absolute;
z-index: 1010;
width: 99%;
float: left;
overflow: hidden;
...
}
.inner_components_displayable {
position: relative;
display: block;
}
.inner_components_hidden {
display: none;
}
So in Summary:
Media queries alone work with size of screen, and resizing of any inner element can be done in percentages to the screen size. They can be of huge help, but you turn into making your components work either with percentages based off screen, or specifying something like min-height and !important (as suggested by #Octavian)
Javascript manipulation of elements is currently easier, but is a costlier alternative (jQuery SIzzle is pretty slow)
A lot of libraries (ex. jQuery UI) use Javascript together with position relative/absolute to make sure their components/plug-ins will work nicely on all users' screen sizes.
I ended up combining position with javascript to emulate media-queries and multi-column design at the same time for responsiveness.
Thanks everyone who participated!
If I am reading this correctly, the main issue here is that it can potentially become too small based on where the code is located.
So why not just add a min-width property with !important? That way you can still base the size off of the parent container, but be sure that it doesn't get too small and ugly.
Potentially, you could even have a script to base the width off of the parent div and the min-width off of the screen size.

CSS - set left position of nth child

I want to set the left postition of n-th div to (n-1)*250px, for e.g:
1st child: left = 0px
2nd child: left = 250px
...
is it possible to do so in css? I am using Javascript to set this. Thanks.
The CSS3 calc() method comes to mind, but it doesn't support using the index (n) as an operand, so that will not work.
Recommended solution: You could potentially design your layout such that the widths of each of the elements is 250px. Give each of the elements display: inline-block or float: left and they'll line up as you intend. If the width of the content of the elements needs to be larger than 250px, ensure overflow: visible (default value) is set on the elements and allow the content to overflow. Without more information, this should achieve the effect you are intending.
However, if you need to use a more direct method of positioning, you should stick with JavaScript to set the position of these elements. Likely, you'll want to take into account screen width, element width, and more, and CSS will leave you unable to do so.
Take a look at this JSFiddle for inspiration. If you post a sketch of what you're looking to achieve, I can help you further.
You can use:
div:nth-of-type(an+b)
// or
div:nth-child(an+b)
to address your divs.
div{
position:absolute;
}
div:nth-child(2){
left: 250px;
}
div:nth-child(3){
left: 500px;
}
without preprocessor you need to write every rule by hand because there is no possibility for a dynamic way when setting the left property.
Another possiblity (depending on what you really want to do) would be to introduce nesting and set padding-left:250px. But that only works if you can alter your markup accordingly.
Javascript probably is the easiest way here.

Applying a clearfix to nth-child without additional markup

First up, for extreme clarity, here a JS fiddle demonstrating what I'm trying to achieve:
http://jsfiddle.net/bb_matt/VsH7X/
Here's the explanation - my rationale:
I'm creating a responsive site using the 1140 grid framework.
It's a fairly complex layout.
I've created a re-usable simple gallery class which can drop into any defined column size & using media queries, I apply relevant percentage widths to the li elements.
Each of the li elements has a right margin of 5%.
I'm using nth-child(xn+x) in the media queries to remove the right margin at the end of each row.
Everything works well - images resize as the layout resizes, the number of gallery items in a row work as I've defined based on percentages.
The only remaining issue to fix is to clear between rows.
I can't add additional html markup and I want to steer clear of overly complex jquery fixes.
I know of two ways to fix this, but I'm not keen on either of them.
First fix, simply using display: inline-block on the li elements, with a vertical align of top, would flow everything correctly... however, all the percentages get shot and the gallery items no longer neatly fit in the allocated space.
Second fix, give the list items a height. This is the route I will go down if necessary - it will require a different height depending on the resolution - no big deal, but not as neat.
I updated your fiddle here: http://jsfiddle.net/VsH7X/5/
I added a clear: left to the first item in each new row.
ul.gallery li:nth-child(5n+6) {
clear: left;
}
Keep in mind that the :nth-child pseudo class does not work in IE6-8, or FF3 and under.
​

Three Variable-Width, Equally-Spaced DIVs? What About Four?

I have some very simple sub-navigation that I'm trying to build across the top of the content area within my web site, but CSS doesn't seem to have any simple solutions for such a common problem: I want either 3 or 4 equally spaced DIVs across the top of the page.
1) e.g. 3 Variable-Width, Equally-Spaced DIVs
[[LEFT] [CENTER] [RIGHT]]
2) e.g. 4 Variable-Width, Equally-Spaced DIVs
[[LEFT] [LEFT CENTER] [RIGHT CENTER] [RIGHT]]
My solution for the first problem with only 3 DIVs was to float the left and right DIVs, and then assign an arbitrary size to the middle DIV and give it "margin: 0 auto". That's not really a solution, but assuming there are no changes to the navigation, it gives a rough approximation of what I want the results to be.
The solution I have for the second problem with 4 DIVs is to simply center a DIV in the same way as before, but then float two DIVs within that, e.g.
[[LEFT] [[LEFT CENTER] [RIGHT CENTER]] [RIGHT]]
But again, this requires applying an arbitrary size to the middle DIV for alignment, and if any language or image changes are made to the site, alignment values will have to be recalculated. As well, it's simply an over-complicated solution that requires merging structure with presentation.
Any help is greatly appreciated.
EDIT 07/20/2012 5:00PM
Alright, I put the "table-cell" solution into place using percents, but I encountered another issue within my slightly more complex implementation: the issue at hand is that each DIV I was referring to is actually a container for two more DIVs which are icon-label pairs, inlined either by float or by display:inline-block.
e.g. http://jsfiddle.net/c3yrm/1/
As you can see, the final element in the list is displayed improperly.
Any help is again greatly appreciated!
EDIT 07/20/2012 7:16PM
Final solution with arttronics' help: http://jsfiddle.net/CuQ7r/4/
Reference: jsFiddle Pure CSS Demo
The solution was to float the individual breadcrumbs while using a simple formula to determine the percentage of breadcrumb width based on the number total breadcrumbs.
You could use percentages, then it just comes down to simple math:
[[LEFT=22%]2% margin><2% margin[LEFT CENTER=22%]2% margin><2% margin[RIGHT CENTER=22%]2% margin><2% marginRIGHT=22%]]=100%/??px
You could then specify a width for its container and use
display:inline;
to keep them inline.
Note: If you use borders to see what the divs are doing that will add space unnaccounted for so you would need to reduce your elements width by 1% or so OR just change their background colors.
ol {
width: 400px;
/*width: 800px;*/
display: table;
table-layout: fixed; /* the magic dust that ensure equal width */
background: #ccc
}
ol > li {
display: table-cell;
border: 1px dashed red;
text-align: center
}
like here: http://jsfiddle.net/QzYAr/
One way I've found to do it is using flex boxes (or inline-flex).
Here is a great explanation and example of how it can be done.
I think in the future, flex boxes will be the superior way of handling this sort of thing, but until other browsers catch up with Mozilla's way of thinking for how to use the flex-basis attribute (with min-content, max-content, fit-content, etc. as values), these flex boxes will continue to be problematic for responsive designs. For example, occasionally the inner content (a_really_really_long_word) can't fit in the allotted space when the window is squished down, and so sometimes some things might not be visible off to the right of the screen if you're not careful.
I think perhaps if you make use of the flex-wrap property, you might be able to ensure everything fits. Here is another example of how this might be done (in Mozilla browsers anyway).
I tend to use flex boxes for letterheads or tables where the width is fairly fixed (not too small) because they usually space themselves nicely; I tend to use nested float and inline-block objects for websites where the content must squish down very small (as suggested in some of the other answers here).

Horizontally centering group of block elements

http://jsfiddle.net/vrcQp/
I want these buttons to be centered (the three versions represent different possible versions of the same thing).. so the css and html has to be the same for all.. just the number of items must change.
I want them to have a set width so I cannot use inline elements (and just text-align center it).
I also need the html mark-up to be simple enough that it could also be used to flexibly stack the buttons vertically with a different stylesheet
Any thoughts on how to accomplish this? I'm not seeing any way to.
Right now there's 1-3 elements.. ideally it would cover potentially any number but that's not necessary. And I'd like for it to work in IE6..
I edited for you: http://jsfiddle.net/vrcQp/6/
Here just replace float:left; by display:inline-block;
But why your button are <div>? It seems to me <button> or <input /> are inline-block by default.
For compatibility, I let you check that: http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/
If you don't mind changing the width of your buttons from percent to px, then you can use the technique explained in this article. It basically uses position: relative; along with left: 50%; and right: 50%; to center items horizontally in a menu.
jsFiddle example
http://jsfiddle.net/vrcQp/8/
Is that what you are trying to do?

Resources