将CSS样式应用于特定元素

61

我有一个已经存在的网站,其中有很多旧页面和使用表格布局的表单,我正在逐步将它们转换为CSS。我想使用Twitter Bootstrap样式表中的样式 - 特别是表单样式 - 但只限于在我明确要求的页面部分中使用它们。例如,我可以像这样用一个div包围整个表单:

<div class="bootstrap">
 <!-- everything in here should have the Bootstrap CSS applied -->
 <form>
   <p><label for="text_input">Label</label><input type="text" id="text_input" /></p>
 </form>
</div>
我希望所有其他表单仍然保持不变,因为我无法同时更改它们。有没有简单的方法可以做到这一点?我可以遍历 Bootstrap CSS 中的每个样式并添加父选择器(例如,'p' 变成 'div.bootstrap p'),但这需要很长时间,而且很容易错过某些样式。
编辑:如果不可能实现这样的事情,是否有一个免费的工具可以从文件中提取所有样式,添加前缀,然后再保存回来呢?

5
你看过 less 吗?因为你可以把整个内容放在括号里就行了。 - Sherbrow
1
我之前听说过less,但不知道它可以帮助解决这种问题。最终我使用了SASS(由他人推荐),它似乎可以做同样的事情。 - pwaring
我刚刚使用了在线的SASS编译器和压缩器,分别是http://sassmeister.com/和http://www.shrinker.ch/。 - pixelbobby
有一些工具不需要编译,例如http://www.css-prefix.com/,但它们有时候表现得很奇怪(始终检查CSS的有效性...)。 - jave.web
另一种方法是通过使用基本编辑器(例如Notepad++)来抽象问题并通过正则表达式来解决 - 参见:https://dev59.com/TGgu5IYBdhLWcg3wrYwl - jave.web
7个回答

46

对于Bootstrap 3,如果您使用less,会更容易:

下载Bootstrap源代码,并创建一个类似于这样的style.less文件:

.bootstrap {
    @import "/path-to-bootstrap-less.less";
    @import "/path-to-bootstrap-responsive-less.less";
}

最后,你需要编译less文件;有许多替代方案。

https://github.com/cloudhead/less.js/wiki/Command-Line-use-of-LESS https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js

或者使用npm安装less,然后将style.less文件编译成style.css

npm install -g less
lessc style.less style.css

14
在引导自定义页面上应该有一个选项,可以添加可选前缀。这样做有很多用途。 - Jens
@Jens 我查看了,无法找到添加前缀的方法,http://getbootstrap.com/customize/#less-variables - pixelbobby
@pixelbobby 没有现成的。我实际上是指这是一个好主意,他们应该在页面上添加它。目前唯一的选择是像inzurrekt建议的那样自己编译。 - Jens
哈,有趣的歧义。我想知道如果你写成“应该有一个选项…”是否会更清晰。 “应该”和“应当”之间的区别一直不太清楚,但我认为这是使用它的情况! - graemeboy
对于那些喜欢自动化事物的人,这里有一个 Nix 推导来为您完成所有操作(在 Linux 或 macOS 上):https://gist.github.com/3noch/c9e523b90d91c8984ba833dfc88d087c - Elliot Cameron

29
最终的解决方法是使用SASS(由外部人员推荐),因为它允许您嵌套元素,然后自动生成最终的CSS。具体步骤如下:
  1. 将两个Bootstrap文件(bootstrap.cssbootstrap-responsive.css)连接成bootstrap-all.css
  2. 创建一个新的SASS文件bootstrap-all.scss,内容为div.bootstrap {
  3. bootstrap-all.css附加到bootstrap-all.scss上。
  4. 通过在bootstrap-all.scss末尾添加}来关闭div.bootstrap选择器。
  5. bootstrap-all.scss运行SASS以生成最终的CSS文件。
  6. 对最终文件运行YUI Compressor以生成压缩版本。
  7. 将压缩版本添加到head元素中,并将要应用样式的所有内容包装在<div class="bootstrap"></div>中。

谢谢,我可能会在以后尝试一下,因为它比我的bash+SASS解决方案更优雅。 - pwaring
第二步只需创建一个新的带有 .SCSS 后缀的文件吗? - SearchForKnowledge
嗨,我知道这篇文章比较老了,但是我最近也遇到了这个问题。另外一个解决方案是使用bootstrap-sass,并执行以下操作:.bootstrap-scope{@import "bootstrap";}。 在这里可以查看Codepen的结果here - ksrb
1
对我来说完美地工作了。我知道上面评论中的问题很旧,但是对于任何其他发现这个问题的人,是的,你只需要创建一个带有 .scss 扩展名的文件进行第二步操作。 - Sherwin Flight
这个答案可能适用于某些东西,但不可避免地会破坏其他东西。想象一下Bootstrap是如何应用样式到HTML和body以修复错误的?你刚刚删除了它们。这是hacky的。 - Toskan
太棒了!像魔法一样运行。 - Jay

15

如果由于工作或其他原因无法使用LESS/SASS,我想出了一种基于CSS的解决方案。

  1. 我使用了这个网站http://www.css-prefix.com/,将bootstrap.min.css复制粘贴到了那里。我设置了前缀='.bootstrap'和间隔=' '。它会在所有样式前面加上.bootstrap,但不是完全符合预期。
  2. 如果您在'.bootstrap @media'中查找grep,您会发现第一个类在左括号右侧没有.bootstrap作为其父级。将所有这些情况添加.bootstrap,对我来说大约有68个。
  3. 然后用'@media'替换所有的'.bootstrap @media'。
  4. 最后一步是将所有的'.bootstrap @'替换为'@'(应该有大约5个这样的情况)。

例如:

.bootstrap @media (min-width:768px){.lead{font-size:21px}}

需要被替换为

@media (min-width:768px){.bootstrap .lead{font-size:21px}}

这种方法有点蛮力,所以请先尝试上面的LESS / SASS方法。

<div>
  No Bootstrap
</div>
<div class="bootstrap">
  Yes Bootstrap
</div>

这是纯粹的天才。 - google1254
2
这个网站看起来被黑了。我再也不能访问css-prefix.com了。 - Lucas Crostarosa

7

我有一个简单的解决方案。

  1. 将Bootstrap CSS内容复制到此(http://css2sass.herokuapp.com/)在线CSS转换为SCSS/Sass转换器中。

  2. 在SCSS内容开头添加您的标签信息(例如div.bootstrap{),并在结尾处关闭标签。

  3. 将整个SCSS内容复制到此SCSS转换为CSS转换器(https://www.sassmeister.com/)中并进行转换 :)


1
同意。不错的解决方案! - Grant Miller

4

我对这些答案都不满意。使用Less来限定规则会产生各种缺陷。例如,Clearfix就被搞得一团糟。而像button.close这样的规则变成了button.bootstrap close,而不是我真正想要的.bootstrap button.close

我采取了不同的方法。我使用PostCSS来处理Bootstrap提供的现成CSS。我使用Scopify插件来将每个规则限定为.bootstrap

这基本上已经做到了。当然,有些规则如htmlbody会变成.bootstrap html.bootstrap body,它们变得没有意义了。没关系...我可以编写一个PostCSS转换来清理它们:

var elevateGlobalsPlugin = postcss.plugin('elevateGlobals', function(opts) {
    return function(css, result) {
        css.walkRules(function(rule) {
            rule.selector = rule.selector.replace('.bootstrap html', '.bootstrap');
            rule.selector = rule.selector.replace('.bootstrap body', '.bootstrap');
        });
    }
});

现在,我可以通过在顶层添加 class="bootstrap" 来隔离所有 Bootstrap 样式。


2
Brian,你能多提供一些关于你的解决方案的信息吗?JS代码是什么样子的? - tofutim
@tofutim 你在找什么?这是我在Gruntfile中作为PostCSS插件使用的JS的全部内容。我的Gruntfile引入了PostCSS并应用了Scopify插件,然后使用上述JS。输出结果是一个带有.bootstrap前缀的Bootstrap版本。 - Brian Genisio

3

这很困难。您无法为同一网页的不同部分应用不同的CSS样式表

我怀疑唯一的方法是为您的内容制作一个单独的文件,以采用Bootstrap样式,并像这样将其嵌入到页面中:

<iframe src="/content-to-take-bootstrap-styles.html" ></iframe>

然后在 content-to-take-bootstrap-styles.html 中的头部引用bootstrap样式表。但是,您会遇到所有iframe的复杂性--例如:iframe元素不会根据内容长度自动增长。


感谢确认(以及有用的其他问题链接)-我怀疑那就是情况。制作一个iframe可能会有点太过于丑陋的hack,但幸运的是我找到了SASS,它似乎已经做到了我想要的。 - pwaring
1
现在有一个新的“作用域”限制器,允许您将不同的样式表应用于页面的不同部分。 - Acyra
@Acyra:很有趣。所以从这里开始:http://css-tricks.com/saving-the-day-with-scoped-css/ 看起来你需要内联嵌入样式标签,并包围适当的在范围内的内容。 - Faust

2

您可以使用已准备好的隔离 CSS 来为 Bootstrap 4.1(使用 LESS 编译)提供支持 -

https://github.com/cryptoapi/Isolate-Bootstrap-4.1-CSS-Themes

它具有主题隔离的CSS -

要使用Bootstrap CSS,只需将您的HTML包装在一个类为bootstrapiso的div中,如下所示:

<div class="bootstrapiso">
<!-- Any HTML here will be styled with Bootstrap CSS -->
</div>

并使用文件夹css4.1中的任何CSS样式,如下所示:

<head>
<link rel="stylesheet" href="css4.1/bootstrapcustom.min.css" crossorigin="anonymous">
...
</head>

// https://github.com/cryptoapi/Isolate-Bootstrap-4.1-CSS-Themes

完成!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接