I have a page generated by a database. It creates a DIV for each entry (extremely simplified for sake a question). Each of these DIVs have a set width, and float left.
However, these DIVs don't have a set height, so occasionally the following as depicted in the image happens. Is there a good way to prevent this from happening, and the white space just 'collapsing?'
The link to the prototype site. Here
I think this article would help you:
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/
Depending on what you have control over, you could always add clear: left; to every other element in your 2-column scenario.
Though, I beleive that the second "The Postal Shoppe" would actually be on the left, and the Brynwood Pak N Ship would be in the right column.
The problem isn't so much that "Brynwood Pak N Ship" isn't collapsing the white-space, it's that the second "The Postal Shoppe" is getting hung up trying to move all the way to the left column by the bottom right corner of the "Express Pack & Mail Center."
Setting clear: left will ensure those entries always move down far enough to "suck up" to the left edge of their parent container. But you will still see some un-evenness using that attribute; the "Brynwood Pak N Ship" will line it's top up with the newly-cleared "Postal Shoppe" showing a tiny gap at the top. Still probably preferable to what's going on currently.
You can add a clear: left attribute to every other div. Alternately, you could try using display: inline-block instead of floating left, but it's not as widely supported (I think it breaks in IE 6 or older), so you'd have to see what hacks are out there to make it work universally.
I suggest giving every box an equal height. This is visually better, and it solves your problem in one go!
I think this is difficult to solve in CSS. I like the suggestions other users have made with 'display:inline-block' and setting the height to be fixed. They both have minor drawbacks, but the situation will be better than it currently is.
If you are going to solve this "properly", we first need to agree what the proper solution is. I think it would be to have two columns, and for each element that has to be added, it is appended to the end of the currently least-full column. This won't necessarily result in elements alternately being placed in column 1 then column 2. Sometimes two (or more) small elements will be placed in column 2 to compensate for a large element in column 1, for example.
I doubt something as complicated as this is possible to define in CSS (but I've been surprised by what can be done before). It could be done using Javascript though. You could have a solution that does a fairly good job if Javascript is disabled using a purely CSS solution, and if Javascript is enabled you could arrange them more elegantly.
I'm not sure it is worth the effort of implementing this though. Some of the existing suggestions seem reasonable compromises, and if it were me, I'd probably go with the inline-block solution, but I thought I'd throw this idea out anyway.
This can be solved now using flex-direction and column-count:
.parent {
column-count: 2;
column-gap: 1.25rem;
}
.child-class {
flex-direction: column;
display: inline-block;
width: 100%;
}
I'm not sure if it's supported in all browsers but it's an easy css solution.
Related
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).
I'm trying to create a grid layout at http://www.gablabelle.com/.
I have multiple divs (images) with float: left; property and I wonder why there is some empty spaces and why the floating divs are not filling the gaps.
Many thanks for your time and help.
UPDATE: I now use jQuery isotope but still have gaps... any idea?
That's just how floating works. Those gaps are there because elements float after another breaks to a new line. It doesn't fill the space above.
If you want an uneven grid effect then you'd need to use a javascript solution where you are setting absolute positions. I'd recommend the masonry plugin, I think the before/after example on the homepage shows the problem you are having and the solution you want.
It seems that you are looking for a way to fill all of the squares on the page. This isn't going to be possible simply through CSS. 'float: left;' is simply filling the space in the page, image by image, and not considering how it all fits together.
Fitting all of the pieces together so they sit cosily and like a jigsaw will not be easy. It is actually quite a complex problem, and it is connected to the knapsack problem (http://en.wikipedia.org/wiki/Knapsack_problem) and the packing problem (http://en.wikipedia.org/wiki/Packing_problem).
To solve this, I'm certain that there would be jQuery or JavaScript (or maybe even PHP) libraries available for use. Alternatively, you could manually order the photos such that they fit together in a tidy fashion.
Good luck!
This is causing the gaps:
article.post {
margin: 0 0 30px 30px;
}
I know there are tons of questions regarding floats, but I seem to be a bit stuck on how to overcome this problem.
See my example here: http://jsfiddle.net/eE9WT/1/
What I am trying to do (or infact, trying to avoid) is the third .float div starting once the second .float div has started.
I would prefer the third div to fall directly underneath the first, making use of all space on the page. I'm aware that I could separate this into two columns, but I was wondering if there is a better solution without having to do that.
Believe it or not, within my 5 years of developing for the web this seems to be the first time I've been faced with this problem!
Thanks guys
This article would help in creating a Floating Box Layout: http://matthewjamestaylor.com/blog/floating-boxes-css-layout.htm
Also check out his other layouts, just in case they seem a better fit for your design!
You can add a rule for the second float to be right
.float + .float {
float: right;
}
I think this is the solution you are looking for:
JSFiddle
I moved all the div's to the left with float.
Made some space in the right side of the screen with padding-right on the container.
And then used the position: relative; to moved the second column to that space.
Display:inline-block;
zoom:-1;
More than float it do something for you. Only some rare case am using float. I know this is not meet your goal, I just explore my side.
I am designing a website for a client, and I am trying to get two side-by-side DIVs to adjust to 100% of their container. I've got the side-by-side done, but I can't get the right DIV to be the same height as the left one.
You can view the problem here: http://www.campusmomlaundry.com/
The "challenges" and "benefits" DIVs should be side-by-side and the same height, without manually specifying the height. How can I do this?
Your problem is that the outer div is sizing automatically by the inner content, which is sizing automatically by its content.
You have couple of options:
Use the background solution mentioned in the #R0MANARMY answer to create the visual ilusion of two equally tall columns.
Set the height of the two inner divs to be the same exact number (using px or em)
Set the height of the outer div to an exact number.
Play with the display attribute and try couple of different values like table-cell and so on. Keep in mind that this one is not going to work in some older browsers. (Not only IE, but some old Firefox and Chrome releases as well)
Use simple table with one row and two columns.
I realize that the last one is the most controversial of all. Yet it is a possible solution for your problem and there's no reason why you shouldn't at least evaluate.
([groan] please, please, nobody mention the words "semantic HTML"! there's no such thing in our universe.)
There's an article on A List Apart on solving a similar problem, you could probably use that as a reference: Faux Columns.
If it was me. I would solve this problem via javascript. Using jquery you could do...
$(document).ready(function()
{
if($('#leftColumn').height() > $('#rightColumn').height())
{
$('#rightColumn').height($('#leftColumn').height());
}
else
{
$('#leftColumn').height($('#rightColumn').height());
}
});
That should do it. If your like the people I work with, and you don't like using Javascript for CSS problems. Then you are probably flat out of luck. Alot of the time, it is much faster just to use JQuery, then to use the "right way" using css. You could probably spend all day trying to get it to work with different combinations of styles.
Perhaps number of bullet points in the left DIV?
Have you tried: height: auto; or height: 100%;?
I have a list of items that I am displaying in a floated list, with each item in the list at a fixed width so that there's two per row. What is the best practice to prevent this horrible thing from happening:
alt text http://x01.co.uk/floated_items.gif
Possibilites:
Trim to a specified number of characters before displaying the data. Requires guesswork on how many characters will be "safe".
Overflow: hidden. Hacky.
Remove the background and just have a top border on each item.
Possible but silly:
Have a scrollbar in each item by doing overflow: auto, this will look horrendous.
Add a background image to the container. It's not guaranteed that there's always an equal number of items so this option is out.
Any help on this irritating issue appreciated!
Are you using a fixed font size, i.e. specified in px? If not you also need to consider the various text size options of each browser which is probably going to make the concept of trimming the string redundant. If it is fixed then perhaps seeing how many Ws you can fit in and restricting your text to that -3 and appending an ellipsis, not sure what this list is for so that's one approach.
Personally I'd probably use overflow:hidden as that covers all eventualities and ensures that it'll always keep your layout consistent.
I guess the last option would be to keep a tight control over what can be added to the list and prevent the problem occuring in the first place. Prevention better than cure as they say, although probably unhelpfully.
There are scripts that help with this by comparing the li in blocks of two and making them both equal to the tallest.
Usually, rather than thinking what's best from a css point of view though, you should consider what presentation you want, then get the css/JavaScript to get you to your desired effect.
If this is something that you're just wanting out of the way, consider using a gradient background image that highlights the top of the li and suggests the block without actually filling it in.
Adding link to a jQuery solution: Equalize
One solution would be to have a alpha-based PNG that would slowly fade the text to the backgroundcolor of your container, on the last 10px or so. That would look good if some text are considerebly shorter than the long ones, however in the case where the text would be equal to the container it could look kinda silly.
Of course, in combination with display: hidden and white-space: no-wrap
From an accessibility point of view it's not a good idea to simply hide the title, since that could hide content on people who increase font sizes due to bad eyesight. Your design should be able to float when hit by bad resolutions or similar obstructions, even if it floats into something less pleasing to the eye.
Now if I understand your issue with the background image correctly, I believe your problem could be solved using the techniques describes in the ALA article on sliding doors, where the background image expands with the content.
Here's some controversy for you.. use a table?
Sounds like you have a grid of data to me, would a table answer this problem for you?
It also raises the question, do you actually want the items to be the same height, or just have the same amount of black background behind them? You could apply the black to the row's background, then create the centre white separator with borders and margins.
You could try using:
ul li{
display:block;
float:left;
width:6em;
height:4em;
background-color:black;
color:white;
margin-right:1em;
}
ul{
height:100%;
overflow:hidden;
}
div{
height:3em;
overflow:hidden;
background-color:blue;
}
Don't know about cross browser consistensy though.
EDIT: This is the html I'm assuming:
<div>
<ul>
<li>asdf
<li>asdf trey tyeu ereyuioquoi
<li>fdas dasf erqwt ytwere r
<li>dfsaklñd s jfañlsdjf ñkljdk ñlfas
<li>ksdflñajñldsafjñlksdjfñalksdfjlkdhfc,v.mxzn
</ul>
</div>