使用 Sass 定制个性化样式

发布于 2021-12-22 02:03:51 字数 5636 浏览 1227 评论 0

我并不介意你是否立即阅读本文,如果你把它加入收藏夹,并且在大脑中留有印象会更好。接下来我讲要谈论一下利用Sass的特性编写个性化样式的话题。

假设你要一次性为不同的品牌做几个不同的网站。假定有四个品牌:

  • Bob's Burgers
  • Paddy's Pub
  • Stu's Stews
  • Jurrasic Fork

如果我们为每个品牌,从头到尾地编写页面和样式,那工作量就太大了。大体上看就会有四倍工作量要做——没人有这时间。

每一个品牌的网站都需要独具一格的设计,但是我们可以对所有的品牌使用同一套页面标记。品牌之间也可以有通用布局和内容结构,所以我们也可以重用所有的样式。在所有通用设计的基础上,我们可以添加一层各个品牌独有的样式,从而在不同主题间体现唯一性。Theme Rules in SMACSS介绍了怎样用普通的CSS完成这一系列工作。你需要认清“通用设计”和“个性化设计”之间的区别。通用设计使用通用样式表,个性化设计使用主题特有的样式表。其次,主题特有的样式表要表现在通用样式表上层,最后就可以合力展现不同的主题风格了。

这就完成工作了,但就像是SMACSS的其余部分一样,这只是一个例子,并不意味着要一字不差地遵守。我们可以取其精华(比如通用设计和个性化设计分离的思想),并重新思考符合项目的实现方式。那是要怎样呢?

实现

重中之重:实现应该是适合用户的。我们不希望用户下载可能用不到的样式表。同理,用户应该只需要对样式表请求一次。如有可能,我们应该避免为获取基本样式表发送依次请求之后,在此基础上再次发送请求获取品牌独有的样式。

其次:实现应该是不刁难开发者的。开发者不应该花费时间,去管理散布在各个文件和目录中相似的代码块。说起来也很好解决。所有的代码应该包含在模块中。这减少了开发者理清整个项目结构的压力。这也有助于改善CSS文件间错综复杂的相互依赖关系。这样做不仅对新手方便,也方便了未来的你。

Sass能够优雅地管理这样的工作。我们只需使用一点预处理器组织样式的方式,就可以为多个主题管理,并提高代码的可读性和可维护性。

首先为每个品牌创建一个基础的SCSS文件。

  • bobs-burgers.scss
  • paddys-pub.scss
  • stus-stews.scss
  • jurassic-fork.scss

注意,这些并不是部件。它们没有以下划线开头,并且都会渲染到各自的CSS文件中。每个品牌只有一个CSS文件。这意味着每个品牌只发送一个请求,页面会更快地展现给用户,也意味着用户会很开心。用户满意就是最好的结果。

在每个文件中,我们都会定义一个$brand变量,然后引入其他组件。$brand变量是整个设计技巧的关键。我们就是通过它来输出各个品牌独有的设计代码。

这就是bobs-burgers.scss

// Set a variable containing current brand 
$brand: 'bobs-burgers'; 

// Import all components 
@import 'header'; 
@import 'hero'; 
@import 'footer'; 

所有品牌的文件看起来都一样,只有$brand的值是不同的。

等一下,“完全相同”?看上去是复制品!让我们消除它。我们可以把导入列表移到各自文件的底部。这样我们编写一个单一的文件就可以更新所有品牌的样式。我们可以创建一个_manifest. scss文件(因为这个文件并不单独存在,所以文件名开头由下划线)。现在我们可以将_manifest. scss导入到所有品牌的文件中,从而消除重复。

这就是新文件,去除了重复的bobs-burgers.scss:

// Set a variable containing current brand 
$brand: 'bobs-burgers'; 

// Import all components 
@import 'manifest'; 

这是_manifest.scss:

@import 'header'; 
@import 'hero'; 
@import 'footer'; 

现在开始,我们为不同的品牌创建样式。因为所有品牌的base文件都设置了$brand变量,我们就可以通过检查该变量的值,为各个品牌编写代码。

如果我们想为每个品牌设置不同的背景颜色,那么在_hero. scss文件中:

.hero { 
  // First, styles that all brands 
  // have in common. 
  // (The "shared stuff") 
  font-size: 2em; 
  font-weight: bold; 
  border: 1px solid; 

  // Next, brand-specific styles. 
  // (The "themed stuff") 
  @if $brand == 'bobs-burgers' { 
    border-color: yellow; 
  } 
  @if $brand == 'paddys-pub' { 
    border-color: green; 
  } 
  @if $brand == 'stus-stews' { 
    border-color: blue; 
  } 
  @if $brand == 'jurassic-fork' { 
    border-color: brown; 
  } 
} 

编译之后,一个既定品牌样式表就会包含所需的样式:所有品牌通用的样式,以及为该品牌独享的样式。不多也不少。在执行渲染的CSS中,没有一条重写的规则。只有恰到好处,简洁的品牌样式。

在模块中使用各个品牌的条件语句,可以帮助你减少输出结果的混淆。无需查找散布各个文件甚至是子文件中的规则。一切都恰到好处。这使得编写新品牌的代码更容易,也让旧代码更容易理解。

混合宏的便捷

那些@if语句看起来有几分难看,而且每个品牌都需要编写大串样式。我永远也记不住你是否需要将值用引号包裹起来。

把每个条件放入自己的混合宏中,我们就可以解决一切。这需要为每个品牌编写一个混合宏。

@mixin bobs-burgers { 
  @if $brand == 'bobs-burgers' { 
    @content; 
  } 
} 

@mixin paddys-pub { 
  @if $brand == 'paddys-pub' { 
    @content; 
  }
} 

@mixin stus-stews { 
  @if $brand == 'stus-stews' { 
    @content; 
  } 
} 

@mixin jurassic-fork { 
  @if $brand == 'jurassic-fork' { 
    @content; 
  } 
} 

通过这些混合宏,_hero. scss可以缩减到这样:

. hero { 
  // First, styles that all brands 
  // have in common. 
  // (The "shared stuff") 
  font-size: 2em; 
  font-weight: bold; 
  border: 1px solid; 

  // Next, brand-specific styles. 
  // (The "themed stuff") 
  @include bobs-burgers { 
    border-color: yellow; 
  } 
  @include paddys-pub { 
    border-color: green; 
  } 
  @include stus-stews { 
    border-color: blue; 
  } 
  @include jurassic-fork { 
    border-color: brown; 
  } 
} 

你看:我们从同一个源,得到了四个不同的主题文件。这些品牌样式对于开发者是易于审查和管理的。对于用户没有浪费一次下载和请求。人人都是赢家。

不仅仅是区分颜色,这个技巧还可以让我们有更多发挥的空间。让我们进一步推进:

. hero { 
  // First, styles that all brands 
  // have in common. 
  // (The "shared stuff") 
  font-size: 2em; 
  font-weight: bold; 
  border: 1px solid; 

  // Next, brand-specific styles. 
  // (The "themed stuff") 
  @include bobs-burgers { 
    border-color: yellow; 
  } 

  @include paddys-pub { 
    border-color: green; 
    background: url(/images/shamrock.png); 
  } 

  @include stus-stews { 
    border-color: blue; 
    &:hover, 
    &:focus { 
      // You can nest styles and even reference 
      // the parent from within this mixin! 
      background-color: blue; 
    }
  }

  @include jurassic-fork { 
    border-color: brown; 
    background: url(/images/dinosaur-footprints.png); 
  } 
} 

你可以尽自己喜欢的改变它。因为这些混合宏实质上是条件式的语法,你甚至可以嵌套额外的选择器或是父选择器。以这种方式使用主题混合宏,最终就会自然而然地变成工作流中的一部分。并且这个技巧远不止使用在定制个性化品牌主题上。我们为Structuring And Serving Styles For Older Browsers使用相同的技巧——改变变量并引入设计。你尽可以做一些奇怪的操作,比如输出一个内联样式表风格指南的样式表。去尝试吧。

警告

最大的警告是编译时间。因为要为每个主题构建一个完整的CSS文件,所以要花费更多时间编译样式。如果这对你来说是个问题,那么你可以试试libsass。它编译Sass比Ruby编译器更快,可能对你有所帮助。

另外,我写这篇文章的前提是假设合并所有的CSS比隔离主题更好。如果用户经常在品牌间切换,或者你的主题文件非常小,那么这就有些不合适了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

想挽留

暂无简介

0 文章
0 评论
20371 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文