博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何组织Html元素与如何进行CSS命名(上)
阅读量:5280 次
发布时间:2019-06-14

本文共 4380 字,大约阅读时间需要 14 分钟。

最近下决心整理一份对页面元素的组织规则和CSS的命名规则,因为深深感受到如果页面上元素太多,没有规则的命名和组织会让网页的维护性大打折扣。参考了几篇文章并且发散了一下,在这里和大家分享

 

本文同时也发表在另一个独立博客 

如何组织页面上的元素,或者说安排元素之间的关系势必会对css命名产生影响;css命名也是对元素关系的映射。BEM这个方法把元素分为三类,代指 Block , Element , Modifier 。

举个例子,通常我们会把页面分为header, body, footer部分,可能header部分里面又包括了logo, search, login模块。我们可以把Block理解为一个已经封装好了的组件,比如一个搜索模块(这里说的模块统统指一系列html元素,而非逻辑上的功能代码),它是相对于同级元素比较独立的(也相对于element元素)。

Element则是block中实现具体功能的部件,比如在搜索模块中最起码需要一个按钮(button),一个输入框(input),它和block的重要区别之一是,它没有block那么独立,一旦离开了上下文环境(比如它所在的block),它失去功能上的意义了。

这就非常灵活了,因为某一个block可以是它父元素或者其他元素的element,比如我们单独看搜索模块可能是一个独立的block,但是搜索模块通常又是放在页面的header中,那么搜索模块此时又成了header的element,而header又是一个更大的block。

接下来,BEM作者给出了CSS的具体命名规则希望是

  • 一个block必须有唯一的名字(class),比如

 

  • 而element的命名需要包括它所属的block的名字,并且以分隔符分隔开:

 

当然modifier就更好理解了,比如在一个tab模块中,我们需要突出某个tab,就需要给它添加一个的modifier作用的class,这里的modifier可以使特殊的状态,也可以是特殊的属性。就拿上面那个menu例子来说,我们想增大字体,想标识当前选中的菜单项,就可以添加

 

巧合的是,在写这篇文章的同时Smashing Magazine上同时发布了一篇谈BEM现在与将来的文章。主要对BEM过去的里程碑,每个里程碑所得出的一些方法论做了一些总结。比如说谈到BEM的起源其实是为了解决实际项目中css选择器冗长的问题,比如

.result .albums .album .buy {
float: left; padding:0.4em1em01.6em;}.result .albums .info i {
font-size:85%;}

 

有甚者

.b-foot div div div div div{
background-position:71%; background-image: url(../i/foot-5.png); } .b-foot div div div div div div{
background-position:87%; background-image: url(../i/foot-6.png); }

 

虽然现在看起来很可笑,但我觉得这却是实际中遇见的问题,必须承认我自己有时也陷入这样的怪圈

这篇文章谈为什么有BEM的来龙去脉更生动一些。有兴趣的同学可以看看。其实BEM是一系列的方法论,甚至还包括文件的命名的文件夹分类规则,XSL templates,甚至整个可供参考的框架。

因为在这里我只是作为一个组织html元素和css命名的其中一个方法,只做了简明的介绍和总结。

 

 

这个方法论将css分为5类,分别是

  • Base
  • Layout
  • Module
  • State
  • Theme(忽略这个先)

下面一一进行介绍

Base:

基本(base)规则即那些只使用元素选择器,后代选择等(从不涉及class或者id)的规则,比如

body, form {
margin:0; padding:0;}a:hover {
color:#03F; }

 

你可以理解为定义一些全局的css样式。通常这种工作也可以交给reset.css或者来完成

 

Layout Rules:

这里的布局(Layout)指页面上比较大块的区域,比如header,body, footer。而这里的layout rule也分为两类,一类是通过id定义的,比如

#header, #article, #footer {
width:960px; margin:auto; } #article {
border: solid #CCC; border-width:1px00; }

 

还有一类可能是在你用了一些css框架的情况下,比如

.container_12 .grid_6,.container_16 .grid_8 {
width:460px;}

作者建议与layout有关的css规则以l-开头,比如

.l-fixed#sidebar {
width:200px;}
Module Rules:

比如说一些登陆,搜索,文章,这样的元素组合我们就可以称之为module。对于这样一些元素的css命名,作者说就免了前缀,直接用模块名称好了,比如

.login {
width:200px;}

作者在这里强调的是,避免使用元素选择器。比如开始我们有这么一段html, 有这么一段样式

Folder Name
/* The Folder Module */.fld > span {
padding-left:20px; background: url(icon.png); }

 

问题是当我们的项目变得庞大,需要增加一个或者更多span标签时

Folder Name
(32 items)

这会就傻×了吧。所以最好是给标签添加上有语义的class名称,比如

Folder Name
(32 items)

还有一种情况,当我们在不同的section中使用了同一个module时,我们可能需要根据module所在的section来重新定义样式,比如

.pod {
width:100%;}.pod input[type=text]{
width:50%;}#sidebar .pod input[type=text] {
width:100%;}

 

但这样还是会产生问题,会让css变得没有规则和难以维护,所以作者建议添加一个子模块css(Subclassing Modules),比如这么做

...
...
.pod {
width:100%;}.pod input[type=text]{
width:50%;}.pod-constrained input[type=text]{
width:100%;}.pod-callout {
width:200px;}.pod-callout input[type=text]{
width:180px;}
State Rules

state 与之前的modifier概念类似,这种类型的class只起一些修饰作用。并且作者建议使用is-开头,比如

 

要注意它和之前sub-module的区别

  • state规则给layout或者module用都行
  • state规则通常由javascript有关(比如错误,高亮,是否折叠),而sub-module是静态不能随意修改的。只是为了区分模块之间的区别

在这个方法论的文章中,我觉得最有价值的一篇是谈到css的可访问性的。首先作者给出的两条建议是

  • css不应该依赖DOM树的结构
  • css选择器不宜太深

假如我们有这么一段css

#sidebar div {
border:1px solid #333; } #sidebar div h3 {
margin-top:5px; } #sidebar div ul {
margin-bottom:5px; }

 

这段css中的div可以看做一个组件,是由h3和ul组成的。如果我们想把这个组件又放在footer中怎么办,看下面这段代码怎么样

#sidebar div, #footer div {
border:1px solid #333; } #sidebar div h3, #footer div h3 {
margin-top:5px; } #sidebar div ul, #footer div ul {
margin-bottom:5px; }

 

代码这么冗余的原因就是因为它与dom联系的太紧密,不如把这层依赖关系去掉,给它加上一个独立的class

.pod {
border:1px solid #333;}.pod > h3 {
margin-top:5px;}.pod > ul {
margin-bottom:5px;}

 

我们试图在可维护性,性能,和可读性三者之间保持平衡,虽然css选择器具有一定深度意味着更少的class,但是它增加了可维护性和可读性。除非你压根就不想使用class。

下一期最后看看高手Nicolas的方法论。并且结合淘宝和人人的css规则看看实际的一些应用情况。

转载于:https://www.cnblogs.com/hh54188/archive/2013/03/14/2958617.html

你可能感兴趣的文章
Java 多线程编程
查看>>
Java 数组实例
查看>>
mysql启动过程
查看>>
2017前端面试题总结
查看>>
SWIFT国际资金清算系统
查看>>
站立会议第四天
查看>>
利用AMPScript获取Uber用户数据的访问权限
查看>>
生成随机数的模板
查看>>
Mysql 数据库操作
查看>>
转:linux终端常用快捷键
查看>>
UVa 11059 最大乘积
查看>>
数组分割问题求两个子数组的和差值的小
查看>>
composer 报 zlib_decode(): data error
查看>>
hdu 3938 并查集
查看>>
《深入分析Java Web技术内幕》读书笔记之JVM内存管理
查看>>
python之GIL release (I/O open(file) socket time.sleep)
查看>>
软件开发与模型
查看>>
161017、SQL必备知识点
查看>>
kill新号专题
查看>>
MVC学习系列——Model验证扩展
查看>>