Scalable

Component

Styles

A well-designed system makes it easy to do the right things and annoying (but not impossible) to do the wrong things

The Pit of Success

https://blog.codinghorror.com/falling-into-the-pit-of-success/

Let's Pretend JS was CSS

Problems with CSS

  • Global Namespace

  • Implicit dependencies

  • Poor Isolation

  • Dead code / duplication

  • Non-deterministic resolution

CSS conventions and tools

  • Naming Conventions
  • Scoped Styles
  • CSS Modules
  • CSS in JS

BEM

.Block
__element
--modifier

Naming Conventions

BEM

<template>
    <div class="TheGreeting">
        <h1 class="TheGreeting__headline">Hello world</h1>
        <div class="TheGreeting__body">
          <BaseButton text="Say Hello"/>
        </div>
    </div>
</template>


<style>
  .TheGreeting {
    border: 1px solid black;
  }

  .TheGreeting__headline {
    color: blue;
  }
</style>
components/TheGreeting.vue

BEM

<template>
    <div class="TheGreeting">
        <h1 class="TheGreeting__headline">Hello world</h1>
        <BaseButton text="Say Hello"/>
    </div>
</template>


<style>
  .TheGreeting .BaseButton {
    margin: 10px;
  }
</style>
components/TheGreeting.vue

BEM

<template>
    <div class="TheGreeting">
        <h1 class="TheGreeting__headline">Hello world</h1>
        <BaseButton class="TheGreeting__BaseButton" text="Say Hello"/>
    </div>
</template>
components/TheGreeting.vue

class is a prop and it's invalid

<template functional>
    <div class="BaseButton" :class="props.className">
      <button class="BaseButton__button">{{ props.text }}</button>
    </div>
</template>
<template>
    <div class="TheGreeting">
        <h1 class="TheGreeting__headline">Hello world</h1>
        <BaseButton className="TheGreeting__BaseButton" text="Say Hello"/>
    </div>
</template>

BEM

<template>
    <div class="TheGreeting">
        <h1 class="TheGreeting__headline">Hello world</h1>
        <div class="TheGreeting__body">
          <BaseButton text="Say Hello"/>
        </div>
    </div>
</template>


<style lang="stylus">
  import '~styles/brand-presets.css';

  .TheGreeting {
    border: 1px solid black;
    &__headline {
        color: headline-color;
    }
  }
</style>
components/TheGreeting.vue

Scoped Styles

<div data-v-6b11abfc class="TheGreeting">
    <h2 data-v-6b11abfc class="headline">Hello world</h2>
    <div data-v-6b11abfc class="body">
        <!-- ... -->
    </div>
</div>
<template>
    <div class="TheGreeting">
        <h2 class="headline">Hello world</h2>
        <div class="body">
          <!-- ... -->
        </div>
    </div>
</template>

<style scoped>
   // Styles here...
</style>
components/TheGreeting.vue
Markup result

Scoped Styles

<template>
    <div class="TheGreeting">
        <h2 class="headline">Hello world</h2>
        <!-- ... -->
    </div>
</template>

<style scoped>
    .headline {
        color: red;
    }
</style>
components/TheGreeting.vue
.headline[data-v-6b11abfc] {
    color: red;
}
output stylesheet

CSS-Modules

<template>
    <div :class="$style.TheGreeting">
        <h2 :class="$style.headline">Hello world</h2>
        <!-- ... -->
    </div>
</template>

<style module>
    .headline {
        color: red;
    }
</style>
components/TheGreeting.vue
<div>
    <h2 class="_components_TheGreeting__headline">
        Hello world
    </h2>
</div>
output markup

CSS-Modules

<template>
    <div :class="$style.TheGreeting">
        <h2 :class="$style.headline">Hello world</h2>
        <!-- ... -->
    </div>
</template>

<style module>
    .headline {
        background-color: black;
        composes: headline-color from '../presets.css';
    }
</style>
components/TheGreeting.vue
<div>
    <h2 class="_components_TheGreeting__headline 
               _123_headline-color">
        Hello world
    </h2>
</div>
output markup

Resouces

deck

By Justin Bennett