如何在rails app中使用twitter bootstrap和bootstrap-sass?

时间:2012-03-27 21:07:27

标签: ruby-on-rails twitter-bootstrap bootstrap-sass

我对此很陌生,但我无法弄清楚问题。

在twitter bootstrap中我会使用:

<div class="row-fluid">
  <div class="span2">Column1</div>
  <div class="span6">Column2</div>
</div>

一切正常。但是我不想将spanX和spanY直接写入我的html文件,而是想提供有意义的类名,例如:

<div class="user-container">
  <div class="user-filter">First Column</div>
  <div class="user-list">Second Column</div>
</div>

鉴于我正在使用https://github.com/thomas-mcdonald/bootstrap-sass的事实,我应该如何编写我的scss文件?我尝试过以下操作,它不起作用(不显示两列):

@import "bootstrap";
@import "bootstrap-responsive";

.user-container {
    @extend .row-fluid;
}

.user-filter {
    @extend .span2;
}

.user-list {
    @extend .span10;
}

如果我查看生成的代码,在我看来一切都应该没问题:

/* line 164, ../../../../../.rvm/gems/ruby-1.9.3-p125/gems/bootstrap-sass-2.0.0/vendor/assets/stylesheets/bootstrap/_mixins.scss */
.span2, .user-filter {
  width: 140px;
}

等等。

我做错了什么?

更新

好吧,只是为了清楚是什么问题 - 列被列为行(一个接一个),而不是真正的列(彼此相邻),例如:

with bootstrap:Column1 Column2
与我的自定义类:
第一栏
第二栏

我已经检查过Chrome中的元素布局,似乎bootstrap类有float属性,而我的 - 没有。看看css源我看到这样的类:

[class*="span"] {
  float: left;
  margin-left: 20px;
}

所以在我的情况下,我认为它应该产生如下:     [class * =“user-filter”] {       向左飘浮;       margin-left:20px;     }

是不是?

3 个答案:

答案 0 :(得分:19)

这是你使用@extend,或者更确切地说,Sass'无法处理通配符类匹配,这是相当不足为奇的,因为它变得相当复杂。

Bootstrap使用了许多我可能称之为“非标准”的方法来解决某些类。您已经在上面的帖子中提到了其中一个 - [class*="span"]

当然,当您使用@extend x时,Sass正在扩展x类。不幸的是,它(目前)无法知道通配符匹配器也会影响类的输出。所以是的,在一个理想的世界中,[class*="span"]也会被扩展为定义[class*="span"], .user-filter,但Sass目前无法做到这一点。

虽然扩展.row-fluid足以包含嵌套在其下的规则。如上所述,span类不会调整扩展跨度的通配符。

bootstrap-sass已经有一个mixin用于固定宽度的列/行,makeRow()makeColumn()。我刚刚推了一个makeFluidColumn()混合物,这就是一个流畅的跨度。您的代码将变为:

.user-container {
  @extend .row-fluid;
}

.user-filter {
  @include makeFluidColumn(2);
}

.user-list {
  @include makeFluidColumn(10);
}

不幸的是(按照惯例)它并不那么简单。 Bootstrap使用此代码段重置第一个spanx类的边距,该第一个spanx类是该行的子节点。

> [class*="span"]:first-child {
  margin-left: 0;
}

但是,我们无法为makeFluidColumn的每次调用重新定义此项,因此我们必须在任何将成为流体行的第一个子元素的元素上手动设置左边距。同样值得注意的是,混合spanx类和makeFluidColumn类将导致第一个spanx类重置其边距,无论它是否实际上是行中的第一列。

因此您的代码将

.user-container {
  @extend .row-fluid;
}

.user-filter {
  @include makeFluidColumn(2);
  margin-left: 0; // reset margin for first-child
}

.user-list {
  @include makeFluidColumn(10);
}

这不是一个特别漂亮的解决方案,但它可以工作,并且与你在问题更新中收集的Bootstrap如何使用通配符类匹配有关。我只是把它推到2.0.2分支,所以你必须使用Bundler和Git来安装它,但是我希望在接下来的几天内发布它。

答案 1 :(得分:4)

你是对的。 Twitter正在推动这里的模式。请参阅此文章。

http://ruby.bvision.com/blog/please-stop-embedding-bootstrap-classes-in-your-html

答案 2 :(得分:0)

使用boostrap-sass 2.3.2.2 gem我必须根据bootstrap的mixins创建自己的mixin,以使CSS类像bootstrap .span类一样。

// private mixin: add styles for bootstrap's spanX classes
@mixin _makeFluidSpan($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth) {
  @include input-block-level();
  float: left;
  margin-left: $fluidGridGutterWidth;
  *margin-left: $fluidGridGutterWidth - (.5 / $gridRowWidth * 100px * 1%);
  @include grid-fluid-span($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth);
}

// thats what you should use
@mixin makeFluidSpan($gridColumns) {
  @media (min-width: 980px) and (max-width: 1199px) {
    @include _makeFluidSpan($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth);
  }
  @media (min-width: 1200px) {
    @include _makeFluidSpan($gridColumns, $fluidGridColumnWidth1200, $fluidGridGutterWidth1200);
  }
  @media (min-width: 768px) and (max-width: 979px) {
    @include _makeFluidSpan($gridColumns, $fluidGridColumnWidth768, $fluidGridGutterWidth768);
  }
  &:first-child {
    margin-left: 0;
  }
  @media (max-width: 767px) {
    float: none;
    display: block;
    width: 100%;
    margin-left: 0;
    box-sizing: border-box;
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
  }
}

示例:

  .like-span3 { // this class acts like .span3
    @include makeFluidSpan(3);
  }