如何使用 sass 正确避免在 HTML 上嵌入 twitter 引导类名称

Posted

技术标签:

【中文标题】如何使用 sass 正确避免在 HTML 上嵌入 twitter 引导类名称【英文标题】:How to use sass to properly avoid embedding twitter bootstrap class names on HTML 【发布时间】:2013-04-10 08:52:03 【问题描述】:

我正在处理一个刚刚开始的 Rails 项目。我们想使用 twitter bootstrap 作为我们样式的基础,一开始我们会直接在 html 代码中使用 bootstrap 的类名,就像在 bootstrap 的文档中显示的那样,但是在阅读了以下帖子之后:

Lessons learned in maintainable css

Please stop embedding Bootstrap classes in your HTML

很清楚为什么这不是使用引导程序的正确原因,所以在阅读了更多内容后:

Decouple Your CSS From HTML

smacss

除此之外,使用 sass @extend 似乎是避免使用引导程序的类名的正确方法,所以不要这样做:

<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;
 

所以我想知道,这是避免将引导程序的类名嵌入到 HTML 中的正确方法,如果是,我应该如何处理这个问题(它经常发生)?如果不是,那么使用自定义类名但仍从引导程序中获取样式的更好方法是什么。

非常感谢您对此的看法。请记住,我只是在学习整体网页设计(css、sass、less、html、js 等)。

【问题讨论】:

除了“不要使用Bootstrap”或者“重写Bootstrap不迟钝”,我不确定有没有解决办法。在您的按钮示例中,不应引用类名(另外,我认为按钮元素上的“按钮”类是多余的)。您的第二个示例不起作用,因为它是一个复合选择器,而 @extend 仅适用于简单选择器。 Bootstrap 最初是用 LESS 编写的,但是有几个 SASS 端口: - github.com/thomas-mcdonald/bootstrap-sass - github.com/jlong/sass-twitter-bootstrap 试试看,其中至少一个应该有你需要的类。跨度> Bootstrap 是自以为是的软件。它使用了很多很多的类。如果不想使用很多很多的类,我同意@cimmanon 的观点,即“不要使用 Bootstrap”是一个很好的解决方案。 我不同意按钮元素上的“按钮”类是多余的。可能存在您不希望将样式应用于按钮的情况。 “按钮”可能不是最合适的类名,但我相信肯定应该使用一个。 我认为是 button.button 还是 button.btn、table.table 还是 table.tbl、label.label 还是 label.lbl,我认为这并不重要,关键是将全局样式应用于标签可能会让以后追踪错位的样式很烦人。 【参考方案1】:

当您将 .btn 重命名为 .button 时,您还应该将 .form-search 重命名为 .form-searchnew 等吗? 在这种情况下,上面示例中的 sass 代码应该类似于:

.form-searchnew .input-appendnew .button 
  extend(.form-search .input-append .btn);

这是有道理的(我不知道 sass)并导致您期望的 css。

我认为引导程序不仅仅与 CSS 有关。 Bootstrap 是关于 css、html(结构)和 javascript 的。即使您将 css 与 html 分开,我也不容易迁移到其他框架。除了 css,您还必须更改 html 结构和 javascript 调用。

从 Twitter 的 Bootstrap 2 迁移到 3 的示例(请参阅:Updating Bootstrap to version 3 - what do I have to do?)。我还想知道您是否可以通过将旧类扩展到新 css 来进行迁移(请参阅:http://bassjobsen.weblogs.fm/migrate-your-templates-from-twitter-bootstrap-2-x-to-twitter-bootstrap-3/)。看完migration guide,我觉得你做不到。

其他解决方案。 Angular JS 将 Twitter 的 Bootstrap 与 javascript 分离。同样在这种情况下,迁移似乎也不是无痛的,请参阅:Angular Dialog directives with Bootstrap 3

也许也读过这篇文章:http://www.jasonwong.org/post/45849350459/migrating-from-zurb-foundation-twitter-bootstrap-to。它指的是Bourdon 和Neat。

来自他们网站的示例:

<!-- 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 混合,不会污染您的 HTML”,这似乎是您正在寻找的方式。

【讨论】:

【参考方案2】:

我建议您查看 sass 占位符类 http://sass-lang.com/documentation/file.SASS_REFERENCE.html#placeholders 以免使您的 css 膨胀。很可能您不会使用引导程序中包含的每一个元素,并且占位符只有在您的代码中实际扩展时才会写入您的样式表。

另外,我认为人们往往会对 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。

【讨论】:

我想+10,但我只能+1!我正在尝试重写 boostrapp 的 sass 并将所有内容转换为占位符,但这很乏味.. 你知道是否有人已经完成了这项任务并分享了它吗?【参考方案3】:

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

.button @extend .btn;

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

...除了每次我们扩展引导类时都会添加的一堆额外选择器,只是为了使用不同的名称...

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

【讨论】:

【参考方案4】:

对于大部分内容都是新手,您走在正确的轨道上;您一直在阅读的资源非常好。但是,我认为您的担忧可能没有道理:

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

其实我想你一定是搞错了。根据 Sass 文档:

@extend 通过在样式表中出现扩展选择器(例如 .error)的任何位置插入扩展选择器(例如 .seriousError)来工作。

完整代码示例请参见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),您就可以开始了。

【讨论】:

【参考方案5】:

sam 和 tjklemz 给出的答案将帮助您解决当前面临的技术挑战,但您的 CSS 和 HTML 可以进一步解耦。我将在下面给出一个示例,但请记住,这只是一个简单的示例,用于展示 mixins/扩展 CSS 类的强大功能。

我还强烈建议查看ZURB Foundation framework,因为它本身就是 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;

【讨论】:

以上是关于如何使用 sass 正确避免在 HTML 上嵌入 twitter 引导类名称的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 SASS 变量的多个 @imports?

如何在 SASS 中使用 Angular 4

如何在预编译期间包含自定义 SASS 函数?

Sass混合的使用

带有 Webpack 的 sass-loader 不会生成 CSS

Webpack sass-loader:如何正确使用字体?