less和bem
在本教程中,我们将学习如何使用PostCSS来使BEM / SUIT样式CSS的开发更轻松,更高效。
这两种方法为类制定了命名约定,这使您更容易使样式紧密地面向函数,并帮助其他开发人员仅通过命名方式来识别各种类的目的。
BEM是Yandex创建的这种类命名方法的先驱。 SUIT方法论是一种基于BEM的方法,但Nicholas Gallagher进行了一些调整和补充。 SUIT可以完成BEM的所有工作,但对许多用户而言,它被认为是一项增强。
使用这些方法肯定有助于产生更好的,结构更好CSS。 但是,棘手的部分是,手动键入此结构所需的类名可能会很麻烦,并且跟踪类之间的相互关系可能会让人有些头疼。
Malte-Maurice Dreyer的postcss-bem插件通过快捷方式和嵌套的组合缓解了这些问题,在学习本教程时,您将学到如何使用它们。
但是首先,让我们快速了解BEM和SUIT方法,以确保您清楚了解使用postcss-bem插件的好处以及使用方式。
BEM上的快速入门
块
在BEM 块中是设计的高层块; 网站的组成部分。 一个块应该是您网站中与其他块无关的部分,并且理论上可以放置在布局中的任何位置,甚至可以嵌套在另一个块中。
例如,您网站上的搜索表单“块”可能使用.search-form
类。
元件
BEM中的元素是块内的子部分。 通过在父块名称后附加两个下划线__
分隔符和元素名称来表示它们。
例如,搜索表单可能包含标题,文本字段和提交按钮元素。 它们的类名分别是.search-form__heading
, .search-form__text-field
和.search-form__submit-button
。
修饰符
修饰符应用于块或元素,以表示其表示形式的更改或状态的更改。 通过在所讨论的块或元素上添加分隔符和修饰符名称来表示它们。
BEM官方网站文档指出修饰符分隔符应为单个下划线_
。 但是,哈里·罗伯茨(Harry Roberts)CSS准则“类似于BEM”的约定使用了两个破折号--
可能比正式的BEM约定更广泛地被使用和知道。
例如,在设计中,您可能希望呈现与常规搜索表单不同的高级搜索表单,从而创建修饰符类.search-form_advanced
(官方BEM)或.search-form_advanced
.search-form--advanced
(类似于BEM)。
在另一个示例中,您可能想要由于状态变化而更改表单的外观,例如是否刚刚提交了无效内容,因此创建了修饰符.search-form_invalid
(官方BEM)或.search-form_invalid
.search-form--invalid
(类似于BEM)。
SUIT快速入门
SUIT包含实用程序和组件 。 在组件可以有修饰语 , 后代和国家 。
SUIT结合使用了pascal大小写(PascalCase),骆驼形大小写(camelCase)和破折号。 它的约定对BEM中可能出现的有时会引起混淆的破折号和下划线进行了限制。 例如,BEM类.search-form__text-field
在SUIT中将是.SearchForm-textField
。
效用
实用程序处理结构和位置样式,并且以可以将其应用于组件中任何位置的方式编写。 它们以u-
为前缀,并以驼峰形式书写。 例如, .u-clearFix
。
零件
SUIT中的组件代替了BEM中的块 。 组件始终以Pascal大小写编写,并且只是SUIT中使用Pascal大小写的一部分,因此易于识别。 例如, .SearchForm
。
组件命名空间
组件可以选择以名称空间和单破折号nmsp-
作为前缀,以确保避免冲突,例如.mine-SearchForm
。
后裔
SUIT中的后代将替换BEM中的元素 。 它使用一个破折号-
并以驼峰形式编写。 例如.SearchForm-heading
, .SearchForm-textField
和.SearchForm-submitButto
。
修饰符
SUIT和BEM一样使用修饰符 ,但是它们的作用受到更严格的控制。 SUIT修饰符通常仅直接应用于组件,而不应用于后代。 它也不应该用来表示状态更改,因为SUIT具有专门的状态命名约定。
修饰语以驼峰书写,前面有两个破折号--
。 例如, .SearchForm--advanced
。
州
状态类可用于反映对组件状态的更改。 这样可以将它们与修改器区分开来,后者反映了组件基本外观的修改,而与状态无关。 如有必要,也可以将状态应用于后代。
州以is-
,并以驼峰式书写。 它们也总是被写为相邻的类。 例如.SearchForm.is-invalid
。
设置您的项目
现在您已经掌握了BEM和SUIT的基本知识,是时候设置您的项目了。
根据您的喜好,您将需要使用Gulp或Grunt的空项目。 如果您还不喜欢其中一种,那么我建议您使用Gulp,因为您将需要更少的代码来达到相同的目的,因此您应该发现使用起来更加简单。
您可以在之前的教程中了解如何为PostCSS设置Gulp或Grunt项目
分别。
但是,如果您不想从头开始手动设置项目,则可以下载本教程附带的源文件 ,并将提供的Gulp或Grunt入门项目提取到一个空项目文件夹中。 然后在终端或命令提示符指向文件夹的情况下,运行命令npm install
。
安装插件
接下来,您需要安装postcss-bem插件。 我们还将安装一个可以很好地与之配合使用的插件: postcss-nested 。
无论您使用的是Gulp还是Grunt,请在项目文件夹中运行以下命令:
npm install postcss-bem postcss-nested --save-dev
现在,我们准备将插件加载到您的项目中。
通过Gulp加载插件
如果您使用的是Gulp,请将这些变量添加到文件中已存在的变量下:
var bem = require('postcss-bem');
var nested = require('postcss-nested');
现在,将每个这些新变量名称添加到processors
数组中:
var processors = [
bem,
nested
];
通过运行gulp css
命令,然后检查项目的“目标”文件夹中是否已出现新的“ style.css”文件,来快速测试一切是否正常。
通过Grunt加载插件
如果您使用的是Grunt,请将嵌套在options
对象下的processors
对象更新为以下内容:
processors: [
require('postcss-bem')(),
require('postcss-nested')()
]
通过运行grunt postcss
命令,然后检查项目的“ dest”文件夹中是否出现了新的“ style.css”文件,来快速测试一切是否正常。
好的,您准备好了。 让我们学习如何生成BEM和SUIT结构。
BEM和SUIT与postcss-bem
手动编写代码时,BEM或SUIT结构可能会变得有些笨拙,因为在类名中连续重复相同的标识符可能会很麻烦,并且跟踪哪些元素和后代属于哪些块和组件会造成混乱。
但是,当您使用postcss-bem时,一眼就可以理解代码的结构,并且几乎不存在重复键入类名的麻烦。
生成SUIT结构
尽管其名称,默认情况下postcss-bem将根据SUIT语法而不是BEM输出。 您可以使用BEM语法输出,这将在后面介绍,但是该插件主要用于输出SUIT,因此,出于这个原因,我们将从SUIT语法开始。
生成组件
要创建组件,请使用语法@component ComponentName {...}
。
通过在您的“ src / style.css”文件中添加SearchForm
组件来进行尝试:
@component SearchForm {
padding: 0;
margin: 0;
}
编译它,您得到的代码应为:
.SearchForm {
padding: 0;
margin: 0;
}
产生后代
要创建后代,请使用嵌套在父组件内部的语法@descendent descName {...}
。
在SearchForm
组件内添加一个名为textField
的后代,如下所示:
@component SearchForm {
padding: 0;
margin: 0;
/* Nest descendent under component */
@descendent textField {
border: 1px solid #ccc;
}
}
编译之后,您现在应该看到:
.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
生成修饰符
使用语法@modifier name {...}
为组件创建一个修饰符,嵌套在其影响的组件内部。 修饰符通常应放置在组件的顶部,在所有子代和状态的上方。
使用以下代码向您的SearchForm
组件添加一个名为advanced
的修饰符:
@component SearchForm {
padding: 0;
margin: 0;
/* Typically, place modifiers above descendents */
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
}
}
重新编译代码,您应该看到新的advanced
组件修饰符:
.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm--advanced {
padding: 1rem;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
产生状态
状态是通过语法@when name {...}
创建的,并且可以嵌套在组件或后代中。
使用以下代码向您的textField
后代添加一个名为invalid
的状态:
@component SearchForm {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
/* This creates a state for the textField descendant */
@when invalid {
border: 1px solid red;
}
}
}
现在,当您编译代码时,您将看到它包含新的invalid
状态:
.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm--advanced {
padding: 1rem;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
.SearchForm-textField.is-invalid {
border: 1px solid red;
}
命名空间组件
您可以使用@component-namespace name {...}
及其嵌套的所有后代,修饰符和状态@component-namespace name {...}
。 如果愿意,可以使用此名称空间包装整个样式表,以便所有类都自动为其添加前缀。
通过使用@component-namespace mine {...}
包装到目前为止的所有代码来尝试一下:
@component-namespace mine {
@component SearchForm {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
@when invalid {
border: 1px solid red;
}
}
}
}
编译后,您将看到现在您的每个组件都以mine-
为前缀:
.mine-SearchForm {
padding: 0;
margin: 0;
}
.mine-SearchForm--advanced {
padding: 1rem;
}
.mine-SearchForm-textField {
border: 1px solid #ccc;
}
.mine-SearchForm-textField.is-invalid {
border: 1px solid red;
}
生成实用程序
使用语法@utility utilityName {...}
创建实用程序。 您会记得,在设置项目时,已安装了postcss-nested插件。 我们这样做是因为与postcss-bem一起使用非常方便,正如您在本例中看到的那样,我们创建了clearFix
实用程序:
@utility clearFix {
&:before, &:after {
content: "";
display: table;
}
&:after {
clear: both;
}
/* If supporting IE 6/7 */
*zoom: 1;
}
添加以上代码后,进行编译,您将看到已创建此新实用程序:
.u-clearFix {
/* If supporting IE 6/7 */
zoom: 1;
}
.u-clearFix:before, .u-clearFix:after {
content: "";
display: table;
}
.u-clearFix:after {
clear: both;
}
生成BEM结构
要激活postcss-bem中的BEM语法输出,请在Gulpfile或Gruntfile中传递选项style: 'bem'
,如下所示:
/* Gulpfile */
var processors = [
bem({style: 'bem'}),
nested
];
/* Gruntfile */
processors: [
require('postcss-bem')({style: 'bem'}),
require('postcss-nested')()
]
默认情况下,postcss-bem将使用官方分隔符将单个下划线_
用作修饰符。 如果对项目很重要,则使用更常见的两个破折号--
而是可以通过转到项目的node_modules / postcss-bem文件夹,打开index.js来更改postcss-bem插件的配置。 ,找到第15行并进行以下更改:
bem: {
separators: {
namespace: '--',
descendent: '__',
modifier: '_'
}
}
...对此:
bem: {
separators: {
namespace: '_',
descendent: '__',
modifier: '--'
}
}
生成块
因为BEM中的“块”与SUIT中的“组件”相关,所以使用语法@component block-name {...}
来生成块。
要创建search-form
块,请添加以下代码:
@component search-form {
padding: 0;
margin: 0;
}
然后编译,您应该看到:
.search-form {
padding: 0;
margin: 0;
}
生成元素
由于BEM中的“元素”与SUIT中的“后裔”相关,因此可以使用嵌套在父块中的@descendent element-name {...}
语法来创建它们。
要创建text-field
元素,请添加以下内容:
@component search-form {
padding: 0;
margin: 0;
@descendent text-field {
border: 1px solid #ccc;
}
}
在编译时,您将看到已创建新元素:
.search-form {
padding: 0;
margin: 0;
}
.search-form__text-field {
border: 1px solid #ccc;
}
生成修饰符
即使BEM允许对块和元素都使用修饰符,但postcss-bem插件仅在嵌套在块而不是元素内部时才处理它们,这是由于修饰符的SUIT约定应用于组件而不是后代。 可以使用嵌套在其父块内的语法@modifier name {...}
来创建它们。
将advanced
修饰符添加到search-form
组件中,如下所示:
@component search-form {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent text-field {
border: 1px solid #ccc;
}
}
在编译时将产生:
.search-form {
padding: 0;
margin: 0;
}
.search-form_advanced {
padding: 1rem;
}
.search-form__text-field {
border: 1px solid #ccc;
}
没有实用程序或状态,但有命名空间
在BEM模式下,由于BEM不使用实用程序或状态,因此@utility
和@when
语法不会编译成任何东西。
但是,即使它通常不是BEM的一部分,如果您希望在BEM样式表中使用@component-namespace
语法,它仍然可以使用。 它将为您的类添加name--
:
.mine--search-form {
padding: 0;
margin: 0;
}
.mine--search-form_advanced {
padding: 1rem;
}
.mine--search-form__text-field {
border: 1px solid #ccc;
}
回顾一下
现在,您了解了如何缩短BEM和SUIT开发的步伐,并使整个过程更加轻松。 让我们总结一下我们涵盖的所有内容:
- BEM和SUIT是类命名约定,有助于使样式表保持功能性和组织性,并帮助其他开发人员认识各种类的目的。
- SUIT就像BEM,但添加了一些额外功能并进行了调整
- postcss-bem插件提供了用于创建BEM和SUIT类的快捷方式,例如
@component
,@descendent
,@modifier
等。 - 该插件还允许以一种有用的方式嵌套代码,例如,修饰符嵌套在组件内部或它们所修改的块中。
- 可以通过使用
@component-namespace name {...}
包装类来自动完成@component-namespace name {...}
在下一个教程中
接下来,我们将探讨利用PostCSS的另一种很棒的方法,那就是将速记和快捷方式的工具包组合在一起,以使我们的编码更快,更高效。
我会在那里见你!
翻译自: https://webdesign.tutsplus.com/tutorials/using-postcss-with-bem-and-suit-methodologies--cms-24592
less和bem