Functional CSS

Dariusz Krolikowski


@darek_kay darekkay.com

Reusability

Adaptability

Readability

Scalability

Performance

Maintainability

  • Reusability
  • Adaptability
  • Readability
  • Scalability
  • Performance

Methodologies

  • BEM (Blocks, Elements, Modifiers)
  • SMACSS (Scalable and Modular Architecture for CSS)
  • OOCSS (Object-Oriented CSS)
  • Functional CSS

BEM

  • Block: Standalone entity.
  • Element: A part of a block.
  • Modifier: A flag on a block or element.
.block {}
.block__element {}
.block__element--modifier {}
<form class="form">
  <input class="form__input form__input--disabled" />
</form>

Reusable and adaptable

1. Duplicate styles

.article-preview
  .article-preview__image
  .article-preview__content
    .article-preview__title
    .article-preview__body
  • Adaptable
  • Not reusable, not DRY*

* Don’t Repeat Yourself

2. CSS Preprocessor

@extend or mixin

.article-preview          { @extend .author-bio; }
.article-preview__image   { @extend .author-bio__image; }
.article-preview__content { @extend .author-bio__content; }
.article-preview__title   { @extend .author-bio__name; }
.article-preview__body    { @extend .author-bio__body; }
  • ? Adaptable
  • ? Reusable
  • Maintainable

3. Content-agnostic component

.media-card
  .media-card__image
  .media-card__content
    .media-card__title
    .media-card__body
  • Reusable, DRY
  • ? Adaptable
  • ? Semantic?

Semantics

CSS semantics are for developers.

<div id="article">
  <div class="headline">Animal sounds</div>
  <div>The cow goes <div class="bold">moo</div>.</div>
</div>

HTML semantics are for users.

<article>
  <h1>Animal sounds</h1>
  <p>The cow goes <strong>moo</strong>.</p>
</article>
.bold        { font-weight: bold; } /* presentational */
.author-name { font-weight: bold; } /* semantic */

“[…] authors are encouraged to use values that describe the nature of the content, rather than values that describe the desired presentation of the content.”

w3.org

Separation of Concerns?

“Semantic” classnames

“Separation of concerns”

HTML is restyleable!

CSS depends on HTML

Presentational classnames

“Mixing concerns”

CSS is reusable!

HTML depends on CSS

Neither approach is “wrong”.

“For individuals weaned on an ideology where ‘Semantic HTML’ means using content-derived class names, it usually requires you to work on a large application before you become aware of the impractical nature of that approach.”

Nicolas Gallagher

Functional CSS

“… is the approach to CSS architecture that favors small, single-purpose classes with names based on visual function.”

Also known as

.position-relative { position: relative }
.display-block     { display: block }
.border            { border: 1px solid #ccc }
.text-center       { text-align: center}
.font-weight-bold  { font-weight: bold }
.red               { color: red }
.font-16           { font-size: 16px }
.font-20           { font-size: 20px }
.font-28           { font-size: 28px }
.margin-1          { margin: 0.5rem }
.margin-2          { margin: 1rem }
.margin-3          { margin: 2rem }
.margin-x-2        { margin-left: 1rem; margin-right: 1rem; }

Wait, what?

  • Reusable
  • Adaptable

  • Reusable
  • Adaptable

Functional CSS

  • Immutable
  • Predictable
  • Pure (no side effects)
  • Composable

Favors composition over inheritance

Issue: Side effects

No side effects

Productivity Boost

The older your codebase is

the less CSS you will write

Naming is hard

There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.

Naming utility classes is straightforward.

Naming schema

Longhand: favors readability

.font-large   { font-size: 3rem }
.margin-top-0 { margin-top: 0 }

Shorthand: favors brevity

.f1   { font-size: 3rem }
.mt-0 { margin-top: 0 }
<div class="profile-wrapper">
  <div class="profile-wrapper__name">Alex</div>
</div>

<div class="flex">
  <div class="flex-1">Alex</div>
</div>

“My biggest argument is not having to name every thing. You know how many times I’ve had to think of a name for a random container that exists simply to align some crap?”

Hacker News

Portability

  • Custom spacing, typography, colors and breakpoints per project
  • Same CSS classes for every project
  • Cross-team consistency

“It’s just inline styles”

<h2 style="font-size: 16px; font-weight: bold; color: purple">
  Breaking Bad
</h2>
<h2 class="font-16 font-bold font-purple">
  Breaking Bad
</h2>
  • Specifity
  • 1 to 1 (inline) vs. 1 to many (classes)
  • Media queries, pseudo elements
  • Inconsistencies

Media Queries

  • Flexbox container
  • Column direction on mobile
  • Row direction on desktop
<div class="flex flex-column flex-md-row">
  <div>Element 1</div>
  <div>Element 2</div>
</div>

Maintainability

“Turn all red buttons blue”
  • Use templates
  • Search and replace
  • Extract common components (.btn, .modal)
<button class="bg-blue-500 hover:bg-blue-700 text-white
               font-bold py-2 px-4 rounded">
  <%= label %>
  <% if (icon) { %>
    <%= icon %>
  <% } %>
</button>

Utility-first

  • No more premature abstraction
  • No unnecessary bloat and complexity
  • Mix with other methodologies
  • TailwindCSS @apply:
<button class="btn-blue">Button</button>

<style>
  .btn-blue {
    @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
  }
</style>

HTML bloat

<div class="mt-4 md:mt-0 md:ml-6 w-64">
  <h3 class="uppercase tracking-wide text-sm text-indigo-600">
    Marketing
  </h3>
  <a href="/pricing.html"
     class="block mt-1 text-lg leading-tight font-semibold
            text-gray-900 hover:underline">Pricing</a>
  <p class="mt-2 text-gray-600">
    Get the best offer for your business
  </p>
</div>
  • “It’s ugly”
  • “It’s bloated”
  • “It’s unreadable”

Theming

  • .margin-20 .margin-3
  • .font-16 .font-3 / .font-medium
  • .color-blue .color-primary

Use abstract over absolute units

Learning curve

  • Every methodology requires a style guide
  • Functional classes are self-describing
  • Cross-team knowledge

Performance

  • Avoid expensive selectors
header#admin-main-header.header--bar-right-part li > a {
  line-height: 35px;
}

.line-height-2 { line-height: 35px; }
  • File size over time
  • GZip compression
  • Caching

Unused CSS

Autocomplete

CSS styles

CSS classes

Locating and selecting components

Frameworks

In the wild

Personal experience

  • Team’s preference for functional CSS
    • Gradual shift
  • Utility-heavy usage

If you love the way you write CSS and don’t want to change… then don’t.

… but

“You have to be prepared to disgard old ideas, look at alternatives, and even revisit ways that you may have previously dismissed.”

Nicolas Gallagher

Resources

Thank you!

github.com / darekkay / presentations

Dariusz Krolikowski

@darek_kay darekkay.com