1

I need to find a way to clearfix a set of floated elements without extra markup.

For example, I have a 2 columns grid in section#main_features. Each div.feature has width: 50% and is float: left. What I want is to find a way to clearfix the rows without extra html markup (since I want to make a simple semantic grid).

<section id="main_features">
  <div class="feature">
    ...
  </div>
  <div class="feature">
    ...
  </div>
  <div class="feature">
    ...
  </div>
  <div class="feature">
    ...
  </div>
</section>

Note that the rows here are just a "concept" (each row is two .feature). I'm using a semantic approach to build this grid, therefore I don't want to need to wrap the columns of each row and then clearfix this wrapper. I'm looking for some trick to clearfix and break the row using only css - or scss, less, etc.

This problem seems to be more complex than it looks.

Thanks in advance.

Bernardo
  • 519
  • 5
  • 16
  • You'll have to clearfix `#main_features`, unless you add in a row element (i.e. wrap two `.feature` elements inside a `div`, for example). – BenM Feb 14 '13 at 11:59
  • Clearfix `#main_features` will not to clearfix the rows. To wrap the two `.feature` elements works, but thats what I want to avoid. – Bernardo Feb 14 '13 at 12:18
  • I know that clearing `#main_features` won't work. That's not what I was suggesting. I was implying that with your current markup, it's your only option ;) – BenM Feb 14 '13 at 12:19
  • Yeah, I think you're right. To wrap the columns in an element and clearfix it seems to be the only option after all :( – Bernardo Feb 14 '13 at 12:33

4 Answers4

3

You can use the css :after to do this, just by putting an invisible full stop after it, forcing the clear fix.

.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

Alternatively, I just found this newer one from Beau Smiths answer here

/* For modern browsers */
.container:before,
.container:after {
    content:"";
    display:table;
}
.container:after {
    clear:both;
}
/* For IE 6/7 (trigger hasLayout) */
.container {
    zoom:1;
}
Community
  • 1
  • 1
Andy
  • 14,427
  • 3
  • 52
  • 76
  • Actually, I need an extra markup for this. The `.container` should be insert to contain the columns and clearfix the rows. – Bernardo Feb 14 '13 at 12:15
3

I have been using the semantic group 'micro clearfix' which I found on CSS Tricks.

.group:after {
  content: "";
  display: table;
  clear: both;
}

The CSS is similar to the above solutions, however the concept is that you can add it to any element which you wish to 'group' together and be followed by a clear. Eg:

<header id="masthead" class="group">
  //content
</header>

The above link also has sub-IE8 rules.

EDIT My apologies, I just answered the title of the question, without properly reading your scenario. I would not use floats in this case. Instead, I like to use display: inline-block like so:

#main_features {
  font-size: 0; /* this resets the default padding created by the inline-block rule below */
  margin: -2%; /* offsets the positive margin below */
}

.feature {
  display: inline-block;
  vertical-align: top;
  width: 46%;
  margin: 2%; /* width + (2x margin) = 50%*/
  font-size: 12px; /* because it is reset to 0 by parent */
}

The font is set to zero on the parent element because some browsers add padding to an inline-block element. The parent element also has a negative margin to offset that of its children. This allows the content to align with the rest of your page.

I have made a basic demo of this here.

Astrotim
  • 2,152
  • 19
  • 23
  • Since I want to clearfix the rows (each row is two `.feature` in my example), I need an extra markup to `.group` them. I'm looking for some trick to clearfix the nth element of a row without extra markup. Note that the row exists just in "concept" in semantic approach. – Bernardo Feb 14 '13 at 13:13
0

If you have been applying clearfix with a class-name and the appropriate selector (.clearfix), then you can do the same with the selector #main_features

So if your normal clearfix style declarations look like this:

.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
*:first-child+html .clearfix { zoom: 1; } /* IE7 */

...then you can avoid having to apply the clearfix class simply by adding to the selector this way:

.clearfix:after, #main_features:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0;  }
*:first-child+html .clearfix, *:first-child+html #main_features { zoom: 1; } /* IE7 */

...and just leave your markup as-is.

Faust
  • 15,130
  • 9
  • 54
  • 111
0

It's an quiet old question but I just stumbled upon it while having a similar question. Anyways I solved it by using the nth-child pseudo selector to clear the float every third child within the container.

.main_features .feature:nth-child(3n) {
  clear: left;
}
yohanesu
  • 1
  • 1