Bootstrap Cards Using Breakpoints to set Number per Row

Bootstrap cards, may be used to easily create content blocks with the same height and styling.

Whilst I like the ease of presenting content blocks in a row I dislike the width adjustments.

As the page width narrows so the width of each card does too, until finally the layout shifts to having one card per row.

There is usually a point where the width of each card has become too narrow.

If there are 4 cards in the row then these get ever narrower until the mobile breakpoint is reached and we have one per row. As illustrated in the card set above.

For reference here’s the html to implement these cards:

<div class="card-set">
  <div class="card-deck card-group">
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
  </div>
</div>             

Realistically an intermediate step is required where the number of cards in the row is reduced to 2.

I wished to set the number per row according to the screen width.

At the smaller screen width, wider than mobile, it would be nice to have, say, 2 cards per row. Thus each card is not as scrunched.

I considered/found two approaches to the problem.

  • CSS aiming for a generic approach.
  • Addition of extra divs with definitions for the sizing breakpoints.

My inclination was to implement using CSS. All the code would then be in the website supporting files. The implementation of the cards would be simple and understandable.

In my trials I found this to be taking more time to achieve a reliable implementation than I wished.

Looking at the use of additional layout components I had a solution in a shorter time. I had found references to adding an extra div between the 2nd or 3rd column cards.

After the second item add a div configured to hide itself by default and to be visible for defined breakpoints.

<div class="w-100 d-none d-sm-block d-md-none">
  <!-- wrap every 2 on sm-->
</div>

The div is configured above :

  • w-100 – width of 100%
  • d-none – default display of none
  • d-sm-block – display style of block for the sm breakpoint
  • d-md-none – display of none for the larger breakpoints

Implementing this approach I found that to ensure the hiding and showing was working for each size as required the list needed to be more explicit.

<div class="w-100 d-none d-sm-block d-md-block d-lg-block d-xl-none"></div>

With this chosen method, using the additional elements, there would a small additional complication ensuring that the breakpoint of the additional element is at the right place within the sequence if cards were moved in their order or added.

This works well with a row of 4 cards. But for 3 cards there is an additional step to add. Illustrated below is a sequence of 3 cards. reduce and enlarge the width of your browser.

As can be seen when the break point div is active creating a row of two cards the last element is full width, double the width of the first two cards.

The answer to this is to add a padding card at the end to ensure the stray ones don’t show full width.

For this I have taken the hide/show from before and added it to a card class wrapper.

<div class="card d-none d-sm-block d-md-none"></div>

Shown below is the set of 3 cards with the extra one at the end, effectively making the total up to 4 under certain widths.

<div class="card-set">
  <div class="card-deck card-group">
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
    <div class="w-100 d-none d-sm-block d-md-block d-lg-block d-xl-none"><!-- wrap every 2 on sm--></div>
    <div class="card">
      <div class="card-header"></div>
      <div class="card-body"></div>
      <div class="card-footer"></div>
    </div>
    <div class="card d-none d-xs-none d-sm-block d-md-block d-lg-block d-xl-none"></div>
  </div>
</div>             

This card is to be shown when the additional div is shown. As can be seen the same classes have been added as per the additional div. As its only a dummy card I’ve not added the rest of the card structure.

Shown above is the completed 3 card example with a breakpoint setting 2 cards and adding a padding after the 3 card ensuring that all cards are kept to the same width.

Adding additional elements to a set of Bootstrap cards creating breakpoints in the row at different browser widths.