Dynamically resize elements sans JavaScript with the help of clutter-free CSS

I’m a big fan of code, including CSS, that’s as easy to use as possible. I’m not a fan of using certain large frameworks such as Bootstrap just to get responsive design onto a site, when something much smaller and simpler will often do. With a few CSS tricks, it’s possible to create CSS containers that will behave responsibly at your chosen viewport break-points, but that can be stripped down to a single class added to a container in many cases.

To that end, observe the following example, which applies table-style formatting at a large/desktop screen size wraps items into a grid-style layout at a medium size, with configurable options for numbers of columns at different numbers of child items; and finally collapses to an item width of 100%. You may also try it for yourself.

* { box-sizing: border-box }

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

@media all and ( min-width: 768px ) {

  .columnContainer { 
    display: table;
    width: 100%;
  }
  .columnContainer > div { 
    display: table-cell;
  }

}

@media all and ( max-width: 767px ) and ( min-width: 481px ) {

  .columnContainer { 
     width: 100%;
  }

  .columnContainer > div {
    float: left;
    width: 100%;
  }

  .columnContainer > div:first-child:nth-last-child(2), .columnContainer > div:first-child:nth-last-child(2) ~ div {  width: 50%;  } 

  .columnContainer > div:first-child:nth-last-child(3), .columnContainer > div:first-child:nth-last-child(3) ~ div {  width: 33.3333%;  } 

  .columnContainer > div:first-child:nth-last-child(4), .columnContainer > div:first-child:nth-last-child(4) ~ div {  width: 50%;  } 
  .columnContainer > div:first-child:nth-last-child(4) ~ div:nth-child(2n+1) { clear: both !important; } 

  .columnContainer > div:first-child:nth-last-child(5), .columnContainer > div:first-child:nth-last-child(5) ~ div {  width: 20%; } 

  .columnContainer > div:first-child:nth-last-child(6), .columnContainer > div:first-child:nth-last-child(6) ~ div {  width: 33.3333%;  } 
  .columnContainer > div:first-child:nth-last-child(6) ~ div:nth-child(3n+1) { clear: both; } 
  
  .columnContainer > div:first-child:nth-last-child(7), .columnContainer > div:first-child:nth-last-child(7) ~ div {  width: 14.2857%; } 

  .columnContainer > div:first-child:nth-last-child(8), .columnContainer > div:first-child:nth-last-child(8) ~ div {  width: 25%;  } 
  .columnContainer > div:first-child:nth-last-child(8) ~ div:nth-child(4n+1) { clear: both !important; } 

  .columnContainer > div:first-child:nth-last-child(9), .columnContainer > div:first-child:nth-last-child(9) ~ div {  width: 33%;  } 
  .columnContainer > div:first-child:nth-last-child(9) ~ div:nth-child(3n+1) { clear: both !important; } 
  
  .columnContainer > div:first-child:nth-last-child(10), .columnContainer > div:first-child:nth-last-child(10) ~ div {  width: 20%;  } 
  .columnContainer > div:first-child:nth-last-child(10) ~ div:nth-child(5n+1) { clear: both !important; } 

  .columnContainer > div:first-child:nth-last-child(11), .columnContainer > div:first-child:nth-last-child(11) ~ div {  width: 9.0909%; } 

  .columnContainer > div:first-child:nth-last-child(12), .columnContainer > div:first-child:nth-last-child(12) ~ div {  width: 25%;  } 
  .columnContainer > div:first-child:nth-last-child(12) ~ div:nth-child(4n+1) { clear: both !important; } 

}

@media all and ( max-width: 480px ) {
  .columnContainer > div { width: 100% }
}

This implementation depends on some CSS3 features working in tandem. At the medium viewport size, by combining the :first-child and :nth-last-child(n) (with following siblings) selectors in tandem, the widths and wrapping for child items can be set specifically based on the number of child items. To create a new row, the nth child is then selected for clearing. An implementation without using floats is also possible; the main technique here is the selection of different layout techniques based on the number of children.

Once this has been implemented, adding a single class, in this case “columnContainer”, on a parent element will hook all this up so it just works. It would also be possible to combine this technique, of course, with named custom classes that applied different widths to columns and the like.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s