一、组件最高类名
1个单词的类名
BS4的组件,以组件名单词作为最高的类名,比如警告条,最高的类名是alert
,又比如徽章,最高类名就是badge
。
也就是说,组件与布局是解耦的,不管你把这个组件用在什么地方,这个组件的基本形态首先就是这个样子,之后你想为项目进行个性化定制,那么你可以给最高层追加定制类。
2个单词的类名
下面的btn-toolbar
就是两个单词组成最高组件类名,反而子元素的类名有1个单词的btn
,这其中的奥妙,就看你怎么看待你的组件了。如果你的组件里面的主要元素是子元素,整个组件就是这些子元素的集合,那么就像btn-toolbar
一样就好了,如果是警告条这种肯定是单个使用的组件,那么最高类名就用一个单词就OK。
二、对最高层的外观附加类、功能附加类、工具类
外观附加类
比如警告条,BS4的做法是,最高层除了alert
,还会紧跟着一个alert-primary
或者其他类,也就是对alert
进行外观定制化,一个基本的alert
可以拓展出无数的附加类。这种类的写法是,把主类放前面,附加词放后面,用短横线链接。
alert-primary
强调的是语境,分为了主要的、次要的、危险的、成功的等等这些词,如果还要给一个“可收起的”属性,怎么办?BS4给出的方案是再加一个alert-dismissible
,这就是功能附加类。
再比如,徽章可以这么写Primary
,有2个附加类,badge-pill表示像胶囊一样的形状,跟后面的语境外观不是一回事,所以要另外摘出来定义。
再说一个特殊的栗子,这是包边的按钮,有带色边线,里面是白色背景填充。为什么不写成
呢?因为
btn-primary
主要特征是填充带色的背景,跟包边是冲突的两套东西,所以没办法配合,只能是另外单独定义一套btn-outline-xxx
系列。
还有一个特殊的栗子是active
类,它并不是独立的工具类,而是外观附加类,因为它都是用于.btn.active {...}
这样的形式,所以没必要写成btn-active
了。同理的还有disabled
等。
功能附加类
在最高层div身上,为了实现不同的目的,可以施加多个类,比如alert-warning
负责外观表现,alert-dismissible
负责功能(可收起的),还有其他功能的话,可以继续加。
Holy guacamole! You should check in on some of those fields below.
工具类
最后我们还可以看到fade show
,这是2个工具类,可以对任何元素起作用,效果一致,fade
是渐变动效果,show
表示当前是显示的状态。如果你能做出跟具体组件无关的通用的工具类,也可以继续追加到后面。
又如mb-0
类,它表示margin-bottom:0;
,这个类的意义是什么呢?因为BS的原则是,上下两个模块拉开间距,一律采用margin-bottom
,不要写任何的margin-top
,原因是间距折叠效应,所以比如一系列
,都统一只设置margin-bottom
的值就可以了。于是有一个问题就是,最后一个
可能不需要margin-bottom
,怎么办?给最后的
加个mb-0
类就好了。
三、使用者自己对最高层的外观附加类、功能附加类、工具类
自定义外观附加类
使用者使用BS4的时候,可以给最高层再加一个外观附加类,比如alert-xxx
,这个类的作用应该是,在alert
和alert-primary
基础上,再做外观修改,比如改一改字体大小,改一改行高,等等。这个xxx
可以是更高级的概念,比如模块名、页面名,甚至网站名:
- 如果利用模块名,比如新闻列表,那可以叫
alert-newslist
,意思是新闻列表里的警告条,就应该是这样子的。 - 如果利用页面名,比如页面是投票页,那就可以是
alert-poll
,意思是,用在投票页的警告条就得是我写的这样的长相。 - 如果利用网站名,比如你这是新浪的页面,可以干脆叫做
alert-sina
,也就是说,我们新浪的警告条,就应该是这个标准。
自定义功能附加类
写到这里的时候还没想出好的例子,先不写了。
自定义工具类
也没想出好的栗子,先不写了。
最终,最高层的类的样子应当是:“主类 外观类 自定义外观类 功能类 自定义功能类 工具类 自定义工具类”这样的顺序,就对了。
四、上下级类怎么写
下级专门定义一个类的情况
从BS4来看,比如警告条,警告条里面有能点击的链接,这样形成了上下级类,BS4的方案是:
This is a primary alert with an example link. Give it a click if you like.
就是说警告条里的链接,它的类的写法就应该是alert-link
。前面还是主类,后面加功能名称。
BS的原则是:能不级联就不级联,尽量只给最顶级标签加各种类,这样方便管理,而且,这些类定义的样式尽量是能继承的样式。所以,BS直接给alert-link
设样式,不写成级联形式。这样,alert-link
继承了祖先元素的一部分样式,自己又定义了一部分样式,这差不多就够用了,没必要写成.alert .alert-link
这样的声明。
下级不专门定义类的情况
看一个栗子:
Well done!
Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.
Whenever you need to, be sure to use margin utilities to keep things nice and tidy.
标签没有加任何样式,原因是BS4给全局
设置了统一的样式,从实践中,很可能你的组件需要跟全局不一样的行高,怎么办呢?应当定义一个类似于这样一个样式:
.alert-sina p {
line-height: 1.8;
}
这时候问题来了,为什么不给
加上alert-p
类?因为首先这个类好像BS官方类一样,容易混淆视听,其次,你这个组件的
的样式,虽然可能跟全局
的样式不一致,但总不至于同一个组件内的
与
互相样式都不一致吧?所以只要统一给组件内设置一个样式就够了。设置类的原则就是一定要尽量精简,也要尽量降低耦合。
接上面问题,为什么组件里面的就得加上 的用途比窄, 除了表示一段话,通常没别的作用,就难讲了,有各种用途,所以不可能统一样式,不可以写成 Card确实是BS4里面比较复杂的一个组件了,我们看一下: Some quick example text to build on the card title and make up the bulk of the card's content. 主类是 顶部的图片是 一条一条的项目,通常就是 上中下结构,上面提过,就是用 若没有上中下结构,而是分为主体和主体旁边的一些零碎,那么主体可以用 如果语义是菜单,通常用 看个栗子: 看个栗子: 可以把组件当做一个人体来看。比如眼睛,它虽然属于头部,但你并不用强调眼睛是“头部的眼睛”。虽然不用强调,但是眼睛还是会继承头部的特性,比如头部的海拔高,所以你眼睛的海拔也高。这就算是继承。栗子可能不太恰当,理解意思即可。 如果用sass来写css,不要沉迷于sass的级联写法,因为组件化的特征就是尽量不级联。sass里的级联,最多是2级连一起就够了。所以,请努力让级联扁平起来。 想给一个组件加样式,应当尽量放在最顶级类里,然后多利用CSS的继承,能在最高级类里面定义的,一定要在最高级类里定义,遇到不能继承的,再在下级类里另写样式。 这种标签,属于用的场合多,但意义简单,所以,要修改 的样式,不要给 身上放类,应该用 从dropdown的栗子可以看出,一个组件可以包含其他组件,这是允许的,其他组件的类名不要写成 容器名字一般就是header/body/footer这种。 即使是很底层的标签,类名也不要繁复,除非有必要,否则应当尽量短。 注意区分两个概念“模块”和“组件”。模块是什么?比如页面左侧导航,比如新闻列表,比如天气预报模块,等等。组件就好比螺丝,模块就好比各种型号的自行车,螺丝生产的时候有自己的工业标准,并不关心螺丝将来是用在哪个厂家的哪辆自行车上。所以,组件的标签上不要带模块名字,而是应该用级联写法,比如模块是评论框,那么模块最外层的类可以叫 有时候你会纠结模块的类名,比如评论区,到底类名应该是 比如BS里面有 由于JS的元素选择器查找id比查找其他的形式要快,所以给被选择的元素加上id是个好习惯。 另外,最好给id名的前面加上 比如你的页面有5个大模块,比如header、footer、main等等的,你除了可以用 可以有2种,一种是驼峰写法 一般不要用连接线写法,因为容易跟class混淆,而且id名可以直接拿来当js的window对象的属性,也就是 业界目前认为最正确的做法,是只给hack做注释,因为你不注释,我真的不好理解你这个hack是干嘛的。其他情况下,应当通过类名就可以让人明白这个类是干什么的。alert-link
呢?因为.alert a
的样子。三层及以上结构
Card title
card
没悬念。card-img-top
,为啥有个top
呢?因为还有一个类是card-img
。card-body
可以看出,如果你的一个组件有上中下三部分,你就可以用-top、-body、-bottom,也可以用-header、-body、-footer。这个元素一般是做容器用,设置简单的样式即可,一般不作为级联样式表的父元素。card-title
、card-text
单词都是表意的,很好理解不解释。除非为了避免歧义,否则card-title
不要写成card-body-title
,一共就2个单词连起来就完事。这就好比,你说“她的眼睛是蓝色的”,没有哪个神经病会说“她的脑袋上的眼睛是蓝色的”,因为眼睛只有一对,一定在她的脑袋上,所以不需要特意写出来。类名用词的惯例:
-item
了;-top
、-body
、-bottom
,也可以用-header
、-body
、-footer
;-inner
,旁边的零碎可以另外设定具体名字。-menu
包裹一系列的-item
。五、3个单词组成的类名
第3个单词作为修饰词的情况
dropdown-menu-right
是3个单词的类名,第三个单词right是修饰词。这跟BEM命名法是一致的。3个单词连起来才描述清楚一个类的情况
form-check-label
是3个单词组成的类,它的意思是form中的check容器中的label标签。通常有一个父元素叫form-check
。form-check-input
也是3个单词组成的类,它的意思是form中的check容器中的input标签。通常有一个父元素叫form-check
。总结
.xxx p {}
这种级联形式。反之,就最好在它身上放类。dropdown-xxx-xxx
,这样等于你把好容易解耦的样式又耦合起来了,应当直接定义一个xxx-xxx
类,然后用.dropdown .xxx-xxx {}
来定义样式。form-check-input
之所以长,是因为它专门用于,实在没办法简写成form-input
。comments
,它里面有几个组件,任何组件的类名都不要带comments字样。最后,用.comments .xxx {}
就搞定了样式。comment-section
还是comment
。说白了,如果下级有类名叫comment
,那么顶级类名叫comment-section
是可以的,如果一个个的comment
形成了list的感觉,顶级类也可以叫comment-list
,如果下级并没有一个类名叫comment
,那么顶级类名就可以直接叫comment
,应该是没问题的。所以,一切看情况而定,类名尽量简单。附录一:id什么时候用?怎么写?
锚链接定位
跳转到header
配合上实现锚链接。
用于让label操作控件。
当做JS的操作绑定元素
id="btnGroupDrop1"
和aria-labelledby="btnGroupDrop1"
:
js-
,这表示这个元素是一个js钩子。当做最大的模块名
id的写法
btnGroupAddon2
,一种是下划线写法btn_group_addon_2
,具体用哪种都可以,真心没有任何区别,所以项目内部统一一种即可。我个人偏向于下划线写法,因为我喜欢给变量名使用驼峰写法,这样的话两种写法在js中就可以一眼区分。window.btn_group_addon_2
就指向该元素,但是window.btn-group-addon-2
是非法的写法。附录二:注释什么时候写?