
The curious case of equidistant boxes, a CSS fail - wheels
http://blog.directededge.com/2010/04/30/the-curious-case-of-equidistant-boxes-a-css-fail/
======
derefr
Browsers know how to do this perfectly well with _text_ —it's simply justified
alignment. Shouldn't it also work for inline-blocks?

~~~
mbrubeck
Wow! That's a crazy and ingenious idea and it seems to work:

<http://limpet.net/mbrubeck/projects/justify-block.html>

View source to see the details. It's very slightly tricky because the last
line of a "text-align:justify" element is not fully justified, so you need
force it to wrap. In my test file I used a generated "spacer" element to do
this. In practice you would probably hide this element by setting its height
to zero or something.

One nice thing about this is how it continues to work even as you resize the
container so the children don't fit on one row. (Resize your browser window to
try it.)

~~~
wheels
Hmm, messing around with this at the moment. Your test case works in IE 7
(fired up VMWare to give it a spin -- noticed my example code actually
doesn't, but the real widget does), but I still haven't gotten it working with
real images. I'll update here once I see if I can get that going.

As an addendum, in the non-contrived case (the one the widget actually uses)
it also allows text to spread beyond the width of the image above it unless
it's on the extreme edges; I haven't yet thought through if that'd be possible
with this or using td spacers with a little extra finageling.

[http://blog.directededge.com/wp-
content/uploads/2010/04/reco...](http://blog.directededge.com/wp-
content/uploads/2010/04/recommendations-test-shop.png)

Note the _Coffee > Everything_ label.

Edit: Reason it wasn't working in IE 7 was because I didn't add a doctype and
it dropped into quirks mode.

~~~
Groxx
I quite doubt there's a way to do overflowing text like that with only CSS
without nastiness. Though, someone, correct me if I'm wrong; I'd be fascinated
to learn how, if it's possible.

With images, I've managed this:
<http://dl.dropbox.com/u/363028/temporary/justify_images.html>

Though it's giving me a 4px taller container for the images than is needed :\
(forgive me if I'm missing something obvious there) It works on Safari 4 w/o
the widths or the height, too, all that's needed are justify, inline, and that
spacer (nice catch, that).

edit: via browsershots:
[http://browsershots.org/http://dl.dropbox.com/u/363028/tempo...](http://browsershots.org/http://dl.dropbox.com/u/363028/temporary/justify_images.html)

looks pretty consistent, for the most part. Probably breaking on inline-divs
where it's failing. (and Opera is the only top-aligning one...? maybe that's a
user stylesheet issue.)

~~~
mikepurvis
You can do the overflowing labels by given the label box a negative left and
right margin. Or a negative right margin and a corresponding relative
position.

Of course, this gives you no guarantee that there wouldn't be two overlapping
labels in adjacent products. To test for and prevent that, you would still be
on the hook for some JS, but it would be much simpler than the JS that's
already in place. Basically just some jQuery to step through the pairs of
adjacent objects and check the overlap of the internal spans containing the
text.

------
mbrubeck
The CSS3 solution is the Flexible Box Model. It's been implemented in Gecko
and Webkit browsers for a long time now:
[http://hacks.mozilla.org/2010/04/the-css-3-flexible-box-
mode...](http://hacks.mozilla.org/2010/04/the-css-3-flexible-box-model/)

Anyone want to write a compatibility shim for IE?

------
gojomo
A trick that may get the desired effect is spacer TDs -- without specified
dimension they'll each expand equally to fill out the desired width. Working
example for Mac FF/Webkit browsers:

<http://gist.github.com/386146>

 _edited to add:_

Live example, now including liquid-width demo as well:
<http://xavvy.com/news.yc/html-distribute.html>

~~~
treyp
gotta agree -- a table with spacer TDs is going to be your best solution here.
like mbrubeck mentioned, justified blocks are going to require a hack since
it's the last line of content.

perhaps the design can be thought out again, though. instead of getting the
first flush with the left and last flush with the right, you could just create
a bunch of blocks with centered content (think: floated list items in a list).
there will be a little extra spacing on the left and right, but you can design
it so that it's not too bothersome. i'm thinking

    
    
      (_A_)_(___B___)_(__C__)_(_D_)
    

instead of

    
    
       (A_______B________C______D)
    

your point about CSS having not really solved this problem yet is a valid one,
but solutions are in the works (namely, the flexible box model).

~~~
kronosis
terfo asdasd

------
Tichy
I must admit I would probably have opted for a simpler solution, like a fixed
spacing and just centering the whole group horizontally.

Also, would it look good with multiple columns? I think items would have to be
aligned vertically for it to look OK?

------
apphacker
I don't think using JavaScript to fix something CSS can't do is the proper
solution. I think to draw a static width box around the variable width items
or just not worrying about the flush on both sides (something you can
accomplish with CSS if you're willing to use an extra container to wrap all
items except the last.)

But styling via JavaScript because you couldn't do it in CSS? Yech. Especially
if it's not some kind of UI component that needs JavaScript interaction like
an accordion or drag handle or something.

~~~
mbrubeck
Maybe I spent too long around TeX and Postscript, but it seems perfectly
natural to me that when a layout can't be described in a declarative language
like CSS, you would turn to a computational language instead.

~~~
btmorex
Fixing layout in javascript has negative performance implications. Either you
embed the js in the html, in which case every page is larger than necessary,
or you put it in a separate file, in which case your layout can't be rendered
correctly until another file is loaded.

I'm not sure what the author's point was exactly. There are tons of things
that are easier to do with "classic" html or just plain hard to do with css
alone. Even though we've been hearing ever since its invention that css is
incredible, I'm still not convinced. It's certainly useful, but in so many
ways limiting and annoying.

~~~
wheels
> _Either you embed the js in the html, in which case every page is larger
> than necessary, or you put it in a separate file_

Which is different from CSS how exactly?

Text is small and most sane server configs are gziping it on top of that.
We're literally talking about 500 bytes.

~~~
btmorex
Well, you can't reasonably avoid external CSS, but you can reasonably avoid
external JS. I still have tons of pages without external Javascript. I'm
fairly sure I don't have a single one without external CSS.

As for gzipping etc. it's the not the actual size that matters it's the
latency + the fact that it's a new connection. TCP/IP connection takes a while
and then (for larger files) you have to deal with slow start. This wouldn't be
a huge deal if everyone supported pipelining, but they don't.

