Cards actually fall under the "component" category but they are so quirky that I thought a separate lesson might be in order. Cards were designed by marketing specialists. You have an image, text descriptions, and call to action in a self-contained display element. They really are the second bread and butter of Bootstrap (after the grid) simply because they are so darned useful. The "card" isn't really a new thing in web design but Bootstrap just makes it easy to create one without custom CSS.
For these examples I will be using random images from Lorum Picsum and forcing most of them into a column to constrain their size. Like most Bootstrap elements, Cards will take up 100% of their parent container.
Some quick example text to build on the card title and make up the bulk of the card's content.
<div class="card">
<img src="https://picsum.photos/300/200?random=1" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
Just want to place a card right in the middle of your page and make it, say 50% of the page? You can do this very easily with Bootstrap's sizing utilities. The class naming convention is very simple. H
for height, or W
for width. Then we choose a number in quarters....eg.: h-100
or w-75
. See how those work? You can apply them to elements and they will apply the specified sizing to the element based on the parent element. These aren't 100% fool-proof and it will take some trial and error to get them to do what you want sometimes.
Another thing that is helpful is using Bootstrap's margin utilities to center an item. No need for a centered DIV
. This applies to, in this case, a card sitting all alone with no container, row,
or columns
. Just add mx-auto
to the class of the element and will center. Remember. M
is "margin. X
is the X axis (left to right, like crossing the street). Auto
gives you margins equal from both left and right of the parent container.
Some quick example text to build on the card title and make up the bulk of the card's content.
Go somewhere<div class="card w-50 mx-auto">
<img src="https://picsum.photos/600/300?random=4" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
Setting cards in a grid can be a challenge. There are actually several ways to align cards into a grid but not all of them are self-evident. the first way is to use the standard grid layout with Containers, Rows,
and columns
. This works perfectly when your images are all the same size...when you stray from that, the cards can all be different sizes - as seen in the example below.
Some quick example text to build on the card title and make up the bulk of the card's content.
Some quick example text to build on the card title and make up the bulk of the card's content.
Some quick example text to build on the card title and make up the bulk of the card's content.
Not at all appealing....However, there is a very simple way around this. Set the class h-100
on the card DIV
.
This sizing utility will set all of the cards to the height of the parent container. In this case the parent is a row
so as the cards stretch the row height the cards will fit to match that height.
Some quick example text to build on the card title and make up the bulk of the card's content.
Some quick example text to build on the card title and make up the bulk of the card's content.
Some quick example text to build on the card title and make up the bulk of the card's content.
Now, if you have design OCD like I do, those pictures look wrong being different sizes. So, there is a "hack" we can apply that works perfectly to correct this.
Some quick example text to build on the card title and make up the bulk of the card's content.
Some quick example text to build on the card title and make up the bulk of the card's content.
Some quick example text to build on the card title and make up the bulk of the card's content.
Much better! I think this is worth a snippet now....Info on how this "hack" works below.
<style>
.card-img-top-fix {
width: 100%;
height: 15vw;
object-fit: cover;
}
</style>
<div class="container-fluid">
<div class="row">
<div class="col-xl-4">
<div class="card h-100">
<img src="https://picsum.photos/300/200?random=1" class="card-img-top card-img-top-fix" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
<div class="col-xl-4">
<div class="card h-100">
<img src="https://picsum.photos/300/200?random=2" class="card-img-top card-img-top-fix" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
<div class="col-xl-4">
<div class="card h-100">
<img src="https://picsum.photos/300/200?random=3" class="card-img-top card-img-top-fix" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
</div>
</div>
That CSS style is what does the trick with the image sizing. There are a couple of thoughts you might consider when using it.
card-img-top-fix
is what I use when I don't want to apply it to every card. You can easily just keep the name card-img-top
and it will apply to every card.A card group is a series of cards that are attached to each other - separated only by a border.
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
Last updated 3 mins ago
This card has supporting text below as a natural lead-in to additional content.
Last updated 3 mins ago
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
Last updated 3 mins ago
<div class="card-group">
<div class="card">
<img src="https://picsum.photos/300/175?random=1" class="card-img-top" alt="...">
<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 class="card">
<img src="https://picsum.photos/300/175?random=2" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img src="https://picsum.photos/300/175?random=3" class="card-img-top" alt="...">
<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 card has even longer content than the first to show that equal height action.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>
A card "deck" is a group of cards that are NOT connected. This layout has a lot of great uses.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
Last updated 3 mins ago
This card has supporting text below as a natural lead-in to additional content.
Last updated 3 mins ago
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
Last updated 3 mins ago
This one is a lot of fun. You can loop over a series of cards and have them displayed in a "masonry" grid. Masonry in web design is cascading grid that will attempt to fit everything into the defined space regardless of height or width. It's pretty neat, really. Check this out.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
This card has supporting text below as a natural lead-in to additional content.
Last updated 3 mins ago
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.
This card has a regular title and short paragraphy of text below it.
Last updated 3 mins ago
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
This is another card with title and supporting text below. This card has some additional content to make it slightly taller overall.
Last updated 3 mins ago
<div class="card-columns">
<div class="card">
<img src="https://picsum.photos/300/175?random=1" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title that wraps to a new line</h5>
<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>
</div>
</div>
<div class="card p-3">
<blockquote class="blockquote mb-0 card-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer class="blockquote-footer">
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card">
<img src="https://picsum.photos/300/175?random=2" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card bg-primary text-white text-center p-3">
<blockquote class="blockquote mb-0">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.</p>
<footer class="blockquote-footer text-white">
<small>
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has a regular title and short paragraphy of text below it.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img src="https://picsum.photos/300/175?random=3" class="card-img-top" alt="...">
</div>
<div class="card p-3 text-right">
<blockquote class="blockquote mb-0">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer class="blockquote-footer">
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is another card with title and supporting text below. This card has some additional content to make it slightly taller overall.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>
This one is the most useful of the group if we really look at it hard. If you want to display database content as cards instead of row by row in a table, you can do it with this "perfect grid" layout.
Now, the term, "perfect" may seems like a bold statement. And it is if you fail to apply the hacks we used on the card images and to set equal heights. This one uses the row-cols-{number}
and/or row-cols-{breakpoint}-{number}
classes which set the number of columns within the row dynamically. So you can theoretically feed 100 records from a database into this layout and it will give you a perfect grid containing 100 cards.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
<div class="row row-cols-2 row-cols-md-3">
<div class="col mb-4">
<div class="card">
<img src="https://picsum.photos/300/175?random=1" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<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>
</div>
</div>
</div>
<div class="col mb-4">
<div class="card">
<img src="https://picsum.photos/300/175?random=2" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<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>
</div>
</div>
</div>
<div class="col mb-4">
<div class="card">
<img src="https://picsum.photos/300/175?random=3" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content.</p>
</div>
</div>
</div>
<div class="col mb-4">
<div class="card">
<img src="https://picsum.photos/300/175?random=4" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<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>
</div>
</div>
</div>
</div>
In the visual demo above, I used ColdFusion to loop over the cards and give me 8 of them but the snippet only gives you 4. I think you get the idea. So, in closing, cards are super useful, very attractive, and not overly complex to use. Once you get the hang of it, you will know which layout will suit your purpose best and have it working in minutes.