Using specific, conventions-based class names to indicate and style component state is part of the larger Invision SCSS Authoring Convention best practices.
Stateful classes are differentiated from component variants/modifiers in that the stylistic alterations they introduce are based on interaction or temporary state. For instance, a button being primary or secondary will not change based on interaction or API activity. However, a button being disabled or having error can change easily and often.
.c-button--primary {} /* vs. */ .c-button.is-disabled {}
The most helpful way to decide when to create or use stateful classes relates to their place in templating. Most typically, stateful classes will only exist in ng-class
definitions. This is because their application will depend on some truthy or enum value in the application state. Javascript is usually needed to apply the styles based on application parameters.
.c-collapsibleSection--narrow {} /* vs. */ .c-collapsibleSection.is-collapsed {}
As such, these classes use a different naming syntax. is-active
is the classic example wherein, when applied, status indication for a component changes. In the example below, c-navItem
only needs temporary state indication when active, whereas a text only version is permanent and context-based departure from the component's default styling.
.c-navItem--textOnly {} /* vs. */ .c-navItem.is-active {}
is-
is the preferred prefix for stateful classes, but has-
can certainly be used in cases where the shift allows for grammatic clarity or brevity.
.c-fieldset.is-disabled {} /* vs. */ .c-fieldset.has-tooltip {}