限制引导程序样式的范围

时间:2012-05-12 23:04:27

标签: twitter-bootstrap

如何将Bootstrap限制为div的范围?我需要将ExtstS应用程序中的Bootstrap样式表嵌套到特定的div中,因为它们需要自己的主体,ul,li,a等,所以它们都会发生冲突。

我正在尝试避免手动编辑bootstrap.css(或将其保持在最低限度),以便可以轻松更新。

9 个答案:

答案 0 :(得分:44)

您可以fork the bootstrap回复并更改bootstrap.less以包装引导样式:

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

然后,在引导项目的根目录中,运行make以生成bootstrap.css文件。

你将失去全局样式bootstrap分配给body和html标签,但你可能不会想要它们。

然后,在您的应用中,为您提供所需的.bootstrap-scope类容器。

答案 1 :(得分:15)

由于修改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这样的各种mixins(来自less / mixins.xml)最终得到了严重的前缀。例如:

    .bootstrap-scope .col-sm-1,
      .col-sm-2,
      .col-sm-3,
    
  • "&" in LESS的使用受到限制:

    .caret {
      .btn-default & {
    

    变为

     .btn-default .bootstrap-scope .caret {
    

    而不是我们想要的:

     .bootstrap-scope .btn-default .caret {
    

答案 2 :(得分:7)

有更简单的方法来实现这一合法要求:将NEWLINE和NEWLINE替换为以前的值和类范围。它很容易在例如升华:

  • 选择} \ r \ n

  • Alt + F3(选择所有出现次数)

  • 替换为} \ r \ n.bootstrap-scope

  • 选择,\ r \ n

  • Alt + F3(选择所有出现次数)

  • 替换为\ r \ n.bootstrap-scope

就是这样!由于更换大约需要一分钟,因此可以很容易地更新它。希望我的回答有所帮助。

答案 3 :(得分:6)

如果您有以下文件结构:

  • mystyles.less
  • mystyles.css
  • /引导/
    • bootstrap.less
    • bootstrap.css
    • grid.less
    • ...
    • /混入/

你想限制引导程序的范围,你必须加入你的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;
 }

但是如果你导入bootstrap较少的文件,你会得到一个错误的范围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;
}

答案 4 :(得分:5)

扩展@Andrew Homeyer回答:

通过执行以下操作,我在我的Reactjs应用程序中使用了defrap样式的boostrap:

  1. 去了here并下载了bootstrap源
  2. 按照指南here安装grunt。摘要:
  3.   

    Bootstrap使用Grunt作为其构建系统,方便的方法   使用框架。我们如何编译代码,运行测试,   等等。

         

    安装Grunt:要安装Grunt,您必须先下载并安装   node.js(包括npm)。 npm代表节点打包模块和   是一种通过node.js管理开发依赖项的方法。

         

    然后,从命令行:全局安装grunt-cli   npm install -g grunt-cli。导航到root / bootstrap /目录,然后运行npm install。 npm将查看package.json文件和   自动安装那里列出的必要的本地依赖项。   完成后,您将能够运行各种Grunt命令   从命令行提供。

    1. 将已下载来源的文件less/bootstrap.less修改为以下内容:
    2. .bootstrap-scope {...pasted all @imports here...}

      enter image description here

      1. grunt dist并将新的dist文件夹复制到我的项目中 在App.js import './styling/bootstrap/css/bootstrap.min.css';
      2. enter image description here

        类似讨论here

答案 5 :(得分:2)

无需分叉/编辑原始引导程序。 只需将其导入包装在您的文件中(就我的情况而言): 我创建了文件" bootstrap-scope-limit.scss" (我在需要bootstrap的地方导入):

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

重要通知!

请记住,bootstrap有一些在使用这种方法时不会应用的体型。但是通过添加" bootstrap-inside"它可以让你通过JS控制bootstrap。如果某些动态内容必须使用bootstrap,则为该元素的类启用或禁用整个页面的引导程序。

你应该注意的另一个问题是:一些覆盖bootstrap样式的插件可能会出现问题,因为带有新类包装器的bootstrap样式变得更强(更具体),并且不能被解包的插件覆盖。

对于webpack案例我建议使用这个加载器:https://www.npmjs.com/package/wrap-css-loader来包装整个包,你可以将它作为你的应用程序的一部分使用(div?)以后

答案 6 :(得分:0)

扩展@jtlindsey答案。如果你想使用bootstrap 4,你必须做一些小改动。

您必须编辑less/bootstrap.less

,而不是编辑scss/bootstrap.scss

然后你必须按顺序执行这个命令:

gem install bundler
bundle install
npm run dist

新的bootstrap.min.css在dist文件夹中生成。

您可以在这里获得更多信息: https://getbootstrap.com/docs/4.0/getting-started/build-tools/

答案 7 :(得分:0)

我唯一知道的是,肯定比该脚本更糟糕的是引导程序本身,但这可能仍然是一段时间的最佳答案:

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

答案 8 :(得分:0)

如果您想要一个不涉及任何外部库的纯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>