CSS naming convention in Vue component
Tags: vue, css, javascript
Published: 2018-03-30 02:38:42

---
title: CSS naming convention in Vue component
published: true
description: How to naming Vue component scoped CSS classes
tags: vue,css,javascript
---


For a long time I considered CSS naming convention in Vue component.

This naming convention is one of my answer. It's less complexity and easy to handling.


I thought about CSS naming conventions tailored to the Vue component
Previously, SFC (Single File Component) used BEM nomenclature, but I felt redundant in writing components. Therefore, based on ECSS's idea, I calmed down to customize it according to SFC.

It is called *SFCSS* that means CSS for SFC.

## Naming convention is necessary even using `scoped`
First of all as a prerequisite, a naming convention is necessary even if `<style scoped>` does not leak out the style of the component. The reason for class name written appropriately according to `scoped` will surely be paid later.

[Official style guide#Component style scoping](https://vuejs.org/v2/style-guide/index.html#Component-style-scoping-essential) In order not to apply it, it is necessary to add a component specific prefix and so on.

However, development at SFC is different from ordinary web site in nature, so I think that the prefix is ​​not necessarily the correct answer.


## Example of naming in ECSS

As an example, ECSS naming is done with the following pattern.

```css
.namespace-Component_ChildNode-variant {}
```

`namespace` gives prefix as to where the component belongs etc `-variant` is a modifier in BEM. Where is `Component` Block and` ChildNode` Element?

We adapted this naming convention to SFC as follows.

## SFCSS
In SFCSS, naming is done with the following pattern.

```css
.ComponentName {}
.ComponentName_ChildNode {}
._variant {}
```

Only these three patterns are used.

## ComponentName
`ComponentName` uses the same name as the` name` of the vue component.

```html
<template>
  <div class="MyComponent"></div>
</template>

<script>
  export default {
    name: 'MyComponent',
  }
</script>

<style lang="scss" scoped>
  .MyComponent {}
</style>
```

By matching the root class name with the `name` of the vue component, it is easier to identify the component from the DOM node.

If you can use vue-devtools, this idea is not necessary, but it will be useful in production environments and verification in browsers without vue-devtools.

## ChildNode
`ChildNode` is an element other than the root element of the component to which you want to grant the class.

For example, set `ChildNode` with the following granularity.

```html
<template>
  <div class="MyComponent">
    <h1 class="MyComponent_Heading">
      heading
    </h1>
    <ul class="MyComponent_List">
      <li class="MyComponent_ListItem"
        v-for="item in list"
      >
        {{item.label}}
      </li>
    </ul>
  </div>
</template>
```

#### bad pattern

In principle, the following `ChildNode` consecutive class names shall be **unacceptable** :no_good:

```css
.MyComponent_List_Item {} / * bad * /
```

## variant
`variant` is a class to use for elements whose style you want to change depending on conditions. ECSS contains a full selector such as `ComponentName_ChildNode` as a class name, but since you can use` scoped`, define it as a single class.

`ComponentName` and `ChildNode` are Pascal cases, whereas `variant` is written in a camel case and begins with a`_` at the beginning of the class name.

```css
._variantClassName {}
```

Since `variant` has many uses to detach it with`: class`, it is convenient to construct it with a character string that does not require quotes.


### namespace is unnecessary
We considered `namespace` unnecessary in the vue component. The `namespace` of ECSS indicates the area to which the component belongs etc, but there is no need to limit the place to be used in the vue component.

You will not need to avoid name conflicts due to prefixes as vue components will have unique names.


## Limit the root class to one
Within `<style>` of `.vue`, limit the root class (` ComponentName`) to one. Only styles are described with components that are one-to-one.

If you want to write more than one root class, it may be a sign to separate into different components.

## Use `lang="scss"` to omit description with `&`

For example, in `template` exemplified by` ChildNode` above, write `style` as follows.

```scss
<template>
  <div class="MyComponent">
    <h1 class="MyComponent_Heading">heading</h1>
    <ul class="MyComponent_List">
      <li class="MyComponent_ListItem"
        v-for="item in list"
        :class="{_selectedItem: isSelectedItem(item)}"
      >
        {{item.label}}
      </li>
    </ul>
  </div>
</template>

<style lang="scss" scoped>
  .MyComponent {
    &_Heading {}
    &_List {}
    &_ListItem {}
    ._selectedItem {}
  }
</style>
```

Although the amount of descriptions of class names in `template` does not decrease, we thought that the overall` style` looks better as compared to writing all in full. This `& _` omission is also useful for partitioning components.


## in conclusion
When I tried this SFCSS in the actual case, I did not suffer from the class name of the component. I think that development is proceeding with a well-balanced state that it is not properly named.


*This post is translation by Google Translate*. [Original post in Japanese](https://qiita.com/nakajmg/items/683395c20a3afbdb2d99)