Bootstrap 4: How to have cards in a row with different height? - html

I'm trying to set up two cards adjacent to one another in a single row, but I'm having an issue where the shorter length card always resizes itself automatically to match the longer one. When resizing the page, the cards are no longer adjacent and collapse onto separate rows and at that point they are independent sizes- I'd like them to be independent sizes in any case. They appear as independent sizes when I manually set the height of both of them, but the content in the cards will be dynamic so I want to avoid that. How would I go about doing this?
<div class="row justify-content-center">
<div class="card mb-4 ml-2 mr-2 text-left">
<div class="card-body">
<p>blahblahblah</p>
</div>
</div>
<div class="card mb-4 ml-2 mr-2 text-left">
<div class="card-body">
<p>blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah</p>
</div>
</div>
</div>
CSS:
.card {
width: 36rem;
}
How they look (without forced height)
How I want them to look (this is by manually styling their height, which I want to avoid)
How they look when shrinking the page (this is fine, just for reference)
https://jsfiddle.net/fu7q6jca/

The .row is designed to contain col-, not card. Put the cards inside col-*...
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card mb-4 ml-2 mr-2 text-left">
<div class="card-body">
<p>blahblahblah</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card mb-4 ml-2 mr-2 text-left">
<div class="card-body">
<p>blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah</p>
</div>
</div>
</div>
</div>
https://www.codeply.com/go/xDnbMaM6Dm

Related

How can I make a Bootstrap grid column fill the whole remaining row?

I receive some elements, and I want to insert some elements in a page. These elements can be "small" or "big". I cannot know in advance how many elements I will receive, or their order.
If they are "small", I want them to be large col-4.
If they are "big", I want them to be large as much as possible, from the previous element to the end of the row.
So, a "big" element can be large col-4, col-8 or col-12 depending on its position.
In a picture:
The most-similar question I've found on SO is the following: Bootstrap fill remaining columns
I have tried to use the approach suggested in the question, but it does not cover the case when, in the same row, you have a "small" element after a "big" element. Using the same words from the linked question:
it does not cover the case when, in the same row, you have a blue element after a rogue element
.col-4{
background:red;
}
.big{
background:yellow;
}
.row{
background:white;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<h1>
Expected result
</h1>
The goal is to obtain this same behaviour using the same style for every "big" element
<div class="container-fluid pt-2">
<div class="row">
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-12 big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-8 big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
</div>
</div>
<h1>
Not working attemp 1 (don't use any col)
</h1>
Issue: The "big" elements start on a new row instead of filling the previous row.
<div class="container-fluid pt-2">
<div class="row">
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
<div class="big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
</div>
</div>
<h1>
Not working attemp 2 (use only "col")
</h1>
Issue: Instead of occupying a whole row, the "big" elements shrink to make space for the next elements
<div class="container-fluid pt-2">
<div class="row">
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
<div class="col big mb-1">
big
</div>
<div class="col-4 mb-1">
small
</div>
</div>
</div>
https://jsfiddle.net/bhLq86o4/
So, how can I assign to the "big" elements the same class, so that the final results looks like the one described in the examples?
Don't use float
#perplexyves' answer won't work in practice. It only looks correct because OP's example only has one word per div.
It breaks if we add some more content, e.g., to the second div:
It will also break in plenty of other ways (e.g., padding/margins as OP noticed) because the float layout is not a real grid, just a superficial hack.
Use flex instead
For each "big" element:
Use Bootstrap's .flex-grow-1 class to fill the remaining row
(Or if you prefer using your own .big class, add .big { flex-grow: 1 !important; } to your CSS)
Add an empty div to force a row break
<div class="col-4 flex-grow-1">big</div> <div></div>
<!-- ^fill to end ^break into new row -->
This flex layout will produce a real grid that works regardless of content/styling:
Complete flex example
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<div class="row">
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-warning">This is the second `div` using the `flex` layout. Note how the grid is completely fine now, even with longer/uneven content.</div>
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-danger flex-grow-1">big</div> <div></div>
<!-- ^fill to end ^break row -->
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-danger flex-grow-1">big</div> <div></div>
<!-- ^fill to end ^break row -->
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-danger flex-grow-1">big</div> <div></div>
<!-- ^fill to end ^break row -->
<div class="col-4 bg-warning">small</div>
</div>
Complete flex example with auto-inserted row breaks
If you are unable/unwilling to append the empty divs manually, use insertAdjacentHTML to insert them automatically:
document.querySelectorAll('.flex-grow-1').forEach(big =>
big.insertAdjacentHTML('afterend', '<div></div>'))
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<div class="row">
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-warning">This is the second `div` using the `flex` layout and using JS to automatically insert the empty `div` row breaks.</div>
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-danger flex-grow-1">big</div>
<!-- ^fill to end ^row break will be auto-inserted here via JS -->
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-danger flex-grow-1">big</div>
<!-- ^fill to end ^row break will be auto-inserted here via JS -->
<div class="col-4 bg-warning">small</div>
<div class="col-4 bg-danger flex-grow-1">big</div>
<!-- ^fill to end ^row break will be auto-inserted here via JS -->
<div class="col-4 bg-warning">small</div>
</div>
After trying multiple possible configurations (flex, grid, float, etc.), I figured out how you can do it as requested ("big" elements have the same class):
CODE:
.small {
width: 33.3%;
float: left;
background: red;
}
.big {
background: yellow;
}
<h1>
Expected result
</h1>
The goal is to obtain this same behaviour using the same style for every "big" element
<div>
<div class="small">
small
</div>
<div class="small">
small
</div>
<div class="small">
small
</div>
<div class="big">
big
</div>
<div class="small">
small
</div>
<div class="small">
small
</div>
<div class="big">
big
</div>
<div class="small">
small
</div>
<div class="big">
big
</div>
<div class="small">
small
</div>
</div>
Some final words: since this is a non-obvious task, I recommend you to do it with native CSS, instead of struggling many days with BS classes.
Regards

customization card bootstrap 4 inside div

I use bootstrap4 and I want to have a big card inside it, i want to put in each row 5 others cards like this screen.
This is my code
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="card w-100 mb-2">
<div class="card-body">
<h5 class="card-title">Available products</h5>
<div class="row" style="display: flex; flex-direction: row;">
<div class="card mr-2 w-25 mb-2">
<div class="card-header">34 products</div>
<div class="mycard-footer">List of products</div>
</div>
<div class="card mr-2 w-25 mb-2">
<div class="card-header">34 products</div>
<div class="mycard-footer">List of products</div>
</div>
<div class="card mr-2 w-25 mb-2">
<div class="card-header">34 products</div>
<div class="mycard-footer">List of products</div>
</div>
</div>
Button
</div>
</div>
but i can't do it, any idea ?
The width utilities of the cards that are inside are relative to the parent. Here is the bootstrap Doc for sizing utilities https://getbootstrap.com/docs/4.0/utilities/sizing/
There is no possible way to fit 5 cards in 1 row. Unless you add your personal styling in CSS and not use the sizing utilities.

Flex rows' height add up to parent bootstrap 4

I'm trying to make a web that has exactly the screen's height (no scrolling), using Bootstrap 4 and flex containers. So far, the structure was holding up, until I decided to try inserting tall images.
The image scales to fit the width and it exceeds the height of the screen (I dont want this).
I want everything to fit in the screen without scrolling: this means, the image has to fill all the available height, without starving other rows of height (e.g. the footer). I've tried specifying height:100% on all parent containers and on the image as well (using bootstrap's h-100 class), but I've encountered two problems:
the image changes the aspect ratio
the added height of rows inside a column exceeds the total parent height, so the total height ends up being larger than the screen, and some elements go off the screen.
I haven't come up with a way of telling child elements of a column (rows in this case), to have a total height of 100% without manually specifying each row's height. I think that would solve the issue.
The whole structure is basically as follows (I've removed unnecessary elements):
<body id="page-top" class="bg-light">
<div id="page-content-wrapper" class="min-vh-100 p-0 d-flex flex-column overflow-hidden h-100">
<div class="container-fluid d-flex flex-row overflow-auto flex-fill justify-content-center pt-3 pb-3 h-100">
<div class="container flex-column d-flex col-7 mr-3 ml-3 h-100">
<!-- play area -->
<div class="row flex-fill h-100">
<div class="section-div flex-grow-1 flex-column d-flex h-100" id="play-area">
<div class="row flex-grow-1">
<div class="jumbotron jumbotron-fluid d-flex w-100">
<div class="container-fluid d-flex flex-column">
<h1 class="display-4 pb-2">title</h1>
<img class="img-fluid" src="https://upload.wikimedia.org/wikipedia/en/9/93/Burj_Khalifa.jpg" style="object-fit:contain">
<hr class="mb-3" />
<p>
some more text
</p>
</div>
</div>
</div>
<div class="row" style="height:100px">
<div class="row mt-auto justify-content-md-center">
<div class="col-md-auto text-center">
<p>some text at bottom</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
And a JSfiddle: https://jsfiddle.net/prx4k76t/

Bootstrap 4 mobile flexbox too wide

So my problem is that my code:
<div class="row">
<div class="w-100 col-auto col-lg-5 w-auto p-3 p-lg-5 m-4 rounded-sm bg-dark text-white shadow-lg">
<h3>This is a very very very long Text</h3>
</div>
</div>
results in this:
Too long Text in Mobile
The column is too wide for my Mobile (or in this case Firefox), i think it is because of the Margin and Padding.
Is there any way to avoid this?
Add flex-shrink-1 and flex-grow-1. It should work.
Best way is, don't try to apply your custom or any other classes to flex layout or the bootstrap's dedicated classes.
don't use margin in col bcz they have a predifined width. width auto take the width till it's content.
<div class="row">
<div class="col-lg-5 p-lg-5">
<div class="w-auto p-3 m-4 rounded-sm bg-dark text-white shadow-lg">
<h3>This is a very very very long Text</h3>
</div>
</div>
</div>

How to add padding in between cards in bootstrap

I have a row consisting of 8 cards.
I want to have all these in single line.
There is a margin of column size 2 on left side and I have set each card of size 1 (so 8 + 2 = 10)
But then, my row is all messed up.
Currently my code for border is
<div class="row">
<div class="col-sm-2">
<div class="card-header"> Discover new genres {{genre}}</div>
</div>
<div class="col-lg-1 text-center">
<div class="card border-secondary mb-3" style="width: 10rem;">
<img class="card-img-top img-responsive full-width circle-img rounded-circle" src="{{rec['artpath']}}" alt="{{rec['name']}}">
</img>
<div class="card-block">
<div class="card-body"><p class="card-title text-center "><small>{{rec["name"]}}</small></p></div>
</div>
</div>
</div>
</div>
I want the card to have this width (so not card to be small)..It can overflow on the right side of the screen..
How do i do this?
The problem has to do with your inline style of width:10rem. It's going to supersede the width of col-lg-1 when it is greater than that column width. Removing this inline style results in expected behavior.
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<div class="container-fluid">
<div class="row">
<div class="col-4">
<div class="card-header"> Discover new genres {{genre}}</div>
</div>
<div class="col-4 text-center">
<div class="card border-secondary mb-3" style="">
<img class="card-img-top img-responsive full-width circle-img rounded-circle" src="{{rec['artpath']}}" alt="{{rec['name']}}">
<div class="card-block">
<div class="card-body">
<p class="card-title text-center">
<small>{{rec["name"]}}</small>
</p>
</div>
</div>
</div>
</div>
<div class="col-4 text-center">
<div class="card border-secondary mb-3" style="">
<img class="card-img-top img-responsive full-width circle-img rounded-circle" src="{{rec['artpath']}}" alt="{{rec['name']}}">
<div class="card-block">
<div class="card-body">
<p class="card-title text-center">
<small>{{rec["name"]}}</small>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
For the purposes of this example I've changed your column breakpoints to something that works better when you choose 'Run Code Snippet'. I suspect you were applying an inline width because col-lg-1 is too small; that being the case I recommend you consider a larger column breakpoint in lieu of inline styles overriding grid behavior.