-3

Quick Tip: Building Responsive Layouts With Floats

In today’s quick tip, we’ll learn how to build responsive layouts using CSS floats, an old yet trusted layout method. With that done, we’ll see how Bootstrap handles things. Floats weren’t initially intended to form the basis of page structure (newer CSS standards such as flexbox and grid aim to address that), so working with floats can sometimes be tricky. Let’s look at an example to illustrate that.

Building a Responsive Layout

Let’s assume that we want to build this card layout:

Check out the full size version for a clearer idea.

Basic Styles

For these cards, we don’t want to set a fixed height for the captions. Neither do we want them to be fixed width. Therefore, to keep the cards usable, so they don’t squash up too much, we need to display a different number of columns depending on the viewport size.

We set up some media queries, so that the following is true:

Viewport No. of columns
<400px 1
≥400px 2
≥768px 3
≥1024px 4

Here’s the markup; list items containing images and captions within figure elements:

<ul class="clearfix">
  <li>
    <figure>
      <img src="path-to-the-image" alt="">
      <figcaption>Some description here</figcaption>
    </figure>
  </li>
        
  <!-- more list items here -->
</ul>

Here’s the CSS to style that layout:

/* stylistic styles */
body {
  width: 80%;
  max-width: 1200px;
  margin: 40px auto;
  font: normal 14px/1.5 "Montserrat", "Helvetica Neue", sans-serif;
  background: #cfd8dc;
  color: #37474f;
}
 
figure {
  background: whitesmoke;
  margin: 0 0 40px;
  box-shadow: 0px 2px 4px rgba(0,0,0,0.2);
}
 
figcaption {
  padding: 20px;
}
 
img {
  max-width: 100%;
  height: auto;
  display: block;
}
 
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}
 
ul {
  margin: 0;
  padding: 0;
}
 
/* structural styles */
 
li {
  list-style-type: none;
  float: left;
  padding-left: 15px;
  padding-right: 15px;
  box-sizing: border-box;
}
 
/* media queries */
 
@media screen and (min-width: 400px) {
  li {
    width: 50%;
  }
}
 
@media screen and (min-width: 768px) {
  li {
    width: 33.333%;
  }
}
 
@media screen and (min-width: 1024px) {
  li {
    width: 25%;  
  }    
}

You’ll notice the media queries at the bottom, which dictate how wide the cards are at certain viewports. Here’s what it gives us:

The problem with this fluid layout, however, is that by not clearing each new row, some cards are getting stuck when trying to find their way back across to the left.

Identifying Cards to Clear

According to the example above, when the row contains four cards, we need to clear the fifth, then the ninth, and so on. To achieve this, we use the :nth-of-type(an+b) CSS pseudo-class where the an+b parameter represents the desired repeating pattern. For example, on large screens (i.e. ≥1024px), we use 4n+1. This formula finds each element which is a factor of four, then selects the next one.

Here’s how we might change our media queries to alter which cards are cleared:

Viewport No. of columns Repeating pattern
<400px 1 -
≥400px 1 2n + 1
≥768px 1 3n + 1
≥1024px 1 4n + 1

And here’s the CSS which achieves that. Note that our media queries are cumulative, so we have to reset the previous clearing card each time we define a new one:

@media screen and (min-width: 400px) {
  li {
    width: 50%;
  }
       
  li:nth-of-type(2n+1) {
    clear: left;
  }
}
     
@media screen and (min-width: 768px) {
  li {
    width: 33.333%;
  }
   
  li:nth-of-type(2n+1) {
    clear: none;
  }
   
  li:nth-of-type(3n+1) {
    clear: left;
  }
}
 
@media screen and (min-width: 1024px) {
  li {
    width: 25%;  
  }    
   
  li:nth-of-type(3n+1) {
    clear: none;
  }
   
  li:nth-of-type(4n+1) {
    clear: left;
  }
}

Lastly, it’s worth mentioning the following things:

  • Instead of the clear:left property value we could equally have used the more generic clear:both property value.
  • Instead of the :nth-of-type(an+b) CSS pseudo-class we could equally have used the :nth-child(an+b) pseudo-class.

Now that we’ve discussed one method for clearing the floats, for the sake of expanding our knowledge let’s take a look at Bootstrap’s approach.

Using Bootstrap’s Method

By taking advantage of Bootstrap’s grid system, we’re able to build a responsive layout similar to the previous one. Again, depending on the viewport size, our layout will change:

Viewport No. of columns
<768px 2
≥768px 3
≥992px 3
≥1200px 4

Here’s the required HTML, stating that our list items fill up six of the twelve columns on extra small viewports, four columns on small, then three columns on large viewports:

<div class="container">
  <ul class="row">
    <li class="col-xs-6 col-sm-4 col-lg-3">
      <figure>
        <img src="path-to-the-image" alt="" class="img-responsive">
        <figcaption>Some description here</figcaption>
      </figure>
    </li>
     
    <!-- more list items here -->
  </ul>
</div>

Normally, this markup is all we need, assuming all columns have equal heights. However, in our example the columns have different heights, so we’ll need to clear the floats. To do this, we’ll use the clearfix class as well as the responsive utility classes.

First, on extra small screens (<768px), we have a two column layout, therefore we should clear the floats after every second list item. Add the following markup after every second list item:

<li class="clearfix visible-xs-block"></li>

Next, on small and medium screens (≥768px and <1200px), we have a three column layout, so we need to clear the floats after every third list item. To do this, we add some extra markup after every third list item (not necessary for the last one):

<li class="clearfix visible-sm-block visible-md-block"></li>

Finally, on large screens (≥1200px), we have a four column layout, so we should clear the floats after every fourth list item. Again, add some more markup, this time after every fourth list item:

<li class="clearfix visible-lg-block"></li>

These additional blocks are a bit messy (a lot of people dislike using markup for driving styles) but they achieve the same end result as our initial method. Each list item is hidden, except for under certain breakpoints when they assume display: block; effectively acting as invisible horizontal dividers between our rows.

Here’s the associated demo:

Conclusion

In this short article, we covered two simple techniques for creating responsive layouts with floats. Although floats might not be (and shouldn’t be) the first choice for your modern layouts, I hope that at some point you’ll find theses techniques useful. If you’re using any other technique, be sure to share it with us!

https://webdesign.tutsplus.com/tutorials/quick-tip-building-responsive-layouts-with-floats--cms-25625 George Martsoukos


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí