如何将 Bootstrap 限制在 div 的范围内?我需要在 ExtJS 应用程序中为特定的 div 嵌套 Bootstrap 样式表,并且两者都发生冲突,因为它们需要自己的 body、ul、li、a 等。
我试图避免手动编辑 bootstrap.css(或将其保持在最低限度),以便可以轻松更新它。
如何将 Bootstrap 限制在 div 的范围内?我需要在 ExtJS 应用程序中为特定的 div 嵌套 Bootstrap 样式表,并且两者都发生冲突,因为它们需要自己的 body、ul、li、a 等。
我试图避免手动编辑 bootstrap.css(或将其保持在最低限度),以便可以轻松更新它。
您可以分叉引导存储库并更改bootstrap.less
以包装引导样式:
.bootstrap-scope {
//put bootstrap @includes in here
}
然后,在 bootstrap 项目的根目录下,运行make
生成bootstrap.css
文件。
您将丢失引导程序分配给 body 和 html 标记的全局样式,但您可能不想要它们。
然后,在您的应用程序中,提供您想要的.bootstrap-scope
类的容器。
由于修改 less/bootstrap.less 的结果对我来说不够好(请参阅帖子底部的原因),我最终过滤了 bootstrap.css :
var css = require('css'), fs = require('fs');
var prefix = '.bootstrap-scope';
var inFile = 'bootstrap.css';
var cssAst = css.parse(fs.readFileSync(inFile, 'utf8'));
prefixNode(cssAst);
console.log(css.stringify(cssAst));
function prefixSelector(sel){
if (sel.match(/^@/)) return sel;
var m = sel.match(/(^| )(body|html)($|\W.*)/i);
if (m)
return m[1] + prefix + m[3];
else
return prefix + ' ' + sel;
}
function prefixNode(node) {
if (node.selectors) {
node.selectors = node.selectors.map(prefixSelector);
} else if (node.stylesheet) {
node.stylesheet.rules.forEach(prefixNode);
} else if (node.rules) {
node.rules.forEach(prefixNode);
}
}
既然生成了 bootstrap.css ,也可以盲目地去做(解决方案类似于 Alexey 的,但也处理了一些极端情况):
perl -lpe 'BEGIN { $prefix = ".bootstrap-scope" } if (($indent, $s, $sep) = /^(\s*)([^@\s].*?)(\s*[,{])$/) { $s =~ /^(from|to)*$/ or $s =~ s/(^| )(body|html)($|\W.*)/$1$prefix$3/i or $s = "$prefix $s"; $_ = "$indent$s$sep" }' bootstrap.css
至于修改 less/bootstrap.css 并调用 grunt 来生成 dist/css/bootstrap.css (Andrew Homeyer 的解决方案),在某些情况下似乎效果不佳(至少在 bootstrap 3 中):
像 .make-grid-columns (来自 less/mixins.xml)这样的各种 mixin 最终会被错误地添加前缀。例子:
.bootstrap-scope .col-sm-1,
.col-sm-2,
.col-sm-3,
LESS中“&”的使用是有限的:
.caret {
.btn-default & {
变成
.btn-default .bootstrap-scope .caret {
而不是我们想要的:
.bootstrap-scope .btn-default .caret {
如果您有以下文件结构:
而且你想限制引导的范围,你必须把你的 mystyles.less (正确的方式):
.your-class-to-limit-bootstrap-scope{
@import (less) "bootstrap/bootstrap.css";
}
我们必须导入 bootstrap.css 文件而不是 bootstrap.less,但使用 (less) @import 选项将文件视为 Less 文件,无论文件扩展名是什么。因此,您将获得正确的 css,例如:
.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;
}
但是,如果您导入较少的引导文件,您将得到一个范围不正确的 css (错误的方式):
.your-class-to-limit-bootstrap-scope{
@import "bootstrap/bootstrap.less";
}
因此,您将获得不正确的作用域 css,例如:
.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;
}
有一种更简单的方法可以实现这一合法要求:将 }NEWLINE 和 ,NEWLINE 替换为以前的值和您的类范围。很容易进入例如 Sublime:
选择 }\r\n
Alt + F3(选择所有匹配项)
替换为 }\r\n.bootstrap-scope
选择 ,\r\n
Alt + F3(选择所有匹配项)
替换为 ,\r\n.bootstrap-scope
就是这样!由于更换大约需要一分钟,因此后续更新将非常容易。希望我的回答有所帮助。
扩展@Andrew Homeyer 答案:
通过执行以下操作,我在我的 Reactjs 应用程序中获得了 boostrap 的范围样式:
Bootstrap 使用 Grunt 作为其构建系统,并提供了使用框架的便捷方法。这就是我们编译代码、运行测试等的方式。
安装 Grunt:要安装 Grunt,您必须首先下载并安装 node.js(包括 npm)。npm 代表 node packaged modules,是一种通过 node.js 管理开发依赖的方法。
然后,从命令行:使用 .grunt-cli 全局安装
npm install -g grunt-cli
。导航到根 /bootstrap/ 目录,然后运行npm install
. npm 将查看 package.json 文件并自动安装其中列出的必要本地依赖项。完成后,您将能够运行从命令行提供的各种 Grunt 命令。
less/bootstrap.less
将下载源中的文件编辑为以下内容:.bootstrap-scope {...pasted all @imports here...}
grunt dist
运行并将新的 dist 文件夹复制到我的App.js项目import './styling/bootstrap/css/bootstrap.min.css';
。类似的讨论在这里
无需分叉/编辑原始引导程序。只需像这样将其导入包装在您的文件中(在我的情况下为 sass):我创建了文件“bootstrap-scope-limit.scss”(我在需要引导的地方导入):
.bootstrap-inside {
@import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";
@import "~bootstrap-sass/assets/stylesheets/bootstrap/_theme.scss";
}
重要通知!
请记住,bootstrap 有一些在使用这种方法时不会应用的 body 样式。但是,如果某些动态内容必须使用引导程序,它使您能够通过向元素添加“bootstrap-inside”类来控制引导程序,以启用或禁用整个页面的引导程序。
您应该注意的另一个问题:一些覆盖引导样式的插件可能会出现问题,因为具有新类包装器的引导样式变得更强大(更具体)并且不能被未包装的插件覆盖。
对于 webpack 案例,我建议使用此加载器:https ://www.npmjs.com/package/wrap-css-loader来包装整个包,您可以稍后将其用作应用程序(div?)的一部分
扩展@jtlindsey 答案。如果你想使用 bootstrap 4,你必须做一些小改动。
而不是编辑less/bootstrap.less
,你必须编辑scss/bootstrap.scss
那么你必须按顺序执行这个命令:
gem install bundler
bundle install
npm run dist
并且在 dist 文件夹中生成了新的 bootstrap.min.css。
在这里您可以获得更多信息: https ://getbootstrap.com/docs/4.0/getting-started/build-tools/
如果你想要一个不涉及外部库的纯 JavaScript 解决方案,你可以走这条路:一般的想法是加载原始 css,然后逐行解析它,在必要时添加你的作用域选择器。
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>
我所知道的唯一肯定比这个脚本更糟糕的是引导程序本身,但这可能仍然是一段时间内最好的答案:
prefix="#bs431"; cat bootstrap.css | while IFS='' read -r line; do if echo "$line" | egrep -i '(\{|,)$' | egrep -iv '\@media' | wc -l | egrep -iq '^0$'; then echo "$line"; else echo "$line" | perl -pe 's/^(\s+)?/\1'"$prefix"' /g' | perl -pe 's/, (\.|#|\[|[a-zA-Z]{1})/, '"$prefix"' \1/g'; fi; done | perl -pe 's/'"$prefix"' :root/'"$prefix"'/g' > bootstrap.scoped.css