Limit the scope of bootstrap styles

后端 未结 9 2195
情歌与酒
情歌与酒 2020-11-27 02:56

How do I limit Bootstrap to just the scope of a div? I need to nest the Bootstrap stylesheet inside an ExtJS app for especific divs and both are clashing since they need the

相关标签:
9条回答
  • 2020-11-27 03:41

    If you have the following file structure:

    • mystyles.less
    • mystyles.css
    • /bootstrap/
      • bootstrap.less
      • bootstrap.css
      • grid.less
      • ...
      • /mixins/

    And you want to limit the scope of bootstrap, you have to put in your mystyles.less (right way):

    .your-class-to-limit-bootstrap-scope{
        @import (less) "bootstrap/bootstrap.css";
    }
    

    We have to import the bootstrap.css file instead of bootstrap.less, but using the (less) @import option in order to treat the file as a Less file, no matter what the file extension. So, you will get the correct css, for example:

    .your-class-to-limit-bootstrap-scope .col-xs-1,
    .your-class-to-limit-bootstrap-scope  .col-sm-1,
    .your-class-to-limit-bootstrap-scope ...
    .your-class-to-limit-bootstrap-scope .col-lg-12 {
        position: relative;
        min-height: 1px;
        padding-left: 7px;
        padding-right: 7px;
     }
    

    But if you import bootstrap less files you will get a incorrectly scoped css (wrong way):

    .your-class-to-limit-bootstrap-scope{
        @import "bootstrap/bootstrap.less";
    }
    

    So, you will get the incorrect scoped css, for example:

    .your-class-to-limit-bootstrap-scope .col-xs-1, 
    .col-sm-1,
    .col-md-1,
    ...
    .col-lg-12 {
        position: relative;
        min-height: 1px;
        padding-left: 15px;
        padding-right: 15px;
    }
    
    0 讨论(0)
  • 2020-11-27 03:41

    Expanding on @jtlindsey answer. If you want to use bootstrap 4 you have to do some little changes.

    Instead of editing less/bootstrap.less you have to edit scss/bootstrap.scss

    then you have to execute this command in order:

    gem install bundler
    bundle install
    npm run dist
    

    And the new bootstrap.min.css is generated in the dist folder.

    Here you can have more information: https://getbootstrap.com/docs/4.0/getting-started/build-tools/

    0 讨论(0)
  • 2020-11-27 03:46

    You can fork the bootstrap repo and change bootstrap.less to wrap the bootstrap styles:

    .bootstrap-scope {
        //put bootstrap @includes in here
    }
    

    Then, in the root of the bootstrap project, run make to generate the bootstrap.css file.

    You'll lose the global styles bootstrap assigns to the body and html tags, but you might not want them anyway.

    And then, in your app, give the container you want the .bootstrap-scope class.

    0 讨论(0)
  • 2020-11-27 03:48

    There is way much easier way to achieve this legitimate requirement: replace }NEWLINE and ,NEWLINE with previous value and your class scope. It's very easy to to in e.g. Sublime:

    • Select }\r\n

    • Alt + F3 (to select all occurrences)

    • Replace with }\r\n.bootstrap-scope

    • Select ,\r\n

    • Alt + F3 (to select all occurrences)

    • Replace with ,\r\n.bootstrap-scope

    That's it! It will be pretty easy to update it going forward since replacement takes about a minute. Hope my answer helped.

    0 讨论(0)
  • 2020-11-27 03:50

    If you want a pure JavaScript solution with no outside libraries involved, you could go this route: The general idea is to load the raw css, then parse it line by line adding in your scoped selector where necessary.

    function scopeCSS(scopeSelector, rawCSS) {
      return rawCSS.split('\n').map(line => {
        var trimmedLine = line.trim()
        if (trimmedLine.startsWith('*') || trimmedLine.startsWith('/*') || trimmedLine.startsWith('@media') || trimmedLine === '' || trimmedLine.endsWith(';') || trimmedLine.endsWith('}')) {
          return line
        }
        return line.split(',').map(selector => selector.trim()).map(selector => selector === '' ? selector : `${scopeSelector} ${selector}`).join(',');
      }).join('\n')
    }
    const rawCSS = document.querySelector('#before').textContent // just as an example, you'd probably use a raw loader with webpack
    document.querySelector('#after').textContent = scopeCSS('.bootstrap-scope', rawCSS)
    #grid {
      display: grid;
      width: 100%;
      grid-template-columns: 1fr 1fr;
    }
    <div id="grid">
      <div id="col-1">
        <pre id="before">/*!
     * Bootstrap Grid v5.0.0-alpha1 (https://getbootstrap.com/)
     * Copyright 2011-2020 The Bootstrap Authors
     * Copyright 2011-2020 Twitter, Inc.
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
     */
    .container,
    .container-fluid,
    .container-sm,
    .container-md,
    .container-lg,
    .container-xl,
    .container-xxl {
      width: 100%;
      padding-right: 1rem;
      padding-left: 1rem;
      margin-right: auto;
      margin-left: auto;
    }
    
    @media (min-width: 576px) {
      .container, .container-sm {
        max-width: 540px;
      }
    }
    
    @media (min-width: 768px) {
      .container, .container-sm, .container-md {
        max-width: 720px;
      }
    }
    
    @media (min-width: 992px) {
      .container, .container-sm, .container-md, .container-lg {
        max-width: 960px;
      }
    }
    
    @media (min-width: 1200px) {
      .container, .container-sm, .container-md, .container-lg, .container-xl {
        max-width: 1140px;
      }
    }
    
    @media (min-width: 1400px) {
      .container, .container-sm, .container-md, .container-lg, .container-xl, .container-xxl {
        max-width: 1320px;
      }
    }
    
    .row {
      --bs-gutter-x: 1.5rem;
      --bs-gutter-y: 0;
      display: flex;
      flex: 1 0 100%;
      flex-wrap: wrap;
      margin-top: calc(var(--bs-gutter-y) * -1);
      margin-right: calc(var(--bs-gutter-x) / -2);
      margin-left: calc(var(--bs-gutter-x) / -2);
    }
    
    .row > * {
      box-sizing: border-box;
      flex-shrink: 0;
      width: 100%;
      max-width: 100%;
      padding-right: calc(var(--bs-gutter-x) / 2);
      padding-left: calc(var(--bs-gutter-x) / 2);
      margin-top: var(--bs-gutter-y);
    }
    
    .col {
      flex: 1 0 0%;
    }
    /*# sourceMappingURL=bootstrap-grid.css.map */</pre>
      </div>
      <div id="col-2">
        <pre id="after"></pre>
      </div>
    </div>

    0 讨论(0)
  • 2020-11-27 03:56

    no need to fork/edit original bootstrap. Just wrap its imports in your file like this (sass in my case): I created the file "bootstrap-scope-limit.scss" (that I import where I need bootstrap):

    .bootstrap-inside {
      @import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";
      @import "~bootstrap-sass/assets/stylesheets/bootstrap/_theme.scss";
    }
    

    important notices!

    please keep in mind that bootstrap has some body styles that wouldn't be applied when using such approach. But it gives you an ability to control bootstrap with JS by adding the "bootstrap-inside" class to the element to enable or disable bootstrap for the whole page if some dynamic content has to use bootstrap or not.

    another concern you should aware about: some plugins that override bootstrap styles may have problems since bootstrap styles with new class wrapper become stronger (more specific) and can't be overridden by unwrapped plugins.


    for webpack case I would recommend to use this loader: https://www.npmjs.com/package/wrap-css-loader to wrap the whole bundle, that you may use as a part of your app (div?) later

    0 讨论(0)
提交回复
热议问题