修改 Bootstrap LESS 文件以使用 ID 选择器

Posted

技术标签:

【中文标题】修改 Bootstrap LESS 文件以使用 ID 选择器【英文标题】:Modify Bootstrap LESS files to use an ID selector 【发布时间】:2014-09-13 20:09:35 【问题描述】:

简而言之,我要做的是在 Bootstrap.CSS 之上应用自定义 ID 选择器,这样我就不会破坏网站上的其他 CSS。所以这个:

.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12

    position: relative;
    min-height: 1px;
    padding-left: 15px;
    padding-right: 15px;    

变成这样:

#my-id-selector .col-xs-1, #my-id-selector .col-sm-1, #my-id-selector .col-md-1, #my-id-selector .col-lg-1, #my-id-selector .col-xs-2, #my-id-selector .col-sm-2, #my-id-selector .col-md-2, #my-id-selector .col-lg-2, #my-id-selector .col-xs-3, #my-id-selector .col-sm-3, #my-id-selector .col-md-3, #my-id-selector .col-lg-3, #my-id-selector .col-xs-4, #my-id-selector .col-sm-4, #my-id-selector .col-md-4, #my-id-selector .col-lg-4, #my-id-selector .col-xs-5, #my-id-selector .col-sm-5, #my-id-selector .col-md-5, #my-id-selector .col-lg-5, #my-id-selector .col-xs-6, #my-id-selector .col-sm-6, #my-id-selector .col-md-6, #my-id-selector .col-lg-6, #my-id-selector .col-xs-7, #my-id-selector .col-sm-7, #my-id-selector .col-md-7, #my-id-selector .col-lg-7, #my-id-selector .col-xs-8, #my-id-selector .col-sm-8, #my-id-selector .col-md-8, #my-id-selector .col-lg-8, #my-id-selector .col-xs-9, #my-id-selector .col-sm-9, #my-id-selector .col-md-9, #my-id-selector .col-lg-9, #my-id-selector .col-xs-10, #my-id-selector .col-sm-10, #my-id-selector .col-md-10, #my-id-selector .col-lg-10, #my-id-selector .col-xs-11, #my-id-selector .col-sm-11, #my-id-selector .col-md-11, #my-id-selector .col-lg-11, #my-id-selector .col-xs-12, #my-id-selector .col-sm-12, #my-id-selector .col-md-12, #my-id-selector .col-lg-12

    position:relative;
    min-height:1px;
    padding-left:15px;
    padding-right:15px

所以,想象一下这种情况,我认为这很常见:

您使用 Bootstrap(在我们的例子中是 3.1.1)来构建需要在另一个应用程序中运行的网络/移动应用程序小部件。小部件将有自己的 CSS,不得破坏宿主应用程序的 CSS。

小部件将存在于具有特定 ID 的漂亮小 DIV 中。

所以我们要做的是修改编译 Bootstrap 的 LESS 文件以引用该特定 ID。我快要做到这一点了,但我一直遇到问题。我目前遇到的问题是 Bootstrap LESS 代码使用 mixins 来创建特定于 GRID 的 CSS(在 GRID.LESS 文件中)。当我尝试将我的选择器添加到 GRID.LESS 文件时,它的行为并不像我期望/希望的那样:它不是将我的 ID 选择器应用于 GRID.LESS 文件中的所有类选择器,而是仅适用于选择器列表中的第一个选择器。

(据我了解,作为 Bootstrap 的一点背景知识(希望那些有 LESS 经验的人即使您从未使用过 Bootstrap 也能回答我的问题):源 LESS 文件都通过 @import 语句在BOOTSTRAP.LESS 文件。我使用 Grunt 根据 Bootstrap 的网站文档编译 Bootstrap.CSS 和 JS 文件(因此存在一个 Grunt.JSON 文件来编排 LESS 编译和一堆其他东西)。BOOTSTRAP.LESS 使用 @import 来访问VARIABLES.LESS、MIXINS.LESS、GRID.LESS,都是本剧的主角)。

希望我能解释一下我的意思:

原始代码(Bootstrap 3.1.1)的 GRID.LESS 文件包含:

// Columns
//
// Common styles for small and large grid columns
.make-grid-columns();

该代码在 MIXIN.LESS 文件中调用了一个 mixin,该文件动态创建了一些列类选择器:

.make-grid-columns() 
  // Common styles for all sizes of grid columns, widths 1-12
  .col(@index) when (@index = 1)  // initial
    @item: ~".col-xs-@index, .col-sm-@index, .col-md-@index, .col-lg-@index";
    .col((@index + 1), @item);
  
  .col(@index, @list) when (@index =< @grid-columns)  // general; "=<" isn't a typo
    @item: ~".col-xs-@index, .col-sm-@index, .col-md-@index, .col-lg-@index";
    .col((@index + 1), ~"@list, @item");
  
  .col(@index, @list) when (@index > @grid-columns)  // terminal
    @list 
      position: relative;
      // Prevent columns from collapsing when empty
      min-height: 1px;
      // Inner gutter via padding
      padding-left:  (@grid-gutter-width / 2);
      padding-right: (@grid-gutter-width / 2);
    
  
  .col(1); // kickstart it

我不完全理解上面的代码,但我认为它会循环遍历它从 Bootstrap 附带的 VARIABLES.LESS 文件中接收到的参数,并在 CSS 中创建类选择器列表,如下所示:

.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12

   position: relative;
   min-height: 1px;
   padding-left: 15px;
   padding-right: 15px;

我所做的修改是在调用周围添加我的自定义 ID 选择器范围,如下所示:

// Columns
//
// Common styles for small and large grid columns
#my-id-selector .make-grid-columns();

问题在于,这不会将我的选择器应用于 Bootstrap 在 MIXIN.LESS 代码中创建的所有动态生成的列,而是仅将我的 ID 选择器添加到列表中的第一个选择器,如下所示:

#my-id-selector .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12

    position: relative;
    min-height: 1px;
    padding-left: 15px;
    padding-right: 15px;

我觉得奇怪的是,如果我只是编写一个没有 mixin 的 LESS 文件来将我的 ID 选择器的范围应用于选择器列表,我会得到我期望的输出。比如这个……

#my-id-selector

    .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12
    
        position: relative;
        min-height: 1px;
        padding-left: 15px;
        padding-right: 15px;    
    

...产生预期的和非常需要的输出:

#my-id-selector .col-xs-1,#my-id-selector .col-sm-1,#my-id-selector .col-md-1,#my-id-selector .col-lg-1,#my-id-selector .col-xs-2,#my-id-selector .col-sm-2,#my-id-selector .col-md-2,#my-id-selector .col-lg-2,#my-id-selector .col-xs-3,#my-id-selector .col-sm-3,#my-id-selector .col-md-3,#my-id-selector .col-lg-3,#my-id-selector .col-xs-4,#my-id-selector .col-sm-4,#my-id-selector .col-md-4,#my-id-selector .col-lg-4,#my-id-selector .col-xs-5,#my-id-selector .col-sm-5,#my-id-selector .col-md-5,#my-id-selector .col-lg-5,#my-id-selector .col-xs-6,#my-id-selector .col-sm-6,#my-id-selector .col-md-6,#my-id-selector .col-lg-6,#my-id-selector .col-xs-7,#my-id-selector .col-sm-7,#my-id-selector .col-md-7,#my-id-selector .col-lg-7,#my-id-selector .col-xs-8,#my-id-selector .col-sm-8,#my-id-selector .col-md-8,#my-id-selector .col-lg-8,#my-id-selector .col-xs-9,#my-id-selector .col-sm-9,#my-id-selector .col-md-9,#my-id-selector .col-lg-9,#my-id-selector .col-xs-10,#my-id-selector .col-sm-10,#my-id-selector .col-md-10,#my-id-selector .col-lg-10,#my-id-selector .col-xs-11,#my-id-selector .col-sm-11,#my-id-selector .col-md-11,#my-id-selector .col-lg-11,#my-id-selector .col-xs-12,#my-id-selector .col-sm-12,#my-id-selector .col-md-12,#my-id-selector .col-lg-12

    position:relative;
    min-height:1px;
    padding-left:15px;
    padding-right:15px

您可以看到我的#my-id-selector 已应用于列表中的所有选择器,我能检测到的唯一区别是 mixin 调用。所以看起来 mixin 在应用我的选择器 ID 后会进行评估。

如果是这种情况,是否有某种方法可以确保首先评估 mixin,然后应用我的范围?

有没有人尝试自定义 Bootstrap 以使其特定于 ID 选择器?

更新: 一种解决方法是修改 MIXINS.LESS 的 .make-grid-columns() mixin 以传入我的 ID 选择器。这是代码:

.make-grid-columns(@id_prefix: "") 
  // Common styles for all sizes of grid columns, widths 1-12
  .col(@index) when (@index = 1)  // initial
    @item: ~"@id_prefix .col-xs-@index, @id_prefix .col-sm-@index, @id_prefix .col-md-@index, @id_prefix .col-lg-@index";
    .col((@index + 1), @item);
  
  .col(@index, @list) when (@index =< @grid-columns)  // general; "=<" isn't a typo
    @item: ~"@id_prefix .col-xs-@index, @id_prefix .col-sm-@index, @id_prefix .col-md-@index, @id_prefix .col-lg-@index";
    .col((@index + 1), ~"@list, @item");
  
  .col(@index, @list) when (@index > @grid-columns)  // terminal
    @list 
      position: relative;
      // Prevent columns from collapsing when empty
      min-height: 1px;
      // Inner gutter via padding
      padding-left:  (@grid-gutter-width / 2);
      padding-right: (@grid-gutter-width / 2);
    
  
  .col(1); // kickstart it

真正令人讨厌的是我必须进行大量自定义才能“修复”所有 Bootstrap CSS,以便它使用我的 ID 选择器。所以我还在寻找更好的解决方案……

【问题讨论】:

【参考方案1】:

目前唯一可能的解决方案是将已编译 Bootstrap CSS 导入 Less 命名空间,即:

#my-id-selector 
    @import (less) "bootstrap.css";

将 Bootstrap 较少的源导入命名空间将无法按预期工作,这不仅是因为列类,而且还有一百零一个原因(有关详细信息,请参阅 #2052)。

【讨论】:

感谢您的提示。我感觉会是这样,:(正如我在帖子中所说,这只是我遇到的最新问题,已经浏览了其他十几个问题......

以上是关于修改 Bootstrap LESS 文件以使用 ID 选择器的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Bootstrap 试图在 Edge 中加载 LESS 文件?

如何使用bootstrap的daterangepicker插件

如何使用bootstrap的daterangepicker插件

Less 和 Bootstrap:如何使用 span3(或 spanX [任意数量])类作为 mixin?

我可以将 LESS 文件导入 SASS 吗?

导入使用mixins的less文件时可以避免重复的css吗?