下面这篇是 Jon Yablonski 的客座文章。Jon 将会给我们展示一个如何处理标记以便让一个组件变得相当通用的例子。它按原样工作,并且有一个制作变种的标准化方式(添加一个类名)来让更改设计以适应场景。

媒体模式
用精确到像素的Photoshop文件构建固定宽度网页的时代过去了。为了制作能巧妙地适应任何屏幕尺寸的弹性布局,我们的工作流程经历了改变,变得更加可迭代和敏捷。我们开始认识到模块化的重要性,以及它如何促进在浏览器保持灵活所需的适应性。作为一名设计师和前端开发,这种适应性对我如何处理Web项目是不可或缺的。我发现自己在浏览器上所做的设计决定比在设计稿上的更多,为了支持这种工作流程,我需要这种构建可轻松扩展的用户界面模块的能力。
可扩展模块
我非常看重的是可扩展性,这是一种系统设计原则,在该原则下的实现会考虑到未来的成长性。可扩展性的中心思想是在改变的同时,尽可能不影响现有系统。对前端开发来说,这意味着要构建可轻松扩展以适应用户界面需求的模块变更,同时保留模块下面的基础。最终的结果就是更少的代码臃肿、更少的因一次性解决方案导致的代码库碎片化以及更容易维护的代码。
为可扩展性而构建
为了保证组件和模式在结构上的一致性,有必要用一种可重用和可预测的方式来构建它们。以下是我采用的基本步骤:
步骤一:确定模块类型
第一步是确认我们要做的模块类型,可以归为两种类别之一:组件或模式。组件是一个独立的、模块化的对象,它没有子元素,但可以有改变外观的修饰符状态(例如:按钮,消息,缩略图)。而模式是拥有子元素的对象(这些子元素也可以是独立的组件),所有子元素都受父对象的影响(例如:header,header logo,header导航)。组件和模式都有改变自身外观或结构的修饰符状态。
步骤二:定义模块的基础
下一步就是找到组件或模式的所有变种都会继承的基本规则。 这些规则应当相对较小,并且保留给很少改变的属性。通常,我发现这些规则是诸如margin、padding、position和display这些属性。
这篇文章的所有代码示例都是用 BEM (block, element, modifier) 命名方法。BEM有诸多好处,但或许我最喜欢的是这点:我只要看标记的名字就知道它是做什么的。如果你想了解这种命名方法的更多信息,我推荐阅读 这篇文章。
HTML 基础
``CSS 基础
.block {
position: relative;
margin: 0 0 1em;
}步骤三:定义公共元素
如果你要构建组件,你可以跳过这一步直接到下一步;但如果你要构建一个会包含子元素的模式,那么下一步就是定义公共元素。这些元素跟父级区块是主题相关的(不过也可作为独立的组件存在于模式之外)。
HTML 公共元素
class="block">
class="block__element">…
class="block__another-element">…
CSS
.block__element {
padding: 1em;
background: white;
border: 1px solid black;
}
.block__another-element {
position: absolute;
top: 0;
right: 0;
}步骤四:用修饰符扩展
最后一步是用修饰符扩展你的组件/模式。修饰符本质上是扩展基础区域和子元素的变种,你可以根据需要创建它们。
HTML修饰符类示例
class="block block—modifier">
class="block__element">…
class="block__another-element">…
CSS修饰符示例
.block—modifier {
border-top: 3px solid red;
}
.block—modifier .block__element {
background: grey;
}例子
既然我们已经看过构建可扩展组件和模式的基本步骤,是时候看些例子了。我们用一个相对简单的组件开始,看看如何扩展它以适应各种不同应用场景。然后再看一个稍微复杂一点的模式。
关于组件
下面是几个公共组件连同变种的一个演示。每个组件由一个父区块和一个扩展该区块的修饰符组成。这允许快速创建各种变种,为你快速迭代和适应任何用户环境提供了灵活性。
公共组件示例
查看 Jon Yablonski (@jonyablonski) 在 CodePen上的代码示例公共可扩展组件。
组件天然应该相对简单,因为它们不包含子元素。现在,让我们看一个稍微复杂的东西。
关于模式
媒体模式是一个由媒体元素(可以是图片或视频)和相关内容(通常是文本形式)组成的对象。你可能对媒体模式的一个变种比较熟悉,就是 ‘media object’ 或 ‘flag object’,我们也会谈及一些。这种模式是关于在构建时考虑可扩展性是如何提供无限灵活性的绝佳范例。
媒体默认模式
我们会以默认模式开始,或者它是如何不带修饰符展示的。为了提供更多的语义信息,我在此通过利用一个``标签做了一些假设。但是你可以改成任何你想要的标签。我们的媒体模式的核心样式如下:
一个弹性容器,它的子元素不会换行
一点边距
这些是所有媒体模式都会继承的样式。另外,每个媒体模式都包含一个媒体项目(在这里是一张图片)和由标题和定义列表组成的媒体主体。
查看 Jon Yablonski @jonyablonski 在 CodePen上的代码示例Default Media Pattern 。
媒体卡片模型Media Card Pattern
虽然在一些情况下,媒体模式的默认变种已经足够了,但是存在其他情况,你需要彻底改变它的外观。下一步就是开始确认允许我们的模式适应各种情况的变化。让我们以跟默认外观区别不大的一个变种开始——卡片模式。前提是只需极少地改动标记,我们通过简单地添加一个修饰符类到父级区块上去就可以改变模式的外观。
查看 Jon Yablonski (@jonyablonski) 在 CodePen上的代码 Media Card Pattern
媒体对象模式
假设后来我发现我需要一种模式,如果有足够的空间,图片和文本并排显示。这是一个众所周知的“媒体对象”模式。为了创建它,我们只要扩展已有的媒体模式以最小化冗余代码。
查看 Jon Yablonski (@jonyablonski) 在 CodePen上的代码 Media Object Pattern 。
媒体板条
让我们更进一步,看一个真正经得起测试的变种。到目前为止我们定义的变种都能很好地适应所有的设计需求,但我需要一个影响更大的。让我们创建一个变种,它撑开整个窗口的宽度,body占一半,图片占另一半。除此之外,我想确保body内容跟页面上的其他内容对齐。我们把它叫做“媒体板条”。
查看Jon Yablonski (@jonyablonski) 在 CodePen上的代码 Media Slat Pattern 。
现在我们有几种媒体模式的变种:默认变种,卡片式变种,对象变种,以及最后的板条变种。这些变种在不同环境下都很有用,并且它们确保使用了相同的基础代码!它的好处在于,对一个模式的任何改动都会影响所有模式,所以每个模式实例会保持同步和一致。
总结
我们谈到了为什么在构建界面时可扩展组件和模式更好,主要集中在灵活性和可维护性。为了演示它,我们谈到了创建可扩展组件涉及的步骤。用这种方式构建界面的好处会立即变得明显,因为你会花更少的时间在意外的设计变更导致的重构上。另外,构成这些组件的样式也变得更容易维护。