对Bootstrap 4 CSS组件架构和命名规则的学习

2017-12-08  本文已影响444人  microkof

一、组件最高类名

1个单词的类名

BS4的组件,以组件名单词作为最高的类名,比如警告条,最高的类名是alert,又比如徽章,最高类名就是badge

也就是说,组件与布局是解耦的,不管你把这个组件用在什么地方,这个组件的基本形态首先就是这个样子,之后你想为项目进行个性化定制,那么你可以给最高层追加定制类。

2个单词的类名

下面的btn-toolbar就是两个单词组成最高组件类名,反而子元素的类名有1个单词的btn,这其中的奥妙,就看你怎么看待你的组件了。如果你的组件里面的主要元素是子元素,整个组件就是这些子元素的集合,那么就像btn-toolbar一样就好了,如果是警告条这种肯定是单个使用的组件,那么最高类名就用一个单词就OK。

<div class="btn-toolbar mb-3" role="toolbar" aria-label="Toolbar with button groups">
  <div class="btn-group mr-2" role="group" aria-label="First group">
    <button type="button" class="btn btn-secondary">1</button>
    <button type="button" class="btn btn-secondary">2</button>
    <button type="button" class="btn btn-secondary">3</button>
    <button type="button" class="btn btn-secondary">4</button>
  </div>
  <div class="input-group">
    <span class="input-group-addon" id="btnGroupAddon">@</span>
    <input type="text" class="form-control" placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon">
  </div>
</div>

二、对最高层的外观附加类、功能附加类、工具类

外观附加类

比如警告条,BS4的做法是,最高层除了alert,还会紧跟着一个alert-primary或者其他类,也就是对alert进行外观定制化,一个基本的alert可以拓展出无数的附加类。这种类的写法是,把主类放前面,附加词放后面,用短横线链接。

alert-primary强调的是语境,分为了主要的、次要的、危险的、成功的等等这些词,如果还要给一个“可收起的”属性,怎么办?BS4给出的方案是再加一个alert-dismissible,这就是功能附加类。

再比如,徽章可以这么写<span class="badge badge-pill badge-primary">Primary</span>,有2个附加类,badge-pill表示像胶囊一样的形状,跟后面的语境外观不是一回事,所以要另外摘出来定义。

再说一个特殊的栗子<button type="button" class="btn btn-outline-primary">Primary</button>,这是包边的按钮,有带色边线,里面是白色背景填充。为什么不写成<button type="button" class="btn btn-outline btn-primary">Primary</button>呢?因为btn-primary主要特征是填充带色的背景,跟包边是冲突的两套东西,所以没办法配合,只能是另外单独定义一套btn-outline-xxx系列。

还有一个特殊的栗子是active类,它并不是独立的工具类,而是外观附加类,因为它都是用于.btn.active {...}这样的形式,所以没必要写成btn-active了。同理的还有disabled等。

功能附加类

在最高层div身上,为了实现不同的目的,可以施加多个类,比如alert-warning负责外观表现,alert-dismissible负责功能(可收起的),还有其他功能的话,可以继续加。

<div class="alert alert-warning alert-dismissible fade show" role="alert">
  <strong>Holy guacamole!</strong> You should check in on some of those fields below.
  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

工具类

最后我们还可以看到fade show,这是2个工具类,可以对任何元素起作用,效果一致,fade是渐变动效果,show表示当前是显示的状态。如果你能做出跟具体组件无关的通用的工具类,也可以继续追加到后面。

又如mb-0类,它表示margin-bottom:0;,这个类的意义是什么呢?因为BS的原则是,上下两个模块拉开间距,一律采用margin-bottom,不要写任何的margin-top,原因是间距折叠效应,所以比如一系列<p>,都统一只设置margin-bottom的值就可以了。于是有一个问题就是,最后一个<p>可能不需要margin-bottom,怎么办?给最后的<p>加个mb-0类就好了。

三、使用者自己对最高层的外观附加类、功能附加类、工具类

自定义外观附加类

使用者使用BS4的时候,可以给最高层再加一个外观附加类,比如alert-xxx,这个类的作用应该是,在alertalert-primary基础上,再做外观修改,比如改一改字体大小,改一改行高,等等。这个xxx可以是更高级的概念,比如模块名、页面名,甚至网站名:

自定义功能附加类

写到这里的时候还没想出好的例子,先不写了。

自定义工具类

也没想出好的栗子,先不写了。

最终,最高层的类的样子应当是:“主类 外观类 自定义外观类 功能类 自定义功能类 工具类 自定义工具类”这样的顺序,就对了。

四、上下级类怎么写

下级专门定义一个类的情况

从BS4来看,比如警告条,警告条里面有能点击的链接,这样形成了上下级类,BS4的方案是:

<div class="alert alert-primary" role="alert">
  This is a primary alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
</div>

就是说警告条里的链接,它的类的写法就应该是alert-link。前面还是主类,后面加功能名称。

BS的原则是:能不级联就不级联,尽量只给最顶级标签加各种类,这样方便管理,而且,这些类定义的样式尽量是能继承的样式。所以,BS直接给alert-link设样式,不写成级联形式。这样,alert-link继承了祖先元素的一部分样式,自己又定义了一部分样式,这差不多就够用了,没必要写成.alert .alert-link这样的声明。

下级不专门定义类的情况

看一个栗子:

<div class="alert alert-success" role="alert">
  <h4 class="alert-heading">Well done!</h4>
  <p>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.</p>
  <hr>
  <p class="mb-0">Whenever you need to, be sure to use margin utilities to keep things nice and tidy.</p>
</div>

<p>标签没有加任何样式,原因是BS4给全局<p>设置了统一的样式,从实践中,很可能你的组件需要跟全局不一样的行高,怎么办呢?应当定义一个类似于这样一个样式:

.alert-sina p {
    line-height: 1.8;
}

这时候问题来了,为什么不给<p>加上alert-p类?因为首先这个类好像BS官方类一样,容易混淆视听,其次,你这个组件的<p>的样式,虽然可能跟全局<p>的样式不一致,但总不至于同一个组件内的<p>与<p>互相样式都不一致吧?所以只要统一给组件内设置一个样式就够了。设置类的原则就是一定要尽量精简,也要尽量降低耦合。

接上面问题,为什么组件里面的<a>就得加上alert-link呢?因为<p>的用途比<a>窄,<p>除了表示一段话,通常没别的作用,<a>就难讲了,有各种用途,所以<a>不可能统一样式,不可以写成.alert a的样子。

三层及以上结构

Card确实是BS4里面比较复杂的一个组件了,我们看一下:

<div class="card" style="width: 20rem;">
  <img class="card-img-top" src="..." alt="Card image cap">
  <div class="card-body">
    <h4 class="card-title">Card title</h4>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
    <a href="#" class="btn btn-primary">Go somewhere</a>
  </div>
</div>

主类是card没悬念。

顶部的图片是card-img-top,为啥有个top呢?因为还有一个类是card-img

card-body可以看出,如果你的一个组件有上中下三部分,你就可以用-top、-body、-bottom,也可以用-header、-body、-footer。这个元素一般是做容器用,设置简单的样式即可,一般不作为级联样式表的父元素。

card-titlecard-text单词都是表意的,很好理解不解释。除非为了避免歧义,否则card-title不要写成card-body-title,一共就2个单词连起来就完事。这就好比,你说“她的眼睛是蓝色的”,没有哪个神经病会说“她的脑袋上的眼睛是蓝色的”,因为眼睛只有一对,一定在她的脑袋上,所以不需要特意写出来。

类名用词的惯例:

五、3个单词组成的类名

第3个单词作为修饰词的情况

看个栗子:

<div class="btn-group">
  <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    This dropdown's menu is right-aligned
  </button>
  <div class="dropdown-menu dropdown-menu-right">
    <button class="dropdown-item" type="button">Action</button>
    <button class="dropdown-item" type="button">Another action</button>
    <button class="dropdown-item" type="button">Something else here</button>
  </div>
</div>

dropdown-menu-right是3个单词的类名,第三个单词right是修饰词。这跟BEM命名法是一致的。

3个单词连起来才描述清楚一个类的情况

看个栗子:

<form class="dropdown-menu p-4">
  <div class="form-group">
    <label for="exampleDropdownFormEmail2">Email address</label>
    <input type="email" class="form-control" id="exampleDropdownFormEmail2" placeholder="email@example.com">
  </div>
  <div class="form-group">
    <label for="exampleDropdownFormPassword2">Password</label>
    <input type="password" class="form-control" id="exampleDropdownFormPassword2" placeholder="Password">
  </div>
  <div class="form-check">
    <label class="form-check-label">
      <input type="checkbox" class="form-check-input">
      Remember me
    </label>
  </div>
  <button type="submit" class="btn btn-primary">Sign in</button>
</form>

form-check-label是3个单词组成的类,它的意思是form中的check容器中的label标签。通常有一个父元素叫form-check

form-check-input也是3个单词组成的类,它的意思是form中的check容器中的input标签。通常有一个父元素叫form-check

总结

附录一:id什么时候用?怎么写?

锚链接定位

<a href="#header">跳转到header</a>配合上<a id="header"></a>实现锚链接。

<label for="...">

<label for="a"><input id="a" type="checkbox"></label>用于让label操作控件。

当做JS的操作绑定元素

比如BS里面有id="btnGroupDrop1"aria-labelledby="btnGroupDrop1"

    <button id="btnGroupDrop1" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      Dropdown
    </button>
    <div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
      <a class="dropdown-item" href="#">Dropdown link</a>
      <a class="dropdown-item" href="#">Dropdown link</a>
    </div>

由于JS的元素选择器查找id比查找其他的形式要快,所以给被选择的元素加上id是个好习惯。

另外,最好给id名的前面加上js-,这表示这个元素是一个js钩子。

当做最大的模块名

比如你的页面有5个大模块,比如header、footer、main等等的,你除了可以用<header>标签外,也可以用<div id="header">,当然了,这种情况下能不用id就别用,因为id主要不是干这个用的。

id的写法

可以有2种,一种是驼峰写法btnGroupAddon2,一种是下划线写法btn_group_addon_2,具体用哪种都可以,真心没有任何区别,所以项目内部统一一种即可。我个人偏向于下划线写法,因为我喜欢给变量名使用驼峰写法,这样的话两种写法在js中就可以一眼区分。

一般不要用连接线写法,因为容易跟class混淆,而且id名可以直接拿来当js的window对象的属性,也就是window.btn_group_addon_2就指向该元素,但是window.btn-group-addon-2是非法的写法。

附录二:注释什么时候写?

业界目前认为最正确的做法,是只给hack做注释,因为你不注释,我真的不好理解你这个hack是干嘛的。其他情况下,应当通过类名就可以让人明白这个类是干什么的。

上一篇下一篇

猜你喜欢

热点阅读