-1

I am trying to learn web design and I am using Angular to do so. However, I am stuck with some of the concepts in bootstrap and I don't know what is right from wrong. I am a beginner so please bear with me. My questions are the following:

  1. When and where should I use containers? Some people say that I should only use one single fluid-container at the root component/index.html file and nothing else. But when I see some examples on Github I don't see many do that. Do I use a fluid-container for components that extends the whole viewport and continer for the other components? Should I use a container for every component? Should I have nested containers? What is best practices?

  2. Can I have cols directly nested in other cols? or is it best practices to use rows if I want to nest more cols in cols?

for example:

<div class="row">
   <div class="col-6">
      <div class="col-6">  
         some content           
      </div>
      <div class="col-6">
         some content
      </div>
   </div>
   <div class="col-6">
      some content
   </div>
</div>
  1. When is it best to use rows and when is it not recommended?

  2. Can I have rows without a container/container-fluid?

Please help me understand and if possible refer to some document.

Mohammed Abdu
  • 25
  • 2
  • 9
  • 2
    I assume that you've already [read the docs](https://getbootstrap.com/docs/5.2/layout/grid/). I'll try to post an answer soon. Since you want to use it with angular, you should probably now from the start that it's not a walk in the park. If you're really starting from scratch, angular material may be better to use – Pieterjan Nov 29 '22 at 19:04
  • 3
    always put columns in rows instead of directly in other columns – Sean Nov 29 '22 at 19:08

1 Answers1

1

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:

Bootstrap grid with gutters

The bootstrap breakpoints are listed here

Bootstrap breakpoints

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:

Bootstrap grid without gutters

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.

Pieterjan
  • 2,738
  • 4
  • 28
  • 55
  • Thanks alot for your answer. That helped me alot. As for my first question, can you please elaborate on it? About using containers in other containers and so on. And where to use container (if for every component or for only the root component). That would make things clearer to me. Sorry for asking alot of questions but it does confuse me alot.. – Mohammed Abdu Nov 29 '22 at 22:24
  • I haven't really had the need to use the grid system in my root template. Usually I'm only using it on angular pages where the user needs to fill out some fields (label on the left, input on the right), so never in the AppComponent – Pieterjan Nov 29 '22 at 22:37