Forum Moderators: not2easy

Message Too Old, No Replies

How do I center floated DIVs

centre floats

         

Dabrowski

6:33 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have a few little info boxes on my page, here's the code:

#featurecontainer { overflow: auto; }
#featurecontainer .featurebox {
float: left;
padding: 10px; margin-right: 10px;
border: 1px solid white;
font-size: 1.3em;
}

<div id='featurecontainer'>
...<div class='featurebox'>
...<b><u>Info!</u></b><br>
...Some Text<br>
...</div>

...<div class='featurebox'>
...<b><u>Info!</u></b><br>
...Some Text<br>
...</div>

...<div class='featurebox'>
...<b><u>Info!</u></b><br>
...Some Text<br>
...</div>
</div>

It's working fine, they're sitting nicely next to each other, but it would look better if they were centered across the space.

Fotiman

7:17 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If you have a fixed width on the featurecontainer and you can set a fixed width on your floated items, then this is possible. However, if you don't know the width, then it will be nearly impoossible (for IE).

Robin_reala

7:33 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



For non-IE browsers, you can use the power of tables! Well, display:table at least:

#featurecontainer {
display: table;
margin: 0 auto;
}
#featurecontainer .featurebox {
display: table-cell;
padding: 10px;
margin-right: 10px;
font-size: 1.3em;
}

This makes #featurecontainer act like a table and wrap its children which we set to act like table-cells. margin: 0 auto on #featurecontainer make the whole thing center.

If you’re wondering where a table row is, an anonymous one is generated when we try to embed display:table-cell elements into a display:table container directly.

cmarshall

7:50 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Like this?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>
Untitled
</title>
<style type="text/css">
* { margin: 0; padding: 0 }
#featurecontainer { width: 100%; overflow: auto; border:1px solid black }
#featurecontainer .featureboxHolder {
float: left;
width: 33%;
text-align: center;
border:1px solid red;
}
#featurecontainer .featureboxHolder .featurebox
{
text-align: left;
padding: 10px;
margin-left: auto;
margin-right: auto;
font-size: 1.3em;
border:1px solid green;
}
</style>
</head>
<body>
<div id='featurecontainer'>
<div class='featureboxHolder'>
<div class='featurebox'>
<b><u>Info!</u></b><br>
Some Text<br>
</div>
</div>

<div class='featureboxHolder'>
<div class='featurebox'>
<b><u>Info!</u></b><br>
Some Text<br>
</div>
</div>

<div class='featureboxHolder'>
<div class='featurebox'>
<b><u>Info!</u></b><br>
Some Text<br>
</div>
</div>
</div>
</body>
</html>

Here's with fixed "inside" boxes:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>
Untitled
</title>
<style type="text/css">
* { margin: 0; padding: 0 }
#featurecontainer { width: 100%; overflow: auto }
#featurecontainer .featureboxHolder {
float: left;
width: 33%;
text-align: center;
}
#featurecontainer .featureboxHolder .featurebox
{
width: 200px;
text-align: left;
margin-left: auto;
margin-right: auto;
border: 1px solid white;
font-size: 1.3em;
}
</style>
</head>
<body>
<div id='featurecontainer'>
<div class='featureboxHolder'>
<div class='featurebox'>
<b><u>Info!</u></b><br>
Some Text<br>
</div>
</div>

<div class='featureboxHolder'>
<div class='featurebox'>
<b><u>Info!</u></b><br>
Some Text<br>
</div>
</div>

<div class='featureboxHolder'>
<div class='featurebox'>
<b><u>Info!</u></b><br>
Some Text<br>
</div>
</div>
</div>
</body>
</html>

I do stuff like this fairly often.

You can get fancy by using combos of float:left and float:right as well, but the source looks odd.

Fotiman

7:58 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@cmarshall
Your example fills the entire width, and each float then takes up a percentage of that:


+-- 100% width ----------------------------------------+
¦+---- Item 1 ----++---- Item 1 ----++---- Item 1 ----+¦
¦¦................¦¦................¦¦................¦¦
¦+----------------++----------------++----------------+¦

But I think what he's looking for is something more like this:


+-- 100% width ----------------------------------------+
¦``````+-- Item 1 --++-- Item 1 --++-- Item 1 --+``````¦
¦``````¦............¦¦............¦¦............¦``````¦
¦``````+------------++------------++------------+``````¦

Dabrowski

8:11 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes Fotiman, that's it.

Instead of using display: table that doesn't work in IE, could I use an actual <table> that does?

If I do

'margin: 0 auto;'
on the table will that work?

I know it's more markup and I am trying to avoid it, but if there's no other reliable way?

I don't know the width, so without a JS hack to set the position afterwards which I also don't want to do.....

I tried

'display: inline; margin: 0 auto;'
but didn't work. What's the point of inline DIVs anyway, you can't do anything with them.

cmarshall

8:16 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, in that case, can't you just apply the same thing to a contained <div>? I have also done that kind of thing before.

Fotiman

8:34 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




Instead of using display: table that doesn't work in IE, could I use an actual <table> that does?

Sure. It's not very semantic though. Also, there'd be no need for floats at all in that case.


If I do 'margin: 0 auto;' on the table will that work?

Note for IE6 (I don't know about IE7). That would be the correct way to do it, but since IE is behind the times you'd need to do that, and also add a text-align: center; to the element that contains the table.

Dabrowski

10:16 pm on Apr 23, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes the <table> way seems to be the way to go in this instance.

It's a little more markup, but works perfectly. The only thing is to get the spacing between the cells you have to use

cellspacing='10'
as you can't do the margin on a TD.

This in turn adds 10px to the top and bottom of the table too, not a problem in my case but can always use negative margins on the <table> to get around this if need be.

The

'margin: 0 auto;'
does work in IE6 also, so I'm still happy!

SuzyUK

9:27 am on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Centered Floats - Not! [webmasterworld.com]

I wonder if you could combine

display:table-cell;
for FF/Opera and
display:inline-block
for Opera/IE if you're just interested in one row?

Suzy

added: to clarify Opera should do either way

[edited by: SuzyUK at 9:49 am (utc) on April 24, 2007]

Dabrowski

9:55 am on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It is essentially only 1 row, so I could use this. Had a look at your exciting ;) thread, looks like inline-block is possibly the way to go, I'll have a mess when I get home.

A couple of observations though, to achieve the effect in your example, you have 3 nested DIVs:


<div id='container'>
...<div class='box'>
......<div>Content</div>

Now I thought the point was to reduce the markup:


<table id='feature'>
...<tr>
......<td>Content</td>

Same amount, so I'd prefer the <table> way as it works without hackery. I'll have a play with your method though and see if I can get it down to 2 tiers.

Dabrowski

10:00 am on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ooo, also you state that <a> is an inline tag. I'm not about to argue, I've never seen you be wrong about CSS yet, but <a> tags still accept margin/padding etc, whereas <span> doesn't? Maybe <a> is actually an inline-block?

SuzyUK

10:00 am on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



k.. I'm sure it can be done with two tiers.. that thread is a bit overkill for what you're actually describing, it was built with multiple, wrapping rows of images in mind, so I'm not advocating the moz-inline-box solution here.

but the essence of centering inline-blocks (for IE) along with the display:table-cell solution already offered here, is what I think might work

and also there is a way to cure your cellspacing problem if you do use display: table-cell so see how it goes.

Suzy

[edited by: SuzyUK at 10:11 am (utc) on April 24, 2007]

SuzyUK

6:36 pm on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OT but I just saw this after x-posting with you this morning.. will you quit asking questions within questions heh! ;)

<a> tags still accept margin/padding etc, whereas <span> doesn't?

No <a> is an inline element [w3.org] same as a <span> {unless you tell them to display: block;}.

Inline elements will accept margin and padding, though not how you think perhaps.. but not width.

sample:

<style type="text/css" media="screen">
html, body {margin: 0; padding: 0;}
a, span {
margin: 50px;
padding: 20px;
background: #dad;
}
</style>
</head>
<body>
<div>Lorem ipsum dolor sit amet, consectetaur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
<a href="#">text link text</a> <span>text span text</span>
<div>Lorem ipsum dolor sit amet, consectetaur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
</body>
</html>

yes = left/right margin
yes = padding, though it doesn't stretch the line-height it simply overflows the text lines

this is as it should be - they stay within their line box
more on inline boxes [w3.org]

Suzy

[edited by: SuzyUK at 6:41 pm (utc) on April 24, 2007]

SuzyUK

6:40 pm on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



and how did you get on with the inline-blocks?

I'm pleased to say that having mocked up a test based on your OP, in theory it can be done quite easily and not only that you can cure your cellspacing problem, which you can't with a table! :) ok ok.. I'm just rubbing it in now - The choice is still yours

Dabrowski

11:07 pm on Apr 24, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, lots of different suggestions, lots of different hacks/methods of doing things. You've been asking me which ones work, I've just got round to doing a test page with all 6 methods on it.

Fotiman you've been unusually quiet on this one?

Anyway, here's the results, not going into details as I'm about to sticky you all with the test page address so you can see for yourselves.

Who.............HTML...CSS...IE6...IE7...FF2...But... 
--------------------------------------------------------------------------------------------
Me (table)......14.....6.....Yes...Yes...Yes...Slightly more markup
Robin...........14.....12....No....No....Y :/ .No gaps between boxes
cmarshall.......20.....9.....Y :/ .Y :/ .Y :/ .Takes 100% width, not centered
cmarshall again.20.....10....Yes...Yes...Yes...Not exactly what I had in mind, but close
and again.......22.....10....Yes...Yes...Yes...Closer, still relies on a width specification
Suzy............14.....13....Yes...Yes...Yes...Perfect, hackery, more code than table

Suzy, I looked at that other thread about your centered floats, FYI, IE7 only needs the hack if a width is not specified, and FF doesn't need the width specified, but still needs the inner DIV, IE6 & 7 don't.

Can one of you guys please test this in FF1.5, particularly Suzy's fix. Mine upgraded itself to v2.

cmarshall

2:30 am on Apr 25, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Looks good in FF 1.5. I'll email you a screenshot.

SuzyUK

6:42 am on Apr 25, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



what no sticky for me ;)

The reason I pointed out that this should be easy if there's only ONE ROW involved is that you can miss out the '<tr>' step or an extra element to wrap rows, if you needed multiple rows then yes extra elements to mimic a <tr> would be needed if using the table properties - so that solution won't have less markup than a table.

However single rows of blocks (with or without widths) that you happen to want to display side by side (or inline) are different, and display:inline-block seems to me to be the better choice - and just 'cos I want to say this, as it's not often, FF is the one who doesn't play with this version well yet (though Robin didn't you say it was coming in FF3?)

So by using display: table for FF (although I let Opera use it in my sample as well to avoid excess workarounds) that is the hackery. there is a small bonus - the use of display: table means you can use the border-spacing property to control the cellspacing.

But the real benefit/beauty of inline-block is lost when you try to add a width and add lots of boxes - the inline blocks will wrap nicely, and stay centered but the table cells will start acting like table cells, they will not wrap and will shrink to fit (will lose their width) into their "row". Similar to what will happen when you use a table. (that's what the previously referred to thread was all about - wrapping rows of blocks)

So that's the compromise, you either use a table, and realise that both the HTML table or the CSS version is still not the right thing, because it won't scale, but you don't need it to in this case
- or -
you merge the two, use less code and realise that it's the table code (CSS) that is there for back compatibility? because it's inline-blocks you prefer for their scalability and less code.

weird huh! now I'm thinking of table CSS as backwards compatible and IE doesn't even support it yet :)

k just for the record here's the code I have, so you can add it to your tests to compare /* comments inline as usual */

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Untitled</title>
<style type="text/css">
html, body {margin: 0; padding: 0;}
#featurecontainer {
display: table;
margin: 0 auto;
text-align: center; /* center inline blocks for IE */
border-collapse: separate; /* cellspacing */
border-spacing: 10px 0; /* cellspacing distance - horizontal/vertical */
}
#featurecontainer .featurebox {
display: inline-block;
margin: 0 10px 0 0; /* spacing for inline-block, FF and Opera will ignore this */
}
#featurecontainer .featurebox {
display: inline; /* IE workaround, extra rule to get inline-block to work for block element */
}
#featurecontainer .featurebox {
display: table-cell; /* FF and Opera, IE will ignore this and use the above two rules */
text-align: left; /* only if required to override center on container */
padding: 10px;
font-size: 1.3em;
border: 2px solid #dad;
/*width: 180px;*/
}
</style>
</head>
<body>
<div id='featurecontainer'>
<div class='featurebox'><b><u>Info!</u></b><br>Some Text<br></div>
<div class='featurebox'><b><u>Info!</u></b><br>Some Text<br></div>
<div class='featurebox'><b><u>Info!</u></b><br>Some Text<br></div>
</div>
</body>
</html>

Suzy

Dabrowski

3:14 pm on Apr 25, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks Suzy, that way is less hacky. And thanks for the FF1.5 test cmarshall.

I actually managed to shorten it every so slightly, I took the border-separate line out and it still worked.

I changed to 'margin: 0 5px' also to get a true center. But in doing this I found a bug with your last method, it may be the -moz-inline-box thing but the spacing between was actually 14px, not 10. Couldn't see it until this one was next to it.

Am I right in thinking then that IE ignores display table/table-cell, and FF ignores the display: inline-block/inline? This does work without conditional commenting the IE bits, however on the test page I have done as in a real site the CSS would be external and IE's bits included conditionally.

I'm sorry to say I've decided to stick with the table method. If IE7 SP1 decides to fix the table/table-cell/inline-block issues, then this will break the site, whereas the <table> although slightly more markup is at least a 100% stable solution.

you can cure your cellspacing problem, which you can't with a table

Suzy just noticed that in your earlier post, not sure what you mean by it. cellspacing='10' and 'margin: -10px auto' works fine.

SuzyUK

6:36 pm on Apr 25, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I actually managed to shorten it every so slightly, I took the border-separate line out and it still worked.

Yea it will, because 'separate' is the default value for border-collapse, I put it there to highlite that border-spacing and border-collapse work together.

I found a bug with your last method, it may be the -moz-inline-box thing but the spacing between was actually 14px, not 10.

No bug, 'normal' inline behaviour - like when you have two words side by side with whitespace - you get the 4px space and yes it's one of the places where that

-moz-inline-box
falls down, but as alluded to in that previous thread it's a Mozilla proprietary property and as such is not liable to follow 'expected rules' (in fact it's not even the correct property it was just the better of two!) - I never said it was perfect, but I did say previously you didn't need that bit for this application.

Am I right in thinking then that IE ignores display table/table-cell, and FF ignores the display: inline-block/inline?

Yes, but I wouldn't rely on it in one stylesheet for future compat reasons -
1. the 'inline' part (the extra rule after inline-block part of the IE workaround) should NOT be needed by IE either and this is a problem that could potentially be fixed in the future so I would definitely separate them into 'condcoms' targeted at IE7 and below.

2. If IE8 decides to support table properties or fixes their own inline-block anomaly then the method should still be good to go! as the table code is in place for FF/Opera

3. IF OTOH FF3 add support for inline-block then it will take time before we can fully get the semantics side of the code sorted! We might not be able to integrate that solution unless they also build in a way for us to target FF3.

I'm sorry to say I've decided to stick with the table method.

Don't be sorry, like I say it's all down to choice, if that works for you then go with it! :)

If IE7 SP1 decides to fix the table/table-cell/inline-block issues

errr. their inline block works?.. I'd be more concerned with FF fixing their inline-block ;) - IE and Opera manages inline-block fine
- IMHO this is a situation where the info is not tabular data and indeed is blocks of information that you just happen to want to display side by side. In an ideal world I would not be using table properties/markup at all - neither HTML nor CSS - which is where the choice came in to start with no? In fact I'm betting we'll be abusing CSS table properties before long :o

not sure what you mean by it. cellspacing='10' and 'margin: -10px auto' works fine.

Yep it does, as long as only ONE ROW is involved - again it's scalability - confined rows (tables) or wrapping blocks? there are cases for both

anyway thanks for the interesting tests and different methods of applying a theory, good discussion!

Suzy

[edited by: SuzyUK at 7:36 pm (utc) on April 25, 2007]