Customize a Bootstrap 4 card-deck layout to adjust the number of columns based on the viewport

I am currently working on implementing the card-deck feature in Bootstrap 4 to ensure that all my cards have the same height.

Although the examples provided by Bootstrap showcase 4 stylish cards, they are always displayed as 4 cards per row, regardless of the viewport size. You can check out the codeply here.

This seems counterintuitive to me because I would expect there to be a minimum size for each card so that the content remains visually appealing even when the card shrinks.

I attempted to add some viewport classes to break at different screen sizes, but doing so caused the card-deck feature to no longer apply, resulting in unequal card heights.

Is there a way to accomplish this task? Could it be a missing feature that will be addressed in the official release of Bootstrap 4?

You can also view the fiddle here: https://jsfiddle.net/crrm5q9m/

<div class="card-deck-wrapper">
  <div class="card-deck">
    <div class="card card-inverse card-success text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>It's really good news that the new Bootstrap 4 now has support for CSS 3 flexbox.</p>
          <footer>Makes flexible layouts <cite title="Source Title">Faster</cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card card-inverse card-danger text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>The Bootstrap 3.x element that was called "Panel" before, is now called a "Card".</p>
          <footer>All of this makes more <cite title="Source Title">Sense</cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card card-inverse card-warning text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>There are also some interesting new text classes for uppercase and capitalize.</p>
          <footer>These handy utilities make it <cite title="Source Title">Easy</cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card card-inverse card-info text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>If you want to use cool icons in Bootstrap 4, you'll have to find your own such as Font Awesome or Ionicons.</p>
          <footer>The Glyphicons are not <cite title="Source Title">Included</cite></footer>
        </blockquote>
      </div>
    </div>
        <div class="card card-inverse card-success text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>It's really good news that the new Bootstrap 4 now has support for CSS 3 flexbox.</p>
          <footer>Makes flexible layouts <cite title="Source Title">Faster</cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card card-inverse card-danger text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>The Bootstrap 3.x element that was called "Panel" before, is now called a "Card".</p>
          <footer>All of this makes more <cite title="Source Title">Sense</cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card card-inverse card-warning text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>There are also some interesting new text classes for uppercase and capitalize.</p>
          <footer>These handy utilities make it <cite title="Source Title">Easy</cite></footer>
        </blockquote>
      </div>
    </div>
    <div class="card card-inverse card-info text-center col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-1">
      <div class="card-block">
        <blockquote class="card-blockquote">
          <p>If you want to use cool icons in Bootstrap 4, you'll have to find your own such as Font Awesome or Ionicons.</p>
          <footer>The Glyphicons are not <cite title="Source Title">Included</cite></footer>
        </blockquote>
      </div>
    </div>
  </div>
</div>

Answer №1

Last Modified in 2018

For a responsive card-deck layout, utilize visibility utilities to ensure a wrap every X columns on various viewport widths (breakpoints)...

Bootstrap 4 responsive card-deck (version 4.1)


Initial solution for Bootstrap 4 alpha 2:

To achieve different column widths, employ the grid class col-*-* instead of card-deck and then apply equal height to the columns using flexbox.

.row > div[class*='col-'] {
  display: flex;
  flex:1 0 auto;
}

(alpha 2)

The issue arises when flexbox is not enabled as the card-deck defaults to table-cell, making width control challenging. With Bootstrap 4 Alpha 6, flexbox is now standard, eliminating the need for additional CSS related to flexbox. Additionally, the h-100 class can be used to ensure full-height cards:


Related query: Bootstrap 4 - Responsive cards in card-columns

Answer №2

Check out this solution using Sass to adjust the number of cards per line based on different breakpoints: https://codepen.io/migli/pen/OQVRMw

This setup works seamlessly with Bootstrap 4 beta 3

// Defining Bootstrap 4 breakpoints and gutter
$grid-breakpoints: (
    xs: 0,
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px
) !default;

$grid-gutter-width: 30px !default;

// Number of cards per line for each breakpoint
$cards-per-line: (
    xs: 1,
    sm: 2,
    md: 3,
    lg: 4,
    xl: 5
);

@each $name, $breakpoint in $grid-breakpoints {
    @media (min-width: $breakpoint) {
        .card-deck .card {
            flex: 0 0 calc(#{100/map-get($cards-per-line, $name)}% - #{$grid-gutter-width});
        }
    }
}

UPDATE (2019/10)

I've developed an alternative method that utilizes horizontal lists group + flex utilities instead of card-deck:

https://codepen.io/migli/pen/gOOmYLb

This approach simplifies organizing various elements into a responsive grid

<div class="container">
    <ul class="list-group list-group-horizontal align-items-stretch flex-wrap">
        <li class="list-group-item">Cras justo odio</li>
        <li class="list-group-item">Dapibus ac facilisis in</li>
        <li class="list-group-item">Morbi leo risus</li>
        <li class="list-group-item">Cras justo odio</li>
        <li class="list-group-item">Dapibus ac facilisis in</li>
        <!-- Add as many items as needed -->
    </ul>
</div>
.list-group-item {
    width: 95%;
    margin: 1% !important;
}

@media (min-width: 576px) {
    .list-group-item {
        width: 47%;
        margin: 5px 1.5% !important;
    }
}

@media (min-width: 768px) {
    .list-group-item {
        width: 31.333%;
        margin: 5px 1% !important;
    }
}

@media (min-width: 992px) {
    .list-group-item {
        width: 23%;
        margin: 5px 1% !important;
    }
}

@media (min-width: 1200px) {
    .list-group-item {
        width: 19%;
        margin: 5px .5% !important;
    }
}

Answer №3

After some experimentation, I managed to make it work by incorporating a min-width property into the cards:

<div class="card mb-3" style="min-width: 18rem;">
  <p>Card content</p>
</div>

With this adjustment, the cards maintain a minimum width without losing their layout integrity, ensuring each row is filled evenly and all cards have consistent heights.

Answer №4

To address that issue, I utilized CSS Grid. By utilizing CSS Grid, all elements in the same row will have uniform height.

However, I haven't explored achieving a consistent height for elements in different rows yet.

Regardless, here's a method to accomplish this:

HTML:

<div class="grid-container">

  <div class="card">...</div>
  <div class="card">...</div>
</div>

CSS:

.grid-container {
  display: grid;  
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

For more details, refer to this JSFiddle link. https://jsfiddle.net/bluegrounds/owjvhstq/4/

Answer №5

<div class="w-100 d-lg-none mt-4"></div>

For my layout, I added 4 cards and positioned this code between the second and third card. Give it a shot and see if it works for you!

Answer №6

If you're utilizing Bootstrap 4.1+ and are concerned about IE 11 compatibility, this answer is for you

Card-deck doesn't adjust the number of visible cards based on viewport size.

The methods mentioned above work but lack IE support. However, with the following technique, you can achieve similar responsive card functionality.

You have the flexibility to control the number of cards displayed at different breakpoints.

In Bootstrap 4.1+, columns have equal height by default; just ensure your card/content utilizes all available space. Try running the snippet provided, and it will become clear.

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
    <div class="row">
        <div class="col-sm-6 col-lg-4 mb-3">
            <div class="card mb-3 h-100">

                <div class="card-body">
                    <h5 class="card-title">Card title</h5>
                    <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                    <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
            </div>
        </div>
        <div class="col-sm-6 col-lg-4 mb-3">
            <div class="card mb-3 h-100">
                <div class="card-body">
                    <h5 class="card-title">Card title</h5>
                    <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                    <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
            </div>
        </div>
        <div class="col-sm-6 col-lg-4 mb-3">
            <div class="card mb-3 h-100">
                <div class="card-body">
                    <h5 class="card-title">Card title</h5>
                    <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                    <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
            </div>
        </div>
    </div>
</div>

Answer №7

Establishing column widths using viewport minimums:


    /* Defining the Number of Cards per Row Based on Viewport Size */
    @media (min-width: 576px) {
        .card-deck .card {
            min-width: 50.1%; /* 1 Column */
            margin-bottom: 12px;
        }
    }

    @media (min-width: 768px) {
        .card-deck .card {
            min-width: 33.4%;  /* 2 Columns */
        }
    }

    @media (min-width: 992px) {
        .card-deck .card {
            min-width: 25.1%;  /* 3 Columns */
        }
    }

    @media (min-width: 1200px) {
        .card-deck .card {
            min-width: 20.1%;  /* 4 Columns */
        }
    }

Answer №8

By utilizing Bootstrap 4.4.1, I successfully established the number of cards per deck with ease by incorporating some scss elements.

HTML

<div class="card-deck deck-1 deck-md-2 deck-lg-3">
   <div class="card">
      <h2 class="card-header">Card 1</h3>
      <div class="card-body">
          Card body
      </div>
      <div class="card-footer">
          Card footer
      </div>
   </div>
   <div class="card">
      <h2 class="card-header">Card 2</h3>
      <div class="card-body">
          Card body
      </div>
      <div class="card-footer">
          Card footer
      </div>
   </div>
   <div class="card">
      <h2 class="card-header">Card 3</h3>
      <div class="card-body">
          Card body
      </div>
      <div class="card-footer">
          Card footer
      </div>
   </div>
</div>

SCSS

// Custom styling to set the number of cards per line for different breakpoints
@for $i from 1 through $grid-columns {
  .deck-#{$i} > .card {
    $percentage: percentage(1 / $i);
    @if $i == 1 {
      $width: $percentage;
      flex-basis: $width;
      max-width: $width;
      margin-left: 0;
      margin-right: 0;
    } @else {
      $width: unquote("calc(#{$percentage} - #{$grid-gutter-width})");
      flex-basis: $width;
      max-width: $width;
    }
  }
}
...

CSS

.deck-1 > .card {
  flex-basis: 100%;
  max-width: 100%;
  margin-left: 0;
  margin-right: 0; }

.deck-2 > .card {
  flex-basis: calc(50% - 30px);
  max-width: calc(50% - 30px); }

...

Answer №9

While @Zim's solution was excellent and deserving of an up-vote, it didn't quite meet my needs as I was working with Jekyll and required my card deck to update automatically whenever a new post was added to my site. Growing the card deck in this manner with each post is simple in Jekyll, but placing the breakpoints correctly posed a challenge. My approach involved utilizing additional liquid tags and modulo mathematics.

Although this question may be outdated, I stumbled upon it and found it helpful. Perhaps someone else using Jekyll will find this information valuable in the future.

<div class = "container">
  <div class = "card-deck">

    {% for post in site.posts %}
      <div class = "card border-0 mt-2">
        <a href = "{{ post.url }}"><img src = "{{ site.baseurl }}{{ post.image }}" class = "mx-auto" alt = "..."></a>
        <div class = "card-body">
          <h5 class = "card-title"><a href = "{{ post.url }}">{{ post.title }}</a></h5>
          <span>Published: {{ post.date | date_to_long_string }} </span>
          <p class = "text-muted">{{ post.excerpt }}</p>
        </div>
        <div class = "card-footer bg-white border-0"><a href = "{{ post.url }}" class = "btn btn-primary">Read more</a></div>
      </div>

      <!-- Use modulo to add divs to handle break points -->
      
      <!-- Modulo calculations here -->
    
    {% endfor %}
  </div>
</div>

This block of code can be directly incorporated into a website or saved in your Jekyll project's _includes folder.

Answer №10

One way to achieve a responsive layout is by setting a fixed height for card elements, including the header and body sections. This allows for easy integration with standard Boostrap column grids.

For example, you can use the following code snippet:

 <div class="card-deck text-center">
    <div class="col-sm-6 col-md-4 col-lg-3">
        <div class="card mb-4">
            <img class="card-img-top img-fluid" src="//placehold.it/500x280" alt="Card image cap">
            <div class="card-body" style="height: 20rem">
                <h4 class="card-title">1 Card title</h4>
                <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
            </div>
        </div>

Answer №11

After some trial and error, I discovered that the key is to avoid using a card-deck and instead utilize .row along with .col classes.

This approach allows for creating responsive cards tailored to different screen sizes: 3 cards for xl screens, 2 for lg and md, and 1 for sm as well as xs. Adding .my-3 applies padding to the top and bottom of each card for a visually pleasing layout.

mixin postList(items)
  .row
    - items.forEach(function(item, index){
      .col-sm-12.col-md-6.col-lg-6.col-xl-4
        .card.my-3
          img.card-img-top(src="...",  alt="Card image cap")
          .card-body
            h5.card-title Card title #{index}
            p.card-text Some quick example text to build on the card title and make up the bulk of the content.
            a.btn.btn-primary(href="#") Go somewhere
    - })

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for effectively utilizing the jQuery closest method

This webpage allows me to upload images to a database and then display them again. When uploading an image, a comment can be added to it using a textarea. When the images are displayed again, the comments are shown and editable as well. Recently, I added a ...

Creating links within a single image in HTML?

Is there a way to hyperlink different parts of a single image to various webpages using JavaScript coordinates or any other method? ...

Maintaining a Multi-page template in PhoneGap: Best practices

I'm a beginner in Hybrid app development, currently using PhoneGap and Jquery Mobile. In my app, I have around 10 separate pages such as login.html, index.html, search.html, etc. My query is whether I should include all JS and CSS files on each indivi ...

Hiding Button in code behind

I have around 100 buttons in a list. Initially, I have set their visibility to false in the ASPX page. Now, I need to change the visibility to true from the code-behind when required. Since there are too many buttons, it's not feasible to individuall ...

Tap on the Dropdown Menu to access the Responsive design feature

Currently, I am working on perfecting a responsive navigation menu. My goal is to have the drop-down menu appear when the menu icon is clicked, as opposed to the hover effect. I am utilizing a Google jQuery script, but I am unsure if the drop-down functi ...

Javascript is responsible for causing a div to become stuck in a loop of alternating between

My current challenge involves a JavaScript function that manipulates boxes by toggling classnames. The strange issue I'm facing is that the correct classes are being set at the correct times, but the div keeps alternating between the original class an ...

Excessive size of bootstrap form

I'm currently working on designing a form within a section that has a width of col-sm-8. The form consists of three columns: label, text input, and username check. I've designated the label to have a width of col-sm-2, the username check to have ...

Overlap of sub menus

Seeking assistance from a CSS expert for a challenge I am facing. I am currently working on a toggle menu for mobile view, and encountering issues with the submenu. Any list item placed below another one with children is not visible. Removing the parent l ...

What is the best way to navigate between different areas of an image using html and javascript?

I am currently in the process of learning how to develop mobile applications, and I am still in the early stages. Although this question is not directly related to mobile development, it pertains more to html/css/js. My goal is to create a simple game wh ...

Troubleshooting code: JavaScript not functioning properly with CSS

I am attempting to create a vertical header using JavaScript, CSS, and HTML. However, I am facing an issue with the header height not dynamically adjusting. I believe there might be an error in how I am calling JSS. Code : <style> table, tr, td, t ...

The class name feature on the Drawer component is malfunctioning

React and material-ui are my tools of choice, but I've hit a roadblock. I'm attempting to define some custom CSS behavior for the drawer component, using the className property as recommended. However, despite following the instructions, it' ...

Struggling to align the login button accurately within the navbar

For proper alignment, the "Login" button needs to be pushed to the right of the navbar alongside other buttons. To see the issue and the code, check out this JSFiddle example: https://jsfiddle.net/sterlingmd17/tk17zjfq/1/ <nav class="navbar navbar ...

use bootstrap to align text vertically according to the image

I am trying to figure out how to center a text vertically next to an image. While I know how to align text horizontally using text-center in bootstrap, I am unsure about how to align it vertically. Is there a way to accomplish this using bootstrap? < ...

Removing CSS from an Ajax combobox

When using an Ajax Combobox, I encountered a problem with the background color changing on hover. The combobox is bound to a datasource with specific conditions for defining the background color, but upon hovering over a list item, the color changes. I wan ...

Purge the external CSS files

Scenario In my React Router setup, most pages include their own .css files along with the default antd (UI framework) stylesheet: import '../styles.css'; This ensures that all components inherit these styles automatically. Issue at Hand Now, I ...

Error arising from CSS positioning with dynamically generated images

My challenge is displaying dynamic images from a database alongside details like color, name, and size, with a hover effect that shows a border. Whenever I hover over one image, the other images shift to the right or left. I want them to stay in place. T ...

When the div is clicked, it changes color and then reverts back to its original color when another

I have encountered an issue where I need to differentiate the div I clicked on in order to avoid confusion, as the pop-up menu on my website will be identical with different links but the same buttons. I have been struggling to find a solution for quite so ...

Troubleshooting spacing and padding problems in Bootstrap 5.2.3's Scrollspy feature

Hello, I'm currently working on developing a new portfolio template that features a list on the left side to guide users through different sections of the page. Utilizing Scrollspy in Bootstrap 5.2.3 has been helpful so far, but I've noticed that ...

Scrolling problems with numerous bootstrap modals on a Webpage

I am faced with an issue on a page where I have set the property overflow: auto. This page features a hyperlink to open the first modal, and within the first modal, there is a link to the second modal. My steps are as follows: Open Page 1 Click on the l ...

Ensure that Colorbox remains centrally positioned even while scrolling

I have noticed a difference in behavior between thickbox and colorbox when it comes to scrolling. Thickbox always stays centered on the screen even when the user scrolls vertically, while colorbox fades out and leaves just a grayed background. Is there a w ...