Clear Rows When Doing Multi-responsive Columns - Bootstrap
Asked Answered
I

10

59

That title might not be very accurate but here is the situation:

The html that does not look proper The view that does not look proper As you can see in the HTML, The grid system goes from 4 images on xl screens to 3 on lg screens to 2 on anything less.

I am trying to get it to display properly - the proper amount of images at each screen size, that is. However, something funky is going on and can't quite figure it out using bootstraps classes.

It seems to me that I would have to add rows dynamically at each break-point.

Any suggestions?

-- UPDATE -- Just realized that col-xl-* doesn't exist. However, that does not change the situation at all. Please disregard the xl declaration.

-- UPDATE 2 -- Updated images.

-- UPDATE 3 -- I'll try to clarify my goal. For that specific image attached in my post, I would like for 3 boxes to appear per row - not all helter skelter.

When it collapses down to 2 boxes per row (xs device), I want to make sure every row has 2 boxes.

Immediacy answered 14/11, 2014 at 21:23 Comment(10)
When you say please disregard, are you telling people to disregard the col-xl-* item you have, or are you telling peple to disregard this question entirely? If it's the latter, then you should delete this question. May want to at least update it with your updated code now that you found that out. :)Congruous
This is the way floated content works. You have the grid classes correct, which is 1/3 at min-width:1200px and up and under that will be 50%. If you want elements to tuck under and fit, you would use a masonry script or investigate flexbox. Alternatively, you can read the documentation and use a responsive utility clearfix shown at the breakpoint in question every 12 columns, at least it will clear but it won't look very goodTripalmitin
Aha! I didn't think of the responsive utility in conjunction with a clearfix. I will try it out.Immediacy
class="clearfix hidden-lg" (after every two of the col-xs-6) and class="clearfix visible-lg after every 3 of the col-lg-4Tripalmitin
See my answers here: https://mcmap.net/q/47942/-gap-in-bootstrap-stacked-rowsDescendible
@Tripalmitin - I didn't think this through, it will not work without javascript.Immediacy
clearfix works without js. Like I wrote, it looks bad, but it clears. Check out masonry, istope masonry, mason, packery, shuffle, and a bunch of other js solutions or flexbox cssTripalmitin
@Tripalmitin - Could you post an answer, then, with the full solution? I am unsure how to include those classes after every those specified increments without using some php or javscript code.Immediacy
If you need to do this with php, then ask that question with the php tag.Tripalmitin
You may consider forcing all columns to the same height. #19696284Bendicty
T
44

I solved this issue by adding clearfix elements where they should be. I wanted 3 columns on md and 2 columns on sm and this is how I did it:

<div class="row">
    <div class="col-sm-6 col-md-4"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-sm"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-md"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-sm"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-md"></div>
    <div class="clearfix visible-sm"></div>
    <div class="col-sm-6 col-md-4"></div>
</div>

So i used clearfix visible-sm after every second div and clearfix visible-md after every third div. I don't find this solution ideal, but it works rather well.

EDIT: As of Bootstrap v3.2.0 .visible-* classes are deprecated.

http://getbootstrap.com/css/#responsive-utilities:

The classes .visible-xs, .visible-sm, .visible-md, and .visible-lg also exist, but are deprecated as of v3.2.0. They are approximately equivalent to .visible-*-block, except with additional special cases for toggling -related elements.

EDIT 2: This solution works as long as you do not want to edit CSS, if you have the option to do so, I recommend you use Jonas's answer as it is much simpler in my opinion.

Toby answered 1/5, 2015 at 9:34 Comment(8)
So, even if it is hidden it won't apply the clear? I am guessing this is so not because it is hidden, but because bootstrap must use display:none instead of visibility:hidden. I haven't tried this solution, but it does seem to be pretty much what I had envisioned! Thanks!Immediacy
Based on what I found out from bootstrap.css, .visible-* uses display: none!important;, so clear wont be applied by that clearfix. Also, classes .visible-* are deprecated as of Bootstrap v3.2.0, you should use .visible-*-block, which should have almost the same effect. I'll edit the answer.Toby
I tested this out and it works well! I think this was exactly what I was looking for. Fiddle to play with: jsfiddle.net/3muu0jnd.Immediacy
Thank you! I could not understand it from the official documentation.Filling
You will most likely want to add visible-lg as well to all the visible-md divs, since you're saying you want there to be 3 columns to a row even at larger sizes than md. Otherwise, if the browser were in the lg range, the clearfix div would no longer be visible!Extravagance
I said I wanted 3 columns on md and 2 columns on sm, I did not mention anything about lg. But you are right, if I wanted to have 3 columns on lg too, I'd have to include visible-lg as well. Thanks for pointing that out.Toby
Since I've gained more knowledge, I'd like to add a point - this solution is great IF one DOES NOT want to extend Bootstrap's css. This solution can be done just using Bootstrap classes and html. See Jonas Appelgran's answer for something that I now find cleaner and more elegant but involves extending Bootstrap's css.Immediacy
Life saver, :D Thank you!Toole
H
71

Extend your bootstrap.css with this css:

@media (min-width:1200px){
    .auto-clear .col-lg-1:nth-child(12n+1){clear:left;}
    .auto-clear .col-lg-2:nth-child(6n+1){clear:left;}
    .auto-clear .col-lg-3:nth-child(4n+1){clear:left;}
    .auto-clear .col-lg-4:nth-child(3n+1){clear:left;}
    .auto-clear .col-lg-6:nth-child(odd){clear:left;}
}
@media (min-width:992px) and (max-width:1199px){
    .auto-clear .col-md-1:nth-child(12n+1){clear:left;}
    .auto-clear .col-md-2:nth-child(6n+1){clear:left;}
    .auto-clear .col-md-3:nth-child(4n+1){clear:left;}
    .auto-clear .col-md-4:nth-child(3n+1){clear:left;}
    .auto-clear .col-md-6:nth-child(odd){clear:left;}
}
@media (min-width:768px) and (max-width:991px){
    .auto-clear .col-sm-1:nth-child(12n+1){clear:left;}
    .auto-clear .col-sm-2:nth-child(6n+1){clear:left;}
    .auto-clear .col-sm-3:nth-child(4n+1){clear:left;}
    .auto-clear .col-sm-4:nth-child(3n+1){clear:left;}
    .auto-clear .col-sm-6:nth-child(odd){clear:left;}
}
@media (max-width:767px){
    .auto-clear .col-xs-1:nth-child(12n+1){clear:left;}
    .auto-clear .col-xs-2:nth-child(6n+1){clear:left;}
    .auto-clear .col-xs-3:nth-child(4n+1){clear:left;}
    .auto-clear .col-xs-4:nth-child(3n+1){clear:left;}
    .auto-clear .col-xs-6:nth-child(odd){clear:left;}
}

Use it like:

<div class="row auto-clear">
    <div class="col-xs-6 col-sm-4 col-md-4 col-lg-3">
        <p>Hey</p>
    </div>
</div>

Note: this requires the use of all col-sizes and that all cols are of the same size.

Hardiman answered 5/11, 2015 at 9:19 Comment(2)
Thanks! I'm including an .scss version of this as an answer as well.Schweiz
As I've aged, I find this answer a bit more elegant if one is open to extending the Bootstrap css. I find it to be cleaner and more maintainable in the long run and keeps the HTML less polluted.Immediacy
T
44

I solved this issue by adding clearfix elements where they should be. I wanted 3 columns on md and 2 columns on sm and this is how I did it:

<div class="row">
    <div class="col-sm-6 col-md-4"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-sm"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-md"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-sm"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="col-sm-6 col-md-4"></div>
    <div class="clearfix visible-md"></div>
    <div class="clearfix visible-sm"></div>
    <div class="col-sm-6 col-md-4"></div>
</div>

So i used clearfix visible-sm after every second div and clearfix visible-md after every third div. I don't find this solution ideal, but it works rather well.

EDIT: As of Bootstrap v3.2.0 .visible-* classes are deprecated.

http://getbootstrap.com/css/#responsive-utilities:

The classes .visible-xs, .visible-sm, .visible-md, and .visible-lg also exist, but are deprecated as of v3.2.0. They are approximately equivalent to .visible-*-block, except with additional special cases for toggling -related elements.

EDIT 2: This solution works as long as you do not want to edit CSS, if you have the option to do so, I recommend you use Jonas's answer as it is much simpler in my opinion.

Toby answered 1/5, 2015 at 9:34 Comment(8)
So, even if it is hidden it won't apply the clear? I am guessing this is so not because it is hidden, but because bootstrap must use display:none instead of visibility:hidden. I haven't tried this solution, but it does seem to be pretty much what I had envisioned! Thanks!Immediacy
Based on what I found out from bootstrap.css, .visible-* uses display: none!important;, so clear wont be applied by that clearfix. Also, classes .visible-* are deprecated as of Bootstrap v3.2.0, you should use .visible-*-block, which should have almost the same effect. I'll edit the answer.Toby
I tested this out and it works well! I think this was exactly what I was looking for. Fiddle to play with: jsfiddle.net/3muu0jnd.Immediacy
Thank you! I could not understand it from the official documentation.Filling
You will most likely want to add visible-lg as well to all the visible-md divs, since you're saying you want there to be 3 columns to a row even at larger sizes than md. Otherwise, if the browser were in the lg range, the clearfix div would no longer be visible!Extravagance
I said I wanted 3 columns on md and 2 columns on sm, I did not mention anything about lg. But you are right, if I wanted to have 3 columns on lg too, I'd have to include visible-lg as well. Thanks for pointing that out.Toby
Since I've gained more knowledge, I'd like to add a point - this solution is great IF one DOES NOT want to extend Bootstrap's css. This solution can be done just using Bootstrap classes and html. See Jonas Appelgran's answer for something that I now find cleaner and more elegant but involves extending Bootstrap's css.Immediacy
Life saver, :D Thank you!Toole
S
11

An .scss fix using bootstrap variables, taken from @jonas and @yog

@mixin row-first-child($col-type) {
  .col-#{$col-type}- {
    &1:nth-child(12n+1),
    &2:nth-child(6n+1),
    &3:nth-child(4n+1),
    &4:nth-child(3n+1),
    &6:nth-child(odd){
      clear: left;
    }
  }
} 

.auto-clear {
  @media (min-width: $screen-lg-min){
    @include row-first-child(lg);
  }
  @media (min-width: $screen-md-min) and (max-width: $screen-md-max){
    @include row-first-child(md);
  }
  @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max){
    @include row-first-child(sm);
  }
  @media (max-width: $screen-xs-max){
    @include row-first-child(xs);
  }
}
Schweiz answered 7/1, 2016 at 20:22 Comment(1)
Note: The only problem with this is that you have to use all col-xx-xx classes. Where you might use col-sm-4 col-xs-6 you'll have to use col-lg-4 col-md-4 col-sm-4 col-xs-6 inside of .auto-clear.Schweiz
L
3

The reason why your layout is breaking is due to the dynamic height of the images being presented. The fix is simple though, just constrain the height of the images. For example

HTML

<div class="container">
  <div class="row">
    <div id="uploaded">
      <div class="col-xs-6 col-lg-4">
        <div class="file-block">
          <div class="file-thumbnail">
            <img src="http://placehold.it/200x500" alt="">
          </div>
          <div class="file-row-footer">
            <a href="javascript:void(0)"> Delete</a>
          </div>
        </div>
      </div>

      <div class="col-xs-6 col-lg-4">
        <div class="file-block">
          <div class="file-thumbnail">
            <img src="http://placehold.it/200x500" alt="">
          </div>
          <div class="file-row-footer">
            <a href="javascript:void(0)"> Delete</a>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

CSS

.file-block {
  border: 1px solid #ccc;
  border-radius: 10px;
  margin: 20px 0px;
  text-align: center;
}

.file-thumbnail {
  display: block;
  padding: 4px;
  margin-bottom: 20px;
  line-height: 1.42857143;
  height: 180px;
  font: 0/0 a;         /* remove the gap between inline(-block) elements */
}

.file-thumbnail:before {
  content: ' ';
  display: inline-block;
  vertical-align: middle;  /* vertical alignment of the inline element */
  height: 100%;
}

.file-thumbnail img {
  display: inline-block;
  margin: 0 auto;
  max-width: 150px;
  max-height: 180px;
  vertical-align: middle;
}

Check out the CodePen to see it in action. Hope this helps.

Lamination answered 15/11, 2014 at 18:36 Comment(2)
Yes, this is one possible solution. However, it was not what I was going for. I want the images to, indeed, have dynamic heights. +1 for an alternative solution.Immediacy
constrain? its contrary to the principle that make me use bsPolypus
N
1

Bootstrap 4 introduces hidden-*-up and hidden-*-down classes. Very handy (and elegant) utility for situations such as these.

Available classes

  • The .hidden-*-up classes hide the element when the viewport is at the given breakpoint or wider. For example, .hidden-md-up hides an element on medium, large, and extra-large viewports.
  • The .hidden-*-down classes hide the element when the viewport is at the given breakpoint or smaller. For example, .hidden-md-down hides an element on extra-small, small, and medium viewports.
  • There are no explicit “visible”/”show” responsive utility classes; you make an element visible by simply not hiding it at that breakpoint size.
  • You can combine one .hidden-*-up class with one .hidden-*-down class to show an element only on a given interval of screen sizes. For example, .hidden-sm-down.hidden-xl-up shows the element only on medium and large viewports. Using multiple .hidden-*-up classes or multiple .hidden-*-down classes is redundant and pointless.
  • These classes don’t attempt to accommodate less common cases where an element’s visibility can’t be expressed as a single contiguous range of viewport breakpoint sizes; you will instead need to use custom CSS in such cases.

http://v4-alpha.getbootstrap.com/layout/responsive-utilities/

Neoterize answered 13/10, 2016 at 20:39 Comment(2)
Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline.Beelzebub
Thanks @pableiros. I've edited as per your suggestion. Cheers!Neoterize
C
1

Adding to @Jonas and @KFunk's answer:

Potential fix for requiring the use of all col-sizes (col-xs-6 col-sm-4 col-md-4 col-lg-4).

Classes created: auto-clear-xs, auto-clear-sm, auto-clear-md and auto-clear-lg.

I've made my answer mobile-first.

Note: This still requires the columns to be the same size.

HTML

<div class="row auto-clear-xs auto-clear-lg">
    <div class="col-xs-6 col-lg-3">
        <p>Hey</p>
    </div>
</div>

SCSS

@mixin row-first-child($col-type, $clear-type) {
   .col-#{$col-type}- {
    &1:nth-child(12n+1),
    &2:nth-child(6n+1),
    &3:nth-child(4n+1),
    &4:nth-child(3n+1),
    &6:nth-child(odd){
      clear: $clear-type;
    }
  }
}

.auto-clear-xs{
  @media (min-width: $screen-xs-min){
    @include row-first-child(xs, both);
}
  @media (max-width: $screen-xs-min){
    @include row-first-child(xs, both);
  }
}

.auto-clear-sm{
  @media (min-width: $screen-sm){
    @include row-first-child(xs, none);
    @include row-first-child(sm, both);
  }
}

.auto-clear-md{
  @media (min-width: $screen-md){
    @include row-first-child(xs, none);
    @include row-first-child(sm, none);
    @include row-first-child(md, both);
  }
}

.auto-clear-lg{
  @media (min-width: $screen-lg){
    @include row-first-child(xs, none);
    @include row-first-child(sm, none);
    @include row-first-child(md, none);
    @include row-first-child(lg, both);
  }
}

CSS

@media (min-width: 480px) {
  .auto-clear-xs .col-xs-1:nth-child(12n+1), 
  .auto-clear-xs .col-xs-2:nth-child(6n+1), 
  .auto-clear-xs .col-xs-3:nth-child(4n+1), 
  .auto-clear-xs .col-xs-4:nth-child(3n+1), 
  .auto-clear-xs .col-xs-6:nth-child(odd) {
    clear: both;
  }
}
@media (max-width: 480px) {
  .auto-clear-xs .col-xs-1:nth-child(12n+1), 
  .auto-clear-xs .col-xs-2:nth-child(6n+1), 
  .auto-clear-xs .col-xs-3:nth-child(4n+1), 
  .auto-clear-xs .col-xs-4:nth-child(3n+1), 
  .auto-clear-xs .col-xs-6:nth-child(odd) {
    clear: both;
  }
}


@media (min-width: 768px) {
  .auto-clear-sm .col-xs-1:nth-child(12n+1), 
  .auto-clear-sm .col-xs-2:nth-child(6n+1), 
  .auto-clear-sm .col-xs-3:nth-child(4n+1), 
  .auto-clear-sm .col-xs-4:nth-child(3n+1), 
  .auto-clear-sm .col-xs-6:nth-child(odd) {
    clear: none;
  }
  .auto-clear-sm .col-sm-1:nth-child(12n+1), 
  .auto-clear-sm .col-sm-2:nth-child(6n+1), 
  .auto-clear-sm .col-sm-3:nth-child(4n+1), 
  .auto-clear-sm .col-sm-4:nth-child(3n+1), 
  .auto-clear-sm .col-sm-6:nth-child(odd) {
    clear: both;
  }
}

@media (min-width: 992px) {
  .auto-clear-md .col-xs-1:nth-child(12n+1), 
  .auto-clear-md .col-xs-2:nth-child(6n+1), 
  .auto-clear-md .col-xs-3:nth-child(4n+1), 
  .auto-clear-md .col-xs-4:nth-child(3n+1), 
  .auto-clear-md .col-xs-6:nth-child(odd) {
    clear: none;
  }
  .auto-clear-md .col-sm-1:nth-child(12n+1), 
  .auto-clear-md .col-sm-2:nth-child(6n+1), 
  .auto-clear-md .col-sm-3:nth-child(4n+1), 
  .auto-clear-md .col-sm-4:nth-child(3n+1), 
  .auto-clear-md .col-sm-6:nth-child(odd) {
    clear: none;
  }
  .auto-clear-md .col-md-1:nth-child(12n+1), 
  .auto-clear-md .col-md-2:nth-child(6n+1), 
  .auto-clear-md .col-md-3:nth-child(4n+1), 
  .auto-clear-md .col-md-4:nth-child(3n+1), 
  .auto-clear-md .col-md-6:nth-child(odd) {
    clear: both;
  }
}

@media (min-width: 1200px) {
  .auto-clear-lg .col-xs-1:nth-child(12n+1), 
  .auto-clear-lg .col-xs-2:nth-child(6n+1), 
  .auto-clear-lg .col-xs-3:nth-child(4n+1), 
  .auto-clear-lg .col-xs-4:nth-child(3n+1), 
  .auto-clear-lg .col-xs-6:nth-child(odd) {
    clear: none;
  }
  .auto-clear-lg .col-sm-1:nth-child(12n+1), 
  .auto-clear-lg .col-sm-2:nth-child(6n+1), 
  .auto-clear-lg .col-sm-3:nth-child(4n+1), 
  .auto-clear-lg .col-sm-4:nth-child(3n+1), 
  .auto-clear-lg .col-sm-6:nth-child(odd) {
    clear: none;
  }
  .auto-clear-lg .col-md-1:nth-child(12n+1), 
  .auto-clear-lg .col-md-2:nth-child(6n+1), 
  .auto-clear-lg .col-md-3:nth-child(4n+1), 
  .auto-clear-lg .col-md-4:nth-child(3n+1), 
  .auto-clear-lg .col-md-6:nth-child(odd) {
    clear: none;
  }
  .auto-clear-lg .col-lg-1:nth-child(12n+1), 
  .auto-clear-lg .col-lg-2:nth-child(6n+1), 
  .auto-clear-lg .col-lg-3:nth-child(4n+1), 
  .auto-clear-lg .col-lg-4:nth-child(3n+1), 
  .auto-clear-lg .col-lg-6:nth-child(odd) {
    clear: both;
  }
}
Caput answered 20/4, 2017 at 16:28 Comment(0)
H
0

Looks like the only solution to your problem is to set a min-height or a fixed height to your elements to that there are no inconsistensies that cause your issues.

add this:

.file-row-contain {
  min-height:250px;
}

...set height according to your needs

Hypochromia answered 15/11, 2014 at 16:48 Comment(0)
A
0

You can fix this very easily with css if you don't need to support IE8.

.file-row-contain.col-lg-4:nth-child(3n+1),
.file-row-contain.col-xs-6:nth-child(2n+1) { 
    clear: left; 
}

See examples

Allcot answered 3/12, 2014 at 21:55 Comment(1)
This won't work because elements have both of those classes (.col-lg-4, .col-xs-6), so it won't be responsive.Toby
M
0

I was looking for a solution as well and since my HTML gets rendered through a CMS I couldn't use the solution of the accepted answer.

So my solution is:

.teaser {
  // break into new line after last element
  > div:last-child {
    clear: right;
  }
}

.teaser {
  // two colums
  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
    > div:nth-child(2n+1) {
      clear: left;
    }
  }
}

.teaser {
  // three colums
  @media (min-width: @screen-md-min) {
    > div:nth-child(3n+1) {
      clear: left;
    }
  }
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row teaser">
    <div class="col-sm-6 col-md-4">div1</div>
    <div class="col-sm-6 col-md-4">div2<br>more content</div>
    <div class="col-sm-6 col-md-4">div3</div>
    <div class="col-sm-6 col-md-4">div4</div>
    <div class="col-sm-6 col-md-4">div5<br>more content content<br>content</div>
    <div class="col-sm-6 col-md-4">div6</div>
    <div class="col-sm-6 col-md-4">div7<br>more content</div>
    <div class="col-sm-6 col-md-4">div8</div>
</div>

Hope this helps someone :-)

Minorca answered 1/12, 2015 at 14:53 Comment(0)
S
0

In case your number of col- boxes in a row is DYNAMIC and different for resolution like it is in my case than based on your col- classes do the modulus operator. Take example of below example.

<div class="row">
    <?php $elementCounter = 0; ?>
    <?php foreach ( $this->programs as $program ): ?>
        <div class="col-xs-6 col-sm-3"> DATA </div>
        <?php $elementCounter++; ?>
        <?php if( $elementCounter % 4 == 0 ): ?>
            <div class="clearfix hidden-xs"></div>
        <?php elseif( $elementCounter % 2 == 0 ): ?>
            <div class="clearfix visible-xs"></div>
        <?php endif; ?>
    <?php endforeach; ?>
</div>

col-xs-6 means it has 2 boxes in a row for extra-small devices. so for it I've added that $elementCounter % 2 == 0 condition so it is true for every second element ( AFTER ). and added clearfix with visible-xs so it shouldn't effect on desktop or other resolutions.

col-sm-3 means 4 boxes in row for small and above devices so in that case i've added $elementCounter % 4 == 0 and with that hidden-xs so that clearfix is hidden for xs devices and will be visible for small and above. This way you can modify it accordingly.

Stithy answered 16/4, 2018 at 13:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.