How to use css classes with Booststrap and wagtail - css

I am using a Bootstrap theme and in one particular location I want to place up to three cards horizontally on the page. I have the html:
<div class="container">
<h1 class="text-center">{{ self.title }}</h1>
<div class="card_deck;" style="display: table;">
{% for card in self.cards %}
<div class="card;" style="display: table-cell; padding:20px;">
A card goes here
</div>
{% endfor %}
</div>
</div>
I have two questions related to this:
How do I centre the cards on the page?
What is the best way to handle the css? I clearly don't want to mess with the Bootstrap card and card_deck elements, so is the only solution to leave the style in the div tag?

for
1. Center the card on the page
<div align='center' class='row'>
<div class="row">
<div class="col-sm">
then paste the cards in here
</div>
<div class="col-sm">
then paste the cards in here
</div>
<div class="col-sm">
then paste the cards in here
</div>
</div>
</div>
You can simply add new class to it, for example, assuming the div below is the place I want to add the CSS
then paste the cards in here
then go ahead and style as such
.myNewCss{
style here
}

If you want your cards to have bootstrap classes depending on how many cards you have you could use a class on card equal to col-12/self.cards.length. This is because bootstrap uses a 12 'sections' grid. So if you have 2 columns you have col-6. 6 is from 12/2 . Which means that if you have 3 cards you will have col-4 , if you have 4 cards you will have col-3 and so on.
I made a pure javascript example below which approximately reproduces what you want to achieve
const cards = [{
text: 'card1 text'
}, {
text: 'card2 text'
}, {
text: 'card3 text'
}]
const card = document.querySelectorAll('.card');
card.forEach((c, i) => {
c.classList.add(`col-${12/cards.length}`)
c.innerHTML = cards[i].text
})
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<h1 class="text-center">{{ self.title }}</h1>
<div class="card_deck row">
<div class="card" style="padding:20px;">
</div>
<div class="card" style="padding:20px;">
</div>
<div class="card" style="padding:20px;">
</div>
</div>
</div>

Related

How to center content generated by *ngFor in a bootstrap grid?

I would like to center some content in a row using the Bootstrap grid system. I have looked at many examples about this including this, but my example differs because of the use of a separate angular component to generate the content.
app.component.html:
<div class="row" style="border:1px solid red;">
<div class="col d-flex justify-content-center">
<button mat-raised-button>text</button>
<app-child-component></app-child-component>
</div>
</div>
child-component.html:
<div *ngFor="let text of buttonText">
<button mat-raised-button>{{text}}</button>
</div>
child-component.ts:
buttonText = ['Button1', 'Button2', 'Button3'];
This gives the result:
But I would like all buttons to be horizonally aligned:
StackBlitz example:
https://stackblitz.com/edit/github-t6uyxp-z6is8f?file=src%2Fapp%2Fchild-component%2Fchild-component.component.ts
Just add display: flex to the wrapper container:
Better to add class instead of inline style. Inlining was done for demo only
<div style="display:flex">
<div *ngFor="let text of buttonText">
<button mat-raised-button>{{text}}</button>
</div>
</div>

How to align card images in bootstrap 4.4 so that all the cards have equal width and height.?

So basically while making a simple website with Django and bootstrap 4.4 I came up with this issue. I was using 'cards' to add images of books in a grid format like in a bookstore web application. But the cards are not having equal dimensions.
How to align card images in bootstrap 4.4 so that all the cards have equal width and height while keeping it responsive to the window size change.??
My problem in the image below. As you can see there the cards are not of same size when i add different images it changes its size as well.
enter image description here
html
<div class="container">
<div class="row">
{% for book in object_list %}
<div class="col s3">
<div class="card">
<img class="img-fluid" src="{{book.book_image}}" alt="">
<div class="card-body">
</div>
</div>
<p class="text-white">{{book.name}}</p>
</div>
{% endfor %}
</div>
</div>
and .css
body{
background: white url('images/webbg.jpg') no-repeat center center;
background-size: cover;
}
Example image of what I actually want to have enter image description here
I want exactly like what there is in the above picture with images loading from my database in a loop.(so not hardcoded image links embedded in html code)
It sounds like you could use .card-deck to achieve your goals
https://getbootstrap.com/docs/4.4/components/card/#card-decks
If .card-deck won't work for you you can use the new Grid Cards. They allow you to select how many cards you want per row based on screen size. The don't automatically set themselves to being equal height however that is easily remedied by adding .h-100 to the cards.
As an example, if you wanted 4 cards per row after the xl breakpoint, 3 after md and 2 on mobile you would write the following. Note there is some margin on the columns to give them some space as they wrap.
<div class="row row-cols-2 row-cols-md-3 row-cols-xl-4">
<div class="col mb-4">
<div class="card h-100">
<!-- content -->
</div>
</div>
<div class="col mb-4">
<div class="card h-100">
<!-- content -->
</div>
</div>
<div class="col mb-4">
<div class="card h-100">
<!-- content -->
</div>
</div>
<div class="col mb-4">
<div class="card h-100">
<!-- content -->
</div>
</div>
</div>

Image Not Aligning to Center in Bootstrap Row

I used Bootstrap grid to centre the position of the 4 images in Angular. The images align perfectly to the centre in the row when I placed them within the same HTML sheet. However, if I placed them in a different HTML sheet, the 4 images are not exactly positioned in the centre, as I notice they are slightly off to the left.
To summarise, this works (./home.component.html):
<div class="container">
<p class="h2-responsive itemsTitle">Items with free shipping</p>
<hr>
<div class="row">
<div class="col-sm">
<img class="itemCard" src="https://images.unsplash.com/photo-1505429155379-441cc7a574f7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0ddea5332a8ab2d09cf5eec6a57d3f9f&auto=format&fit=crop&w=334&q=80">
</div>
<div class="col-sm">
<img class="itemCard" src="https://images.unsplash.com/photo-1505429155379-441cc7a574f7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0ddea5332a8ab2d09cf5eec6a57d3f9f&auto=format&fit=crop&w=334&q=80">
</div>
<div class="col-sm">
<img class="itemCard" src="https://images.unsplash.com/photo-1505429155379-441cc7a574f7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0ddea5332a8ab2d09cf5eec6a57d3f9f&auto=format&fit=crop&w=334&q=80">
</div>
<div class="col-sm">
<img class="itemCard" src="https://images.unsplash.com/photo-1505429155379-441cc7a574f7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0ddea5332a8ab2d09cf5eec6a57d3f9f&auto=format&fit=crop&w=334&q=80">
</div>
</div>
</div>
But this doesn't (./home.component.html):
<div class="container">
<p class="h2-responsive itemsTitle">Items with free shipping</p>
<hr>
<div class="row">
<app-home-item></app-home-item>
<app-home-item></app-home-item>
<app-home-item></app-home-item>
<app-home-item></app-home-item>
</div>
</div>
(./home-item.component.html):
<div class="col-sm">
<img class="itemCard" src="https://images.unsplash.com/photo-1505429155379-441cc7a574f7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0ddea5332a8ab2d09cf5eec6a57d3f9f&auto=format&fit=crop&w=334&q=80">
</div>
Here's what happens. The circled part shows that the images are slightly off to the left, which doesn't happen when I use the first example code above.
I am not too sure where it goes wrong. All the components are imported and declared in app.module. The bootstrap link is placed in the index.html as well.
CSS (in styles.css):
.itemsTitle {
margin-top: 16px;
}
.itemCard {
width: 15rem;
}
The problem is with the width of col inside app-home-item so in that component add flex: 1; to the wrapper

Bootstrap Jumbotron alignment within a row

I have been trying for a while without success.
I have a row with two jumbotron in it, but I can't figure out how to make theme the same height.
I guess that there is paddling issue from the bootstrapp css but I do not know how to overide it ..
here is how it looks:
<div class="row">
{% if project.has_member_responses %}
<div class="col-8">
<div class="jumbotron greenback">
<h4>Welcome to the Project test "{{ project.name }}" Detail page</h4>
</div>
</div>
<div class="col-4">
<div class="jumbotron greenback">
<div class="inner-score">
<h6>Team Score</h6>
<h4>85</h4>
</div>
</div>
</div>
</div>
How can I make the two jumbotron with the same height ?
The easiest way would be to fix the height of the jumbotron
.jumbotron.greenback {
height:200px;
}

AngularJS / Bootstrap CSS: Wrong panels alignments into 2 columns inside a ng-repeat

I have an issue with Bootstrap panels with AngularJS.
I'm not able align correctly my panels. I want to display my panels into 2 columns.
I have the following HTML code:
<div class="row">
<div class="col-lg-3 col-sm-3 col-xs-3">
<span>Some stuffs</span>
</div>
<div class="col-lg-9 col-sm-9 col-xs-9">
<div class="row">
<div class="col-lg-6 col-sm-6 col-xs-6"
ng-repeat="i in items">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{i.title}}</h3>
</div>
<div class="panel-body">
{{i.content}}
</div>
</div>
</div>
</div>
</div>
</div>
Basic case:
Let's say, I have 3 items.
The 2 first items will be displayed in the first row.
- item1: row0/col0
- item2: row0/col1
The last item should be displayed in the 2nd row and first column
- item3: row1/col0
It works fine when the height of the panels are the same.
My use case:
My panel content can be different from each other.
So, when my first panel content is bigger than the others, the third item goes to the col1.
- item3: row1/col1
It leaves a big space and then if I want to add a 4th item...it becomes ugly :(
I've created a demo showing the issue: http://plnkr.co/edit/TZDck5b9G9Ap32KlPk4q?p=preview
The only solution I can think of to correctly display the 3rd div regardless of its size is to use one row for the first 2 divs and another for the next 2 (and so on and so forth). You can do this by putting the ng-repeat iteration outside the row div and assigning the row class conditionally when the iteration is on an add element.
<div ng-repeat="i in items">
<div ng-if="$even" class="row">
<div class="col-lg-6 col-sm-6 col-xs-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{i.title}}</h3>
</div>
<div class="panel-body">
{{i.content}}
</div>
</div>
</div>
<div class="col-lg-6 col-sm-6 col-xs-6" ng-if="items[$index + 1]">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{items[$index + 1].title}}</h3>
</div>
<div class="panel-body">
{{items[$index + 1].content}}
</div>
</div>
</div>
</div>
</div>
The downside is of course that you are duplicating the markup for the column (the one that shows the actual pannel), which can be avoided if you create a directive for this part. I get that Exlord's solution is simpler, however I have the feeling that this is closer to the Angular / Bootstrap way, since otherwise you are effectively overriding Bootstrap's row system by "forcing" the row's columns to break in more than one row (using clear:right).
See updated plunkr here: http://plnkr.co/edit/7KMZdzcpR7Ff2D6pExVB?p=preview
<div ng-repeat="..." ng-class="{clear_right:$odd}">
//your panel content here
</div>
.clear_right{clear:right;}
.clear_right:after{content:" ";display:block;}
#Christina: Nice solution, but you lost your scope. In my complex template html I need access to the parent scope.
I changed the directive to building a new scope that inherits from the parent, see the plunker fork http://plnkr.co/edit/CCwbnZCE7e8ej2fFBi2e?p=preview
app.directive('panelContent', function(){
return {
restrict: 'E',
scope: true,
templateUrl: 'panel-content.html',
link: function(scope, element, attributes){
scope.item = scope.$eval(attributes["item"]);
}
};
})
Update 03.06.15:
The {{$index +1}} solution will cause problems if you add or remove items. In this case anguluar gets problem with data-binding and does not update the view to the modified collection.
Now I solved the problem with a
<div ng-if="$even" style="clear: both;"></div>
in the ng-repeat block
<div ng-repeat="item in myItems">
<div ng-if="$even" style="clear: both;"></div>
<item-content /> <!-- directive that adds the content for each item ( or direct html if you want)-->
</div>

Resources