>웹 프론트엔드 >JS 튜토리얼 >BEM 구문에 대한 자세한 설명

BEM 구문에 대한 자세한 설명

php中世界最好的语言
php中世界最好的语言원래의
2018-03-19 10:01:583464검색

이번에는 BEM 구문에 대한 자세한 설명을 가져왔습니다. BEM 구문 사용 시 주의사항은 무엇인가요? 실제 사례를 살펴보겠습니다.

BEM은 블록, 요소, 수정자를 의미하며 Yandex 팀이 제안한 프런트엔드 명명 방법론입니다. 이 영리한 명명 방법을 사용하면 CSS 클래스가 다른 개발자에게 더욱 투명하고 의미 있게 됩니다. BEM 명명 규칙은 더 엄격하고 더 많은 정보를 포함하며 팀에서 시간이 많이 걸리는 대규모 프로젝트를 개발하는 데 사용됩니다.

내가 사용한 BEM 기반 명명 체계는 Nicolas Gallagher가 수정했다는 점에 유의하는 것이 중요합니다. 이 글에서 설명하는 네이밍 기법은 원래 BEM은 아니지만, 제가 선호하는 개선된 버전입니다. 실제 사용된 표기법에 관계없이 모두 동일한 BEM 원칙을 기반으로 합니다.

명명 규칙 패턴은 다음과 같습니다.

.block{}.blockelement{}.block--modifier{}
  • .block은 더 높은 수준의 추상화 또는 구성 요소를 나타냅니다. .block 代表了更高级别的抽象或组件。

  • .blockelement 代表.block的后代,用于形成一个完整的.block的整体。

  • .block--modifier代表.block的不同状态或不同版本。

之所以使用两个连字符和下划线而不是一个,是为了让你自己的块可以用单个连字符来界定,如:

.site-search{} /* 块 */.site-searchfield{} /* 元素 */.site-search--full{} /* 修饰符 */

BEM的关键是光凭名字就可以告诉其他开发者某个标记是用来干什么的。通过浏览HTML代码中的class属性,你就能够明白模块之间是如何关联的:有一些仅仅是组件,有一些则是这些组件的子孙或者是元素,还有一些是组件的其他形态或者是修饰符。我们用一个类比/模型来思考一下下面的这些元素是怎么关联的:

.person{}.personhand{}.person--female{}.person--femalehand{}.personhand--left{}

顶级块是‘person’,它拥有一些元素,如‘hand’。一个人也会有其他形态,比如女性,这种形态进而也会拥有它自己的元素。下面我们把他们写成‘常规’CSS:

.person{}.hand{}.female{}.female-hand{}.left-hand{}

这些‘常规’CSS都是有意义的,但是它们之间却有些脱节。就拿.female来说,是指女性人类还是某种雌性的动物?还有.hand,是在说一只钟表的指针(译注:英文中hand有指针的意思)?还是一只正在玩纸牌的手?使用BEM我们可以获得更多的描述和更加清晰的结构,单单通过我们代码中的命名就能知道元素之间的关联。BEM真是强大。

再来看一个之前用‘常规’方式命名的.site-search的例子:

<form class="site-search  full">
  <input type="text" class="field">
  <input type="Submit" value ="Search" class="button">
</form>

这些CSS类名真是太不精确了,并不能告诉我们足够的信息。尽管我们可以用它们来完成工作,但它们确实非常含糊不清。用BEM记号法就会是下面这个样子:

<form class="site-search  site-search--full">
  <input type="text" class="site-searchfield">
  <input type="Submit" value ="Search" class="site-searchbutton">
</form>

我们能清晰地看到有个叫.site-search的块,他内部是一个叫.site-searchfield的元素。并且.site-search还有另外一种形态叫.site-search--full

我们再来举个例子……

如果你熟悉OOCSS(面向对象CSS),那么你对media对象一定也不陌生。用BEM的方式,media对象就会是下面这个样子:

.media{}.mediaimg{}.mediaimg--rev{}.mediabody{}

从这种CSS的写法上我们就已经知道.mediaimg.mediabody一定是位于.media内部的,而且.mediaimg--rev.mediaimg.blockelement는 .block의 자손을 나타내며 전체적으로 완전한 .block을 형성하는 데 사용됩니다.

.block--modifier는 .block의 다양한 상태 또는 버전을 나타냅니다.


하이픈 2개와 밑줄 1개를 사용하는 이유는 다음과 같이 자신의 블록을 하나의 하이픈으로 구분할 수 있도록 하기 위함입니다.

<p class="media">
  <img src="logo.png" alt="Foo Corp logo" class="img-rev">
  <p class="body">
    <h3 class="alpha">Welcome to Foo Corp</h3>
    <p class="lede">Foo Corp is the best, seriously!</p>
  </p>
</p>
🎜BEM의 핵심은 이름입니다. 혼자서 특정 태그의 용도를 다른 개발자에게 알릴 수 있습니다. HTML 코드에서 클래스 속성을 탐색하면 모듈이 어떻게 관련되어 있는지 이해할 수 있습니다. 일부는 단지 구성 요소이고 일부는 이러한 구성 요소의 하위 요소이거나 요소이며 일부는 구성 요소 기호의 다른 형태 또는 수정입니다. 비유/모델을 사용하여 다음 요소가 어떻게 관련되어 있는지 생각해 보겠습니다. 🎜
<p class="media">
  <img src="logo.png" alt="Foo Corp logo" class="mediaimg--rev">
  <p class="mediabody">
    <h3 class="alpha">Welcome to Foo Corp</h3>
    <p class="lede">Foo Corp is the best, seriously!</p>
  </p>
</p>
🎜 최상위 블록은 '손'과 같은 요소를 보유하는 '사람'입니다. 사람은 여성의 형태와 같은 다른 형태도 갖고 있으며, 여성의 형태도 고유한 요소를 갖습니다. 아래에서는 이를 '일반' CSS로 작성합니다. 🎜
.caps{ text-transform:uppercase; }
🎜이 '일반' CSS는 모두 의미가 있지만 둘 사이에는 약간의 연결이 끊어져 있습니다. .female을(를) 예로 들어 보겠습니다. 이 단어는 인간 여성을 의미합니까, 아니면 일종의 암컷 동물을 의미합니까? 그리고 .hand는 시계바늘을 말하는 건가요?(hand는 영어로 손을 의미합니다.) 아니면 손으로 카드놀이를 하는 걸까요? BEM을 사용하면 더 많은 설명과 더 명확한 구조를 얻을 수 있으며, 코드의 이름 지정을 통해 요소 간의 관계를 알 수 있습니다. BEM은 정말 강력합니다. 🎜🎜'기존' 방식으로 명명된 .site-search의 또 다른 예를 살펴보겠습니다. 🎜
.site-logo{}
🎜이 CSS 클래스 이름은 정말 부정확하고 충분한 정보를 제공하지 않습니다. 우리가 그들과 함께 일을 끝낼 수는 있지만 그들은 정말 모호합니다. BEM 표기법을 사용하면 다음과 같습니다. 🎜
.header{}.headerlogo{}
🎜 .site-search라는 블록이 있고 그 안에 .site-searchfield 요소. 그리고 <code>.site-search에는 .site-search--full이라는 또 다른 형식이 있습니다. 🎜🎜다른 예를 들어보겠습니다...🎜🎜OOCSS에 익숙하다면(객체 지향 🎜CSS ), 그렇다면 미디어 객체에 대해 잘 알고 있어야 합니다. BEM을 사용하면 미디어 개체는 다음과 같습니다. 🎜
<p class="content">
  <h1 class="contentheadline">Lorem ipsum dolor...</h1>
</p>
🎜이 CSS 작성 방법을 통해 우리는 .mediaimg.mediabody에 위치해야 한다는 것을 이미 알고 있습니다. media는 내부이고 .mediaimg--rev.mediaimg의 또 다른 형식입니다. 🎜CSS 선택기🎜의 이름을 통해 위의 모든 정보를 얻을 수 있습니다. 🎜🎜다음 상황에서 BEM의 또 다른 이점은 다음과 같습니다. 🎜
.site-logo{}.site-logo--xmas{}
🎜위 코드만으로는 .media와 .alpha 두 클래스가 서로 어떻게 관련되어 있는지 전혀 이해하지 못합니까? 마찬가지로, .body와 .lede 사이, 또는 .img-rev🎜와 .media 사이의 관계가 무엇인지 알 방법이 없습니다. 이 HTML에서(미디어 객체를 잘 알지 않는 한) 우리는 이 구성 요소가 무엇으로 구성되어 있는지, 어떤 다른 형식을 가지고 있는지 알 수 없습니다. 이 코드를 BEM 방식으로 다시 작성하면: 🎜
<p class="media">
  <img src="logo.png" alt="Foo Corp logo" class="mediaimg--rev">
  <p class="mediabody">
    <h3 class="alpha">Welcome to Foo Corp</h3>
    <p class="lede">Foo Corp is the best, seriously!</p>
  </p>
</p>

我们立马就能明白.media是一个块,.mediaimg--rev是一个加了修饰符的.mediaimg的变体,它是属于.media的元素。而.mediabody是一个尚未被改变过的也是属于.media的元素。所有以上这些信息都通过它们的class名称就能明白,由此看来BEM确实非常实用。

丑极了!

通常人们会认为BEM这种写法难看。我敢说,如果你仅仅是因为这种代码看上去不怎么好看而羞于使用它,那么你将错失最重要的东西。除非使用BEM让代码增加了不必要的维护困难,或者这么做确实让代码更难读了,那么你在使用它之前就要三思而行了。但是,如果只是“看起来有点怪”而事实上是一种有效的手段,那么我们在开发之前当然应该充分考虑它。

是,BEM看上去确实怪怪的,但是它的好处远远超过它外观上的那点瑕疵。

BEM可能看上去有点滑稽,而且有可能导致我们输入更长的文本(大部分编辑器都有自动补全功能,而且gzip压缩将会让我们消除对文件体积的担忧),但是它依旧强大。

用还是不用BEM?

我在我的所有项目中都使用了BEM记号法,因为它的有效性已经被它自己一次又一次地证明。我也极力地建议别人使用BEM,因为它让所有东西之间的联系变得更加紧密,让团队甚至是你个人都能够更加容易地维护代码。

然而,当你真正使用BEM的时候,重要的是,请记住你没必要真的在每个地方都用上它。比如:

.caps{ text-transform:uppercase; }

这条CSS不属于任何一个BEM范畴,它仅仅只是一条单独的样式。

另一个没有使用BEM的例子是:

.site-logo{}

这是一个logo,我们可以把它写成BEM格式,像下面这样:

.header{}.headerlogo{}

但我们没必要这么做。使用BEM的诀窍是,你要知道什么时候哪些东西是应该写成BEM格式的。因为某些东西确实是位于一个块的内部,但这并不意味它就是BEM中所说的元素。这个例子中,网站logo完全是恰巧在.header的内部,它也有可能在侧边栏或是页脚里面。一个元素的范围可能开始于任何上下文,因此你要确定只在你需要用到BEM的地方你才使用它。再看一个例子:

<p class="content">
  <h1 class="contentheadline">Lorem ipsum dolor...</h1>
</p>

在这个例子里,我们也许仅仅只需要另一个class,可以叫它.headline;它的样式取决于它是如何被层叠的,因为它在.content的内部;或者它只是恰巧在.content的内部。如果它是后者(即恰巧在.content的内部,而不总是在)我们就不需要使用BEM。

然而,一切都有可能潜在地用到BEM。我们再来看一下.site-logo的例子,想象一下我们想要给网站增加一点圣诞节的气氛,所以我们想有一个圣诞版的logo。于是我们有了下面的代码:

.site-logo{}.site-logo--xmas{}

我们可以通过使用--修饰符来快速地为我们的代码构建另一个版本。

BEM最难的部分之一是明确作用域是从哪开始和到哪结束的,以及什么时候使用(不使用)它。随着接触的多了,有了经验积累,你慢慢就会知道怎么用,这些问题也不再是问题。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

在表单中button与input的区别

详谈css样式初始化 

js的自定义trim函数使用方法

위 내용은 BEM 구문에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.