Forum Moderators: not2easy
the latter accidentally threw up some further possibilities for the former. The problem with the former was that although it would display inline rows it required the divs to be of fixed width, and if you were using it for a gallery that of course meant the images had to be fixed width
However I think now that there may be a stable solution to rows of uneven width/height! it still uses inline-blocks which Mozilla does not yet support, but it uses a (new to me) Mozilla property which can cope with the same thing!
stack was the epiphany.. inline-stack was the break-through!
For your tearing apart pleasure.. feel free to suggest better/worse/flaws!
HTML:
<div id="container">
<div class="box"><div><p>test<br>test more</p></div></div>
<div class="box"><div><p>test</p></div></div>
<div class="box"><div><p>test 300px width box</p><p>what happens with 2 x paragraphs</p></div></div>
<div class="box"><div><p>test.<br />test ...<br />test.<br />test.<br />test.</p></div></div>
<div class="box"><div><p>test</p></div></div>
<div class="box"><div><h3>test caption</h3><img src="http://showcase.netins.net/web/phdss/wmwgfx/dlogo.png" width="109" height="56" alt="#" /></div></div>
<div class="box"><div><p>test</p>
<ul>
<li><a href="#">item 1 which is really, really long.. what happens</a></li>
<li><a href="#">item 2</a></li>
<li><a href="#">item 3</a></li>
</ul></div></div>
<div class="box"><div><p>test</p></div></div>
<div class="box"><div><p>You have to have the content in these boxes nested inside a further block element for FF. This paragraph also serves to see if text wraps in container</p></div></div>
</div>CSS:
<style type="text/css" media="screen">
html, body {padding: 0; margin: 0; border: 0; background: #00f;}
#container {
background: #fff;
margin: 0 150px;
border: 1px solid #f00;
padding: 5px;
text-align: center;
}.box {
display: -moz-inline-stack; /* mozilla */
display: inline-block; /* IE needs it given in two separate rules for a block element so see CC below */
/* width: 150px; */
max-width: 98%; /* if you don't know the width of say images.. then don't use one.. but FF benefits from a max-width setting or it would overflow */
background: #eee;
margin: 5px;
border: 1px solid #000;
vertical-align: top;
text-align: left;
}.box div {display: block;} /* the moz method needs this, and it does no harm to anyone else */
.box p {
margin: 0.5em;
}.box ul {
padding: 0;
margin: 1em 0.5em 1em 1.5em;
}.box h3 {text-align: center; font-size: 14px;}
.box img {display: block; margin: 5px 20px;}
</style>
<!--[if IE]>
<style type="text/css" media="screen">
/* IE needs the values given in 2 x parts for some strange reason */
.box {display: inline-block;}
.box {display: inline;}
</style>
<![endif]-->
let me know what you think.... useful or unnecessary?
edit reason: fixed image reference
[edited by: SuzyUK at 7:35 pm (utc) on July 25, 2007]
Wasn't this recently discussed, more or less, here:
[webmasterworld.com...]
Pender had a good sugestion as I recall.
Marshall
this is just a bit of "pushing the envelope fun" which might, if we're lucky, mean that CSS can do something outwith table restrictions, think photo sharing sites.. etc.. not that we need that proof of course ;)
Marshall
With penders' floated solution they are all the same height and width, so technically as long as the images didn't exceed the li's fixed dimensions (width and height would be required) it should still work without knowing the image dimensions fine too. If they (the li's) are not the same height the 'rows' would not work properly when they wrap, also if you had slim images they might appear oddly spaced as they will still be in a fixed width "cell" (li)
I however should've/could've marked my code up as list, because it fits nicely.. Moz would still require that a wrapper div is nested inside the <li> but it no longer needs dimension restricting.
I just remembered the point of the initial post (from 2005) I referred to. You can only float something left or right.. the original 'solution' (debatable ;)) was to offer a way for all rows to center horizontally as well as vertically align so if for example a single image wrapped it would appear in the center and not way over to the left, and small 'images' would vertically center within their row - this is more flexible than a table as with it you need to know where rows break, and obviously a table would stretch and possibly break layout as window narrows.
What the original idea could do was, get rows of uneven height divs to wrap properly, and center the content of the 'rows' horizontally and/or vertically - but it still required that the divs (cells) were fixed width because of the Moz problem, what this one can do is all of the above but no longer needs any dimension restrictions, though you could use them if you want.
you could of course add more classes to cope with differing widths but I was imagining its usage for a file upload site where the user/system only need input/calculate the image dimension and it would appear in the HTML for the image - and the CSS needn't know the sizes to still work. There might be no way to set up classes for each and every variation in some cases?
I know most sites have uniform sized thumbnails so the issue might not be that much of one, however an (ecomm) site I saw recently had uneven sized product pics listed - They're in a table (though I know they tried to find a CSS way) it looked odd because if the images were as wide as the cells they appeared close together then a slim image appeared like it was disjointed from the rest because it was centered in a wide table cell - just made it look odd, to me anyway..
Having the ability to use vertical-align: middle; made me smile. Yay
Noticed one bit of weirdness, in FF2 I cant seem to highlight the text "test caption".
also penders solution, I was playing with something similar a while ago and instead of setting both the width and height on the images, I used a class on the images and just set the longest eg .portrait {height:6em;} and .landscape {width:5em}.
I used a class on the images and just set the longest eg .portrait {height:6em;} and .landscape {width:5em}., do you not have to manually sset the classes? If I am understanding Suzy right, she is trying to automate the process. That being the case, it may be necessary to utilize some javascript, something along the lines of (and this isn't real script:
if img width >= 500px
document.write "img width 250px"
if img height >= 300px
document.write "img height 150px"
Just a thought.
Marshall
"do you not have to manually set the classes?" Yes. You could do something daft like .portrait200 {height:200px} .portrait150 {height:150px} which could get scary.
Although the js solution seems even more scary in a non js way.
Suzys way I prefer just for being able to align the images vertically and yes it allows different sized images without the need for the CSS image size silliness. And not using float means you dont get that thing where the float would stick to the right of the previous highest div.
Yes, I suppose so :) just trying to make it as fluid/flexible as possible
appi2, I don't understand about the highlight text, do you mean select text to highlight or put a background color on? - I tried both in FF and both work for me, but I have changed my code slightly..
I have found an issue with centering images if the caption is long, it appears it's best to leave the image as an inline element and use text-align center, margin: auto causes oddities in IE :o just for change -
also use of max-width is good for getting long captions to wrap but IE6 and below won't honor it..
random finding.. -moz-stack also works if there is no width on the "inline-block" but -moz-inline-stack works for both so would stick with that
I also came across an issue with hasLayout on lists while trying to convert my original markup to a list. Because I have a nested list in one of my sample blocks its <li>'s were gaining layout too (via display inline-block) and they were then displaying at 100% of *container* width (in IE6 and below), You can't reverse hasLayout when it's set using this particular property so I still had to put a class on all the parent <li>'s to differentiate them from the nested ones (could've used a child selector if <IE6 supported it!), but that would only be an issue if you too wanted to use nested lists in the 'blocks'.
appi2 if you do 'real-world/stress test' this code with actual data do let us know how it gets on.. I haven't had time to run it with a real life example code yet..
As in for some reason say I just wanted to select the '.est ca..' bit of "test caption" to copy and paste from a browser window to a text file. FF2 wouldn't highlight it. I had to click outside of the div and drag into the box to highlight it. Opera IE and Safari didnt have this problem. Bit weird.
Just found out it only does the above when the div has an image and a p or h tag.
Going to have a play with the code, mi brain keeps wanting to play with how I could use this with dropdown css menus not sure why though. Its often very wrong.
Mozilla CSS Extensions [developer.mozilla.org] handy link!
If you ad a float property to any image inside the div the image disapears in FF2.
If you add a float property to one of the outer divs it drops to the next row except in opera.
The not being able to highlight text thing in FF2, if you use lists with an inner div then the problem disapears and you can highlight the text.
Changing the #container to text-align:justify;
Works in FF2 Opera and Safari good old IE says no.
Another FF2 oddity wheres text1 gone
<ul>
<li class="box"><p>text 1</p><div><img src="/img.jpg" /></div></li>
<li class="box"><div><p>text 2</p><img src="/img.jpg" /></div></li>
<li class="box"><div><img src="/img.jpg" /><p>text 3</p></div></li>
<li class="box"><div><img src="/img.jpg" /></div><p>text 4</p></li>
</ul>
remove the p tags from the above and highlight text4 with the mouse, strange.
And by far the best FF2 arrrrg is
<div class="box"><div><a href="#"><img src="/img.jpg" /></a></div></div>
you cant click! nice.
First:
Another FF2 oddity wheres text1 gone
<ul>
<li class="box"><p>text 1</p><div><img src="/img.jpg" /></div></li>
<li class="box"><div><p>text 2</p><img src="/img.jpg" /></div></li>
<li class="box"><div><img src="/img.jpg" /><p>text 3</p></div></li>
<li class="box"><div><img src="/img.jpg" /></div><p>text 4</p></li>
</ul>
The text is gone under the image - it's how the "stack" property should work. It stacks all immediate children of the stack on top of each other.. that's why Moz needs the wrapper div around all the content for this application, here we're just using the inline-stack to get the inline-block look, we don't actually want the content to stack ;) so by using the encompassing wrapper div around all content inside the box we are in fact only stacking the 1 x child div then.
If you ad a float property to any image inside the div the image disapears in FF2.
So it does! but Good News, you can get it back by adding position:relative to the floated image
Opera has an interesting feature whereby if you've two blocks containing floated images next to each other the second image disappears!
Good news on that one too, add differing z-indexes to the two relatively positioned floats I only tried 2 images, z-index:1; for left float and z-index:2 for right float but that seemed to have worked for all other images even if you subsequently swap the order of the floats.. ho humm
Changing the #container to text-align:justify;
Works in FF2 Opera and Safari good old IE says no.
So it does, but at least it doesn't break ;)
There's a lot of the usual "quirks" with IE6 and below, you have to be careful because of hasLayout as usual, most things can be fixed by restricting the width of the boxes, which might not be a problem for your application?
for example you can float the image right, but it will stretch the box to 100% of the container unless it's restricted. I'm assuming that if you're floating images it's because you have a text description beside them, if so then flexible box width to suit image width might not be so much of an issue, anyway restricting the box width fixes it and should be easily enough "classed".
next as I've already mentioned was the nested lists in the box, lists notoriously have haslayout problems when a link inside them has display block anyway (though OK in IE7) you can apply the effects to a list, no problem but the hasLayout fixes that were required to get the hover to be active on the whole link, or remove whitespace will again cause the box to stretch to 100% wide, and again that would mean a width restriction :(
remove the p tags from the above and highlight text4 with the mouse, strange.
have tried this both with image inline and block and have no trouble selecting text?
And by far the best FF2 arrrrg is<div class="box"><div><a href="#"><img src="/img.jpg" /></a></div></div>
you cant click! nice.
Again I have no problems clicking on an image link?
I'll send you my code if you like, I could post it but it's getting a bit long with all the comments and stuff ;)
If you have an example of an image that can be clicked please show me, pm or otherwise.
Really don't understand why I cant click on an image link, just tried changing doctypes disabling FF addons standing on one leg etc. Still can't get it to work. I can get focus with the keyboard but the mouse just treats it as though its text.
You forgot to chant the "this is going to work" mantra didn't you ;)
Have sent you a link let me know if it's the same..
This you cant click (last div on new line)
<div class="box"><div><a href="#"><img src="/img.jpg" /></a></div>
</div>
Now if you use li with any formatting it works.
<li class="box"><div><a href="#"><img src="/img.jpg" /></a></div>
</li>
?
It actually does happen using list formatting too
e.g. to recreate
<li class="box"><div>
<p>content in here will not be selectable or clickable</p>
</div>
</li> here what I think but haven't had time to look or see if it's right/wrong..
...</p>
</div>"whitespace"
</li>
Mozilla is handling the "whitespace" between the closing </div> (inner container) and the closing </li> or </div> (the 'box') as a child element(node?) and is then "stacking" that child element on top of the previous one, which is the div.. essentially covering it over and making it inaccessible
does that make sense?
I suppose the answer for now is to make sure that whitespace doesn't exist!
but in the interest of "I've just got to know" - can someone more familiar with Mozilla/Dom let us know if this is right and indeed if there's anything that can do about it..
Whitespace in the DOM Mozzilla Dev [developer.mozilla.org]
As for your code as long as the last two closing tags dont contain white space it works and you can still format the rest.
Oh and images have nothing to do with the problem.
<li class="box"><div><a href="#">Cant Click</a></div>
</li>
<li class="box">
<div>
<a href="#">Can Click</a>
</div></li>
Now I understand why I had some problem with a js script for keyboard nav on CSS dropdowns.
<style type="text/css" media="screen">
html, body {padding: 0; margin: 0; border: 0; background: #000;}
#container {color:#ccc;background: #333;margin: 0 50px;text-align: center;}
.box, .box div,.box a, .box img {
padding:5px;margin:5px; border-width:5px; border-style:solid;
/*Just so I could see margins, borders padding*/
}
.box {-moz-border-radius: 5px; /*mozilla round corners*/
display: -moz-inline-stack; /*mozilla */
display: inline-block;
max-width: 98%;
border-color:#fff;
background: #E6E6E6;
vertical-align: middle;
text-align: center;
}
.box div {display: block;border-color:#DADADA; background: #CDCDCD;}
.box a {display:inherit;display:block;
/* display:block; for mouse keyboard focus border in non IE */
position:relative;
/* FF fix
Problem with the above, if we use that, Opera loses every second image!
solved it by adding position:inherit to the image.*/
border-color:#C1C1C1; background:#B4B4B4;}
.box a:focus, .box a:active, .box a:hover {border-color:#000;}
.box img {position:inherit; border-color:#A7A7A7; background:#9A9A9A;}
/* Fix for Opera second image problem. */
</style>
<!--[if IE]>
<style type="text/css" media="screen">
.box {display: inline-block;}
.box {display: inline;}
</style>
<![endif]-->
</head>
<body>
<div id="container">
<ul>
<li class="box">
<div>
<a href="#"><img src="/img.jpg" width="100" height="71" alt="#" /></a>
</div>
</li>
<!-- Just repeat some more <li>..</li> here -->