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
If you have the following file structure:
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;
}
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/
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.
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.
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>
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