如何使用Sass正确避免在HTML中嵌入Twitter Bootstrap类名

18

我正在开发一个Rails项目,现在处于起步阶段。我们想要以Twitter Bootstrap为基础样式,开始时我们会像Bootstrap文档中展示的那样,在HTML代码中直接使用Bootstrap的类名,但是在阅读了以下文章之后:

可维护CSS的教训

请停止在HTML中嵌入Bootstrap类

就变得清楚了为什么这不是使用Bootstrap的正确方式,所以在阅读更多的文章后:

将CSS从HTML分离出来

SMACSS

等其他文章中,使用Sass @extend似乎是避免使用Bootstrap类名的正确方式,因此不再像这样做:

<button type="submit" class="btn">Search</button>

我们会这样做:

<button type="submit" class="button">Search</button>

我们的 Sass 代码将如下所示:

.button {
   @extend ".btn";
}

除了每次扩展引导程序类以使用不同名称时都会添加一堆额外的选择器之外,这种方法的问题在于,在引导程序使用这样的选择器的情况下:

.form-search .input-append .btn, .form-search .form-input-append .btn {
  border-radius: 0 14px 14px 0;
} 

按钮不会获得正确的样式,因为Sass不会将同一规则应用于我们的自定义类名,我的意思是,Sass不会这样做:

.form-search .input-append .btn, .form-search .input-append .button, 
.form-search .form-input-append .btn, .form-search .form-input-append .button {
  border-radius: 0 14px 14px 0;
} 

我在想,这是否是避免将Bootstrap的类名嵌入HTML的正确方式?如果是,我该如何解决这个问题(它经常发生)?如果不是,有什么更好的方法可以使用自定义类名但仍从Bootstrap获取样式。

非常感谢您对此的想法。请记住,我只是在学习整体网页设计(CSS、Sass、Less、HTML、JS等)。


4
除了“不要使用Bootstrap”或者“改写Bootstrap使其不愚蠢”之外,我不确定是否有解决方案。在您的按钮示例中,类名不应该被引用(此外我认为,在按钮元素上使用“button”类是多余的)。您的第二个示例不起作用,因为它是复合选择器,而“@extend”仅适用于简单选择器。 - cimmanon
2
Bootstrap最初是用LESS编写的,但也有一些移植到SASS的版本:
  • https://github.com/thomas-mcdonald/bootstrap-sass
  • https://github.com/jlong/sass-twitter-bootstrap 试试它们,至少其中一个应该有你需要的类。
- Andrey Mikhaylov - lolmaus
2
Bootstrap是一种有主见的软件。它使用了大量的类。如果您不想使用大量的类,我同意@cimmanon的观点,即“不使用Bootstrap”是一个好的解决方案。 - bookcasey
2
我不同意在按钮元素上使用“button”类是多余的观点。可能存在一种情况,您不希望将样式应用于按钮。 “button”可能不是最合适的类名,但我认为肯定应该使用一个类名。 - Matthew G
1
我认为这并不重要,无论是button.button还是button.btn、table.table或table.tbl、label.label或label.lbl,关键是将全局样式应用于标签可能会使跟踪错误放置的样式变得很麻烦。 - Matthew G
显示剩余5条评论
5个回答

2
当你将.btn重命名为.button时,你也应该将.form-search重命名为.form-searchnew等等。在这种情况下,以上示例中的Sass代码应该是这样的:
.form-searchnew .input-appendnew .button {
  extend(.form-search .input-append .btn);
}

这样做是有道理的(我不了解Sass),并且会产生您所期望的CSS。

我认为Bootstrap不仅仅是CSS。Bootstrap涉及到CSS、HTML(结构)和JavaScript。即使将CSS与HTML分离,也不容易迁移到其他框架。除了CSS之外,您还需要更改HTML结构和JavaScript调用。

例如,从Twitter的Bootstrap 2迁移到3(请参见:更新Bootstrap到版本3-我需要做什么?)。我还想知道是否可以通过扩展旧类来迁移新的CSS(请参见:http://bassjobsen.weblogs.fm/migrate-your-templates-from-twitter-bootstrap-2-x-to-twitter-bootstrap-3/)。阅读了迁移指南后,我认为您不能这样做。

其他解决方案。Angular JS将Twitter的Bootstrap与JavaScript解耦。即使在这种情况下,迁移也似乎不是无痛的(请参见:使用Bootstrap 3的Angular对话框指令)。

也可以阅读这篇文章:从Zurb Foundation / Twitter Bootstrap迁移。它提到了BourdonNeat

他们网站上的例子:

<!-- HTML markup for the section right below this code block -->
<section>
  <aside>What is it about?</aside>
  <article>Neat is an open source semantic grid framework built on top of Sass and Bourbon…</article>
</section>

// Enter Neat
section {
  @include outer-container;
  aside { @include span-columns(3); }
  article { @include span-columns(9); }
}
// And the result is...

正如他们所说:“它完全依赖于Sass mixin,不会污染您的HTML”,这似乎是您正在寻找的方式。

2
我建议您查看sass占位符类http://sass-lang.com/documentation/file.SASS_REFERENCE.html#placeholders,以避免使您的css膨胀。很可能您不会使用Bootstrap中包含的每个元素,只有在代码中实际扩展它们时,占位符才会被写入您的样式表中。
此外,我认为人们往往会对css框架的工作方式和如何解耦css和html感到困惑。 对于非常大的网站(或者您预计最终会变得非常大),其中性能和css文件大小至关重要,一些OOCSS方法是您最好的选择。这意味着您必须直接在HTML中编写格式化代码。
如果您可以容忍效率稍低,并且希望您的HTML保持清洁,请确保使用语义类(例如按钮的示例:call-to-action、call-to-action-secondary、submit、btn-primary、btn-corporate-color等)。
还要记得将JS与CSS分离!使用特殊类来附加行为(例如js-submit、js-call-to-action等...)。
最后但并非最不重要的是:不要计划更新你的CSS框架。这些框架旨在为您提供一个起点,而不是成为您整体设计解决方案。扩展它们,调整它们,使它们成为您自己的,投资于设计并创建您自己的外观以使您的应用程序独特。如果让您想更新的原因是担心跟上标准变化,最好使用Compass Mixins。

1
我想要+10,但我只能+1!我正在尝试重写Bootstrap的Sass,并将所有内容转换为占位符,但这很繁琐...你知道是否有人已经完成了这个任务并分享了吗? - redben

1

使用@extend,但不要引用选择器:

.button { @extend .btn; }

然后你会发现Sass也会扩展相关的选择器,就像你想要的一样(.form-search .input-append .btn等)。

...除了每次我们扩展一个bootstrap类来使用不同名称时将添加的大量额外选择器...

@extend通过复制选择器来工作。如果您不想这样做,可以在HTML中“扩展” - 即添加Bootstrap的类名。 :)


1
对于大部分新手来说,你已经走在了正确的道路上;你所阅读的资源是极好的。但是,我认为你所担心的问题可能是没有必要的:

......按钮不会得到正确的样式,因为sass不会将同一规则应用于我们的自定义类名......

实际上,我认为你可能是错的。根据Sass文档:

@extend通过在样式表中插入扩展选择器(例如.seriousError),出现扩展选择器(例如.error)的任何地方都可以工作。

请参见http://sass-lang.com/documentation/file.SASS_REFERENCE.html#how_it_works以获取完整的代码示例。
你最初的解决方案实际上是正确的。使用扩展,但不要加引号:
.button {
  @extend .btn; //no quotes
}

我使用你的示例进行了测试,它可以正常工作。Sass会复制所有带有“.btn”类选择器的选择器,并在这些新创建的选择器上将“.btn”替换为“.button”。

此外,如果Sass生成了太多的重复代码,不必担心(只要您遵循所提供的链接指出的最佳实践)。如果服务器使用gzip或等效方法,则可以轻松压缩重复的代码; 客户端不应注意到任何较慢的加载时间,尽管可能需要稍长时间才能“解压”CSS。至于CSS选择器速度,也不必担心; 选择器速度仅在JavaScript方面特别是jQuery方面才很重要。对于您的Sass代码,请遵循可维护性的最佳实践(特别是像SMACSS这样的模块化),然后您就可以开始工作了。


0

Sam和tjklemz提供的答案将帮助您解决即时的技术挑战,但是可以更进一步地解耦CSS和HTML。我将在下面给出一个示例,但请记住,这只是一个快速示例,以展示mixin/扩展CSS类的强大功能。

我还强烈建议查看ZURB Foundation框架,因为它是本地SASS,并且专为这种开发风格而设计。

例如:

<body>
    <div id="my-header">
        <h1><a href="#">My Company</a></h1>
        <h2>My Tagline</h2>
    </div>
    <div id="my-main">
        <div class="my-widget">
            <h1>Widget Title</h1>
            <a>Widget Option 1</a>
            <a>Widget Option 2</a> 
        </div>    
    </div>
</body>

搭配的 SCSS 代码如下:

//these examples wouldn't really work
//because bootstrap needs more markup
#my-header {
    @extend .navbar;
}
#my-header h1 {
    @extend .branding;
}
#my-main {
    @extend .container;
}

//good example
.my-widget {
    @extend .well;
    @extend .hero-unit;
}
.my-widget a {
    @extend .btn;
}

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