# 状态规则

状态规则是用来增强和覆盖其他样式的。例如,一个手风琴组件可能有收缩和展开两种状态。一个消息组件可能有成功和错误两种状态。

通常状态规则是和布局规则或者是基础模块类一起使用的。

<!-- 状态规则应用于一个元素 -->
<div id="header" class="is-collapsed">
    <form>
        <div class="msg is-error">
            There is an error!
        </div>
        <label for="searchbox" class="is-hidden">Search</label>
        <input type="search" id="searchbox">
    </form>
</div>

#header元素用了ID选择器,所以我们可以假设这个元素上的任何样式都是为了布局的,而is-collapsed则表示了折叠状态。有人可能还会觉得没有状态规则,默认状态就是展开状态。

msg模块也比较简单,定义了一个error的状态,有人可能已经想到了,success状态也可以定义在这个模块上。

最后的label区域有一个hidden状态,label会隐藏不见,但仍然会为某些设备(屏幕阅读器)做保留。这个例子当中,我们实际上将状态应用于基础元素,没有去覆盖布局和模块的样式。

# 这难道不就是模块吗?

子模块样式和状态样式确实存在很多的相似之处,都是改变一个元素现有的外观。但是,两者有两处关键的不同:

  1. 状态样式可以应用于布局或者是模块样式
  2. 状态样式和JavaScript之间可能存在依赖关系

第二点是最重要的区别。子模块样式在渲染的时候应用于元素,之后将不会有任何改变。但是状态样式通常表示的是页面上一个元素状态的变化,可能会因为某些交互发生改变。

例如,点击一个选项卡将会激活这个选项卡,这时is-active或者is-tab-active这样的状态类名就比较适合这种状态的改变。点击对话框上的一个关闭按钮将会隐藏这个对话框,这时用is-hidden这样的类名就比较合适。

# 使用!important

状态应该是独立的,并且由类选择器表示。

由于状态样式可能需要去覆盖更加复杂的规则集,所以!important的使用是允许的,并且我也推荐这样去使用(我曾经说过!important永远都不需要使用,但是在复杂系统中,有时却是必须要使用的)。不过,你通常也不会让两个状态同时去影响一个模块,或者是让两个状态影响同一套样式。所以,由于特殊性的冲突而去使用!important这样情况应该是少之又少的。

# 将状态规则和模块规则结合起来

状态规则有一个问题是无法避免的, 它无法通过继承来应用在某些需要的地方。有时,某个特殊的模块可能有非常特殊的状态。

这种情况状态规则是专门为特定模块定制,状态名应该含有模块的名称。而且状态规则应该放在模块规则中,不要和全局状态规则放在一起。

/* 模块的状态规则 */
.tab {
    background-color: purple;
    color: white;
}

.is-tab-active {
    background-color: white;
    color: black;
}

如果你的CSS是实时加载的,那么一般状态应该包含在基础和全局样式中,并且在初始页面中加载。特殊模块的状态样式不用在初始化的时候加载,在模块加载时加载就可以了。