Combining Angular and Bootstrap can be quite a challenge. Since you're just mentioning the bootstrap grid system, I'll start off with that.
Bootstrap grid
Docs
The simplest grid is as follows
<div class="container">
<div class="row">
<div class="col-md-6">
<button class="btn btn-primary">Primary button</button>
</div>
<div class="col-md-6">
<button class="btn btn-secondary">Secondary button</button>
</div>
</div>
</div>
I'm using the .container
, so respectively to the window width, the grid will keep a fixed size:

The bootstrap breakpoints are listed here

So if the window is wider than 1200px (XL), then the container will have a fixed width of 1200px.
.container-fluid
indicates that you don't want gutters, but prefer the container to expand to full-width:

Columns
The bootstrap grid uses the 12-column grid system ideology. You can specify the width of each column (1 to 12), and alltogether they should come to 12 (or fewer).
Wrapping
<div class="col-md-6">
indicates that the cells of the grid will move below one another when the window is smaller than 768px. You may as well tell the browser that cells should wrap sooner (eg. col-xs-6
) or later (eg. col-lg-6
).
Nested grid
As you've indicated, you want to have subgrids too. @Sean already explained how to do this:
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-xs-4">Cell 1</div>
<div class="col-xs-4">Cell 2</div>
<div class="col-xs-4">Cell 3</div>
</div>
<div class="row">
<div class="col-xs-4">Cell 1</div>
<div class="col-xs-4">Cell 2</div>
<div class="col-xs-4">Cell 3</div>
</div>
</div>
</div>
</div>
Spoiler
As I already mentioned, using bootstrap with angular is another challenge. In order to use the bootstrap grid in angular, you can add the bootstrap styles through angular.json
(or off course only use _grid.scss
...):
{
"projects": {
"example": {
...,
"architect": {
"build": {
"options": {
...,
"styles": [
{ "input": "node_modules/bootstrap/scss/bootstrap.scss", "bundleName": "style.css" },
{ "input": "src/styles.scss", "bundleName": "style.css" }
],
"scripts": [
...
]
}
}
}
}
}
}
However, doing the same for the scripts
doesn't really work properly, and isn't recommended too. Scripts registered through angular.json
aren't tree-shakable and will end up entirely in the main bundle.
So for advanced bootstrap components that require javascript, you have to arrange this by creating angular components for them. But this in turn poses a challenge as well. There are already multiple angular-bootstrap libraries out there:
- ng-bootstrap: only rewrites the typescript code, and the css is referenced globally, which increases the bundlesize with 180 kB
- ngx-bootstrap, also using global css
Writing your own ng-bootstrap library
I've been in the process of writing a library myself. The idea was to extract the styles into the specific components, in order to prevent styles from being bundled in the main bundle while you actually don't need them. Usually you would do the following:
:host ::ng-deep {
// Configuration
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
// Layout & components
@import "~bootstrap/scss/alert";
// Custom SCSS
.alert .btn {
bottom: 0;
display: inline-flex;
align-items: center;
}
}
However I found out that from the moment a selector contains ::ng-deep
, angular will create a javascript chunk in the main bundle containing this style, even for :host ::ng-deep
. I've created a github issue for this, hoping that they'll fix this...
Conclusion
If you don't care about your bundle size, you may use ng-bootstrap, ngx-bootstrap, or if there's no javascript magic to what you're writing, simply reference _bootstrap.scss
from angular.json
.
If bundle size matters to you, you'll probably have to wait until the angular team resolves this issue, and use or build a library like this one.