3

I have a div with some inline elements inside it. I want to put one of the elements on the left and the rest over on the right:

+---------------------------+
|+----+      +-----+ +-----+|
|| A  |      |  B  | |  C  ||
|+----+      |     | |     ||
|            |     | |     ||
|            |     | |     ||
|            +-----+ +-----+|
+---------------------------+

I tried using float:right on BC and C but that removes them from the flow, making them stand out of the container:

+---------------------------+
|+----+      +-----+ +-----+|
|| A  |      |  B  | |  C  ||
|+----+      |     | |     ||
+------------|     |-|     |+
             |     | |     |
             +-----+ +-----+

What are the best alternatives for putting things over on the right without having them spill out of the outer container?

EDIT: Most answers seem to suggest either using overflow-auto or clear. What is the difference between them? How do I choose one over the other? Also, everyone seems to assume that I need to float the elements. Is float the only way to put things over on the right?

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • Wouldn't clearfix solve this? – smilly92 Jul 29 '12 at 13:12
  • @smilledge: What is clearfix? – hugomg Jul 29 '12 at 13:13
  • maybe providing code or jsfiddle is better – bugwheels94 Jul 29 '12 at 13:15
  • 1
    use this to clear your floating elements `
    ` using this wont spill those two divs out of the flow
    – Mr. Alien Jul 29 '12 at 13:18
  • set overflow:auto; on the parent div – bugwheels94 Jul 29 '12 at 13:19
  • @AnkitGautam: I don't know if code would help that much, I'm not looking to fix a particular situation as much as I am trying to write things in the first place. – hugomg Jul 29 '12 at 13:20
  • @Ankit Gautam, I think you mean `overflow: hidden;`? Overflow would be set to auto be default... – smilly92 Jul 29 '12 at 13:21
  • @smilledge no i mean auto and by default overflow is visible – bugwheels94 Jul 29 '12 at 13:22
  • But wouldn't `overflow: auto;` cause scrollbars? (http://css-tricks.com/the-css-overflow-property/) – smilly92 Jul 29 '12 at 13:28
  • Actually, looks like it doesn't. Why have I been using clearfix all my life?!?! – smilly92 Jul 29 '12 at 13:30
  • 1
    no they will not add scrollbar until you add a fixed height to parent – bugwheels94 Jul 29 '12 at 13:30
  • What you want is to [clearfix the container](http://stackoverflow.com/questions/211383/which-method-of-clearfix-is-best) so the floated elements trigger the container to take it's height from them. I suspect `display: inline-block` would be "best", but some older browsers don't support it. You could also use `position`ing or `display: table-cell` (in a fashion). – Jared Farrish Jul 29 '12 at 13:38
  • I see you've already selected an answer, but this was what I was going to propose: http://jsfiddle.net/AZJzz/ This doesn't work in IE7, but does in IE8 and above and Chrome, Opera and Firefox. – Jared Farrish Jul 29 '12 at 13:46
  • @JaredFarrish: Cool Hack! :) However, it looks like it will only work if you know the width of the container a priori... – hugomg Jul 29 '12 at 13:51
  • 1
    It's not a hack. That's the way *it's supposed to be*. Floating elements and clearfixing *is a hack*. And that width was only a side-effect of trying to make what you were showing; if you're talking liquid-layouts, that could be accommodated, probably with percentages. – Jared Farrish Jul 29 '12 at 13:54
  • @Jared Farrish: Upvote of commendation for calling the clearfix a hack. – BoltClock Jul 29 '12 at 13:55
  • @BoltClock - Clearfix was a nifty (and necessary) tool, but the sooner IE7 fades into the mists of time, the better off we'll all be. – Jared Farrish Jul 29 '12 at 13:59
  • Here is a width-agnostic approach (could still be tweaked, but you get the idea): http://jsfiddle.net/AZJzz/2/ – Jared Farrish Jul 29 '12 at 14:06

6 Answers6

3

When you float elements the parent's height is not calculated. Either you can use the clearfix class, or you can clear floats using the overflow property.

You can also add <div style="clear:both;"></div> at the end of your parent div, however this is less semantic the the above solutions.

However, what you choose to use is really a personal preference.

Also you might want to try using a grid system. You can try 960 or Bootstrap.

smilly92
  • 2,383
  • 1
  • 23
  • 43
  • 2
    The `overflow` property does not technically clear floats - rather, it causes the element to form a new [formatting context](http://www.w3.org/TR/CSS21/visuren.html#block-formatting) in which the floats can be contained. This causes the container to stretch to the height of the floats in order to contain them, so scrollbars won't appear for `overflow: auto` until you force it to have a height that is less than the floats will occupy. – BoltClock Jul 29 '12 at 13:34
3

One simple solution is to add overflow:autoto the container in order to solve this. This will cause the container to expand to contain its floats but will make scrollbars appear if for some reason someone additionally sets a small height for the container.

There are also other alternatives that also work and might be better in other cases. See this question and its second answer for a good overview on the problem.

Community
  • 1
  • 1
4ndro1d
  • 2,926
  • 7
  • 35
  • 65
2

You need to clear out your floating elements like this :

<div style="clear: both;"></div>

My Fiddle

If you dont-clear it'll be like this : My Fiddle (Floats not cleared)

Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
2

For the record, there is a better (at least in my eyes) way of doing this than float-happy clearfixing. Use display: inline-block. The downside? IE7 doesn't support it (of course). The below works, though, in IE8 and above and Chrome, Firefox and Opera.

NOTE: I've simplified the demo's CSS in an attempt to dispel perceptions this is complicated. It's not. The display: inline-block is the only part you need; the rest is part of the attempt to match what the OP described in the question's depiction.

<div id="container">
    <div id="a">A</div>
    <div id="b">B</div>
    <div id="c">C</div>
</div>

#container {
    background: #ddd;
    text-align: center;
}
#container > div {
    background: #cff;
    display: inline-block;
    padding: 2%;
    height: 100px;
    width: 25%;
}
#container #a {
    height: 30px;
    margin: 0 10% 0 0;
}

http://jsfiddle.net/AZJzz/4

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • is there anyway this approach would work for a fluid-width layout? – Jan Drewniak Jul 29 '12 at 14:03
  • I was just working on that. Haven't gotten the width on the `#container` right, but: http://jsfiddle.net/AZJzz/1/ – Jared Farrish Jul 29 '12 at 14:04
  • Could still use some tweaking, but this shows it will work: http://jsfiddle.net/AZJzz/2/ – Jared Farrish Jul 29 '12 at 14:06
  • Using inline-blocks can be a nice alternative to floats, especially for something like this. It can make you have to think of the elements in play slightly differently, but not a bad thing in any means. – Fewfre Jul 29 '12 at 14:07
  • @Kyomu - Clearfixing is a hack; it's because `display: inline-block` wasn't initially well-supported back in the table-display days. IE6 "naturally" did something like clearfixing due to a bug (one of hundreds in IE6), and clearfixing was seen as an acceptable method. ONE DAY, please God, clearfixing will no longer be necessary. But be sure, it is *not* the alternative. – Jared Farrish Jul 29 '12 at 14:09
  • @JaredFarrish I said "a nice alternative". As in another, **good** way to do it. No need to read so deeply into a complement ;) Last part of my comment was just saying might be more than others want to deal with. – Fewfre Jul 29 '12 at 14:25
  • @Kyomu - I remember when clearfix was developed (around 2004 I believe). The mentality that you're promoting, that it's harder to do it "right", is just wrong in my mind; clearfixing *is harder* and requires more markup in many cases. Here's an interactive demo: http://jsfiddle.net/AZJzz/4/ You're telling me that's *harder* than clearfixing? The `position` part was only to match what the OP had in the question, that is not required to make this work. – Jared Farrish Jul 29 '12 at 14:30
  • @JaredFarrish Again, I never said its harder to do it the 'right' way, I said it makes you think differently, and as such some people might prefer dealing with what they know (or floats). I'm simply pointing out, the OP asked how to do it with floats, and as such he might be more comfortable with them. But my point was that I'm glad you pointed out a good way to do it without floats, if he wanted. – Fewfre Jul 29 '12 at 17:10
1

Place this line after it:

<div style="clear:both;"></div>

This should extend the div they are in to fit around them.

Here's a live demo, to illustrate how to do it.

Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
Fewfre
  • 1,461
  • 3
  • 19
  • 32
0

Currently floats are probably the only way to get the desired result. You can also float the parent container, but then you'll then have to give it a width. This method can quickly lead to a 'float everything' layout, but it works. http://jsfiddle.net/mjzNP/

Community
  • 1
  • 1
Jan Drewniak
  • 1,316
  • 15
  • 18
  • They're not the only way. There are even some that see floats as strictly *not* the right way (since it's meant for text flow, not block flow). This is what `display: inline-block` is for, but it's not well supported in IE7 and 8 I believe. – Jared Farrish Jul 29 '12 at 13:44