according to most neuroscience studies, 80% of the population agrees that their number one fear is public speaking.

number two is death.

Adrià Fontcuberta

@afontcu_

Software Engineer at Calidae

Adrià Fontcuberta

@afontcu_

Frontend Dev at Calidae

Adrià Fontcuberta

@afontcu_

UI Engineer at Calidae

Adrià Fontcuberta

@afontcu_

Webmaster at Calidae

Chapter 1

"wat CSS"

body.product .content-body-wrapper.tabs-block .switch
.offer section.accommodation .content-width .accommodation
.select-accommodation-box .list .map { width: 100%; height: 300px; }

body.product .content-body-wrapper.tabs-block .switch .offer
section.accommodation .content-width .accommodation
.select-accommodation-box .list .list-content .items
.accommodation-info #formAccomodation .accommodation-form 
.mealplan .select-price input { display: inline-block }

wat happened, CSS?

CSS Zen Garden happened

.sidebar .design-selection nav ul li a {
  display: inline;
}
<div class="remove-product">
  <h1>
  <div>
    <img>
    <p>
  </div>
  <div>
    <button class="remove">
    <button>
  </div>
</div>
.remove-product {
  > h1 { }
  > div {
      img { }
      p { }
    }
  > div {
    > button {
      &.remove { }
    }
  }
}

Issues

1) HTML and CSS were too coupled.

2) CSS was not reusable.

3) We needed to learn CSS.

Chapter 2

one issue at a time.

1) HTML and CSS were too coupled.

Decouple them!

<div class="remove-product">
  <h1>
  <div>
    <img>
    <p>
  </div>
  <div>
    <button class="remove">
    <button>
  </div>
</div>
<div class="remove-product">
  <h1 class="remove-product-title">
  <div class="remove-product-body">
    <img class="remove-product-image">
    <p class="remove-product-message">
  </div>
  <div class="remove-product-buttons">
    <button class="remove">
    <button>
  </div>
</div>

2) CSS was not reusable.

From semantic CSS to visual CSS.

<div class="remove-product">
  <h1 class="remove-product-title">
  <div class="remove-product-body">
    <img class="remove-product-image">
    <p class="remove-product-message">
  </div>
  <div class="remove-product-buttons">
    <button class="remove">
    <button>
  </div>
</div>
<div class="modal">
  <h1 class="modal-title">
  <div class="modal-body">
    <img class="modal-icon">
    <p class="modal-message">
  </div>
  <div class="modal-buttons">
    <button class="btn primary">
    <button class="btn">
  </div>
</div>

what if...

.modal-messages {
  .modal-icon { ... }
  .modal-message { ... }
}
.alert-content {
  .alert-img { ... }
  .alert-text { ... }
}
.icon-text {}
.text-with-icon-on-left {}

The media object is an image to the left, with descriptive content to the right.

Nicole Sullivan

<div class="modal">
  <h1 class="modal-title">
  <div class="modal-body">     <--
    <img class="modal-icon">   <--
    <p class="modal-message">  <--
  </div>
  <div class="modal-buttons">
    <button class="btn primary">
    <button class="btn">
  </div>
</div>
<div class="modal">
  <h1 class="modal-title">
  <div class="media modal-body">  <--
    <img class="media-img">       <--
    <p class="media-body">        <--
  </div>
  <div class="modal-buttons">
    <button class="btn primary">
    <button class="btn">
  </div>
</div>
<div class="media alert">
  <img class="media-img">
  <p class="media-body alert-content">
</div>

3) Learn CSS

anyway.

decoupled, understood, visual CSS.

our CSS classes were now reusable across projects.

a component made of components.

modal = media + button + card + ...

we were not building pages anymore.

we were creating components, and composing them.

from styling pages to creating design systems.

design wat?

Design systems

Principles

Rules

Constraints

Principles: Spacing should help establish relationship between elements.

Rules: Spacing values must be proportional.

Constraints: Only 5 spacing values available.

$baseline: 6px;
$unit-factor-tiny:   1;
$unit-factor-small:  2;
$unit-factor:        4;
$unit-factor-large:  8;
$unit-factor-huge:  16;
$spacing-unit-tiny  =  $baseline * $unit-factor-tiny;  // 6px
$spacing-unit-small =  $baseline * $unit-factor-small; // 12px
$spacing-unit       =  $baseline * $unit-factor;       // 24px
$spacing-unit-large =  $baseline * $unit-factor-large; // 48px
$spacing-unit-huge  =  $baseline * $unit-factor-huge;  // 96px
.modal-body {
  margin-left: $global-spacing-unit;
}

.alert-content {
  padding: $global-spacing-unit-small $global-spacing-unit;
}

❤️ backends

Other important decisions

File structure.

Naming.

File structure

ITCSS (Inverted Triangle CSS)

Settings

Global defaults

Objects

Components

Utilitites

/scss/1-Settings/_settings.core.scss

$baseline: 6px;

$unit-factor-tiny:  1;
$unit-factor-small: 2;
$unit-factor:       4;

$spacing-unit-tiny  =  $baseline * $unit-factor-tiny;  // 6px
$spacing-unit-small =  $baseline * $unit-factor-small; // 12px
$spacing-unit       =  $baseline * $unit-factor;       // 24px

Naming

BEM (Block, Element, Modifier)

.human {}

.human__head {}

.human__eyes {}

.human--tall {}

.human__eyes--blue {}
.media {}

.media__img {}

.media__body {}

.media--large {}
.o-media {}

.o-media__img {}

.o-media__body {}

.o-media--large {}

/scss/5-Objects/_objects.media.scss

.o-media { display: flex; align-items: flex-start; }

.o-media__body { flex: 1; }

.o-media__image { margin-right: $spacing-unit; }

.o-media--large .o-media__image {
  margin-right: $spacing-unit-large; }
<div class="c-card c-card--rounded">
  <h1 class="c-card__header u-text-hairline">
  <div class="c-card__body">
    <div class="o-media o-media--center o-box">
      <img class="o-media__img">
      <p class="o-media__body u-text-h5 u-text-hairline">
    </div>
    <div class="c-card__footer c-card__footer--between">
      <button class="c-btn c-btn--ghost">
      <button class="c-btn c-btn--primary">
    </div>
  </div>
</div>
<div class="c-card c-card--rounded">
  <h1 class="c-card__header u-text-hairline">
  <div class="c-card__body">
    <div class="o-media o-media--center o-box">
      <img class="o-media__img">
      <p class="o-media__body u-text-h5 u-text-hairline">
    </div>
    <div class="c-card__footer c-card__footer--between">
      <button class="c-btn c-btn--ghost">
      <button class="c-btn c-btn--primary">
    </div>
  </div>
</div>

death by repetition

.o-media--large .o-media__image {
  margin-right: $spacing-unit-large; }
.c-list_item--large {
  margin-right: $spacing-unit-large; }
.c-actions-list--large .c-actions-list__item {
  margin-right: $spacing-unit-large; }
.u-margin-right-large {
  margin-right: $spacing-unit-large !important;
}

Flexbox utilities

Padding and margin utilities

Width and height utilities

Text sizes, colors, styles and weights

/scss/7-Utilities/_utilities.height.scss

.u-height-none { height: 0 !important; }

.u-height-full { height: 100% !important; }

.u-height-viewport { height: 100vh !important; }

Chapter 3

utility-first CSS.

create a lot of small, reusable, focused CSS classes, and use them to build your UI.

<div class="u-padding u-border-radius u-background-white u-shadow-large">
  <h1 class="u-padding u-text-hairline">
  <div class="u-padding-vertical-small">
    <div class="o-media u-flex-items-center u-padding">
      <img class="o-media__img">
      <p class="o-media__body u-text-h5 u-text-hairline">
    </div>
    <div class="u-padding-small u-background-dark-gray
                u-flex u-flex-justify-between">
      <button class="c-btn c-btn--ghost">
      <button class="c-btn u-background-primary">
    </div>
  </div>
</div>

it is possible to build a whole new component without writing a single line of CSS.

a word of caution.

Wrapping up

"a lot of things happened in ~40 minutes"

Normandy CSS

SCSS + ITCSS + BEM + Namespaces + utility-first

Github

Next steps

👋 SCSS?

JS + CSS = 💖?

Shadow DOM (Scoped CSS)

(Our) Learnings

  • Use software principles.
  • Use visual-based class naming.
  • Think in terms of Design Systems.
  • Utility-first. Abstract out components.
  • Agree on structure, naming, principles...

Thank you !

What questions do you have?

(ask me anything! @afontcu_ on Twitter)

https://maintainable-scalable-css-commit.now.sh/

References