Web制作

【修正指示に爆速対応】カンプ崩しゼロ!flocss思想でつくる自作SCSSユーティリティ一式

【修正指示に爆速対応】カンプ崩しゼロ!flocss思想でつくる自作SCSSユーティリティ一式

デザインカンプの見た目どおりに組んだあとに、「余白だけ +10px」「SP だけ折り返すな」と修正が来ます。クラスを検索して上書きし、ブロックの修飾子が増えていく。その時間は、よくあります。カンプ崩しゼロ、修正が激減、とは言いません。ブロックの名前は触らず、例外だけを短いクラスで足す用意があると、後工程の差分が小さくなりやすい、です。

結論です。Tailwind を否定するわけではありません。その他の命名規則 が主の案件に、別系統のユーティリティを無制限に混ぜると、読み解く必要があります。プロジェクトの余白ステップとブレークポイントに合わせた、接頭辞付きの自作 Utility は、その隙間用です。直感的な命名で即座に、は案件のルール次第になります。接頭辞付きの自作 Utilityを先に用意しておくことで、納品前の上書き地獄を減らします。

この記事では、フリーランスのWebディレクター兼エンジニアとして、flocss に馴染む SCSS Utility の作り方を整理します。テンプレート配布というわけではありません。ここに出すコードは、出力量を抑える前提の骨組みです。全プロパティ×全サイズ×6ブレークポイントを全部出すと、CSS は太ります。

なぜ Tailwind 一式ではなく、自作なのか

mt-4 や flex を その他の命名規則 の隣に置くこと自体は動きます。クラス名のバッティングが必ず起きる、ことはありません。起きやすいのは、二つの命名(ブロック/ユーティリティ)が同じ HTML に混ざり、どちらが正しいかが見えなくなることです。ブレークポイントが Bootstrap 由来の md と、カンプの 768 がずれる、もよくあります。

自作にする利点は、フレームワークを導入してない案件に追加できること、軽いこと、$space と $breakpoints がデザインのトークンと一致することです。Mixin と @each でクラスを出すと、値の追加がマップ1行で済みます。フレームワークより常に保守しやすい、とは言いません。トークンが少ない案件向けです。

命名と、対象プロパティ

接頭辞は u-。既存の .c- / .l- と衝突しにくいようにします。形は次です。

  • ベース: .u-{property}--{value}
  • 方向があるもの: .u-margin-top--md
  • ブレークポイント以上: .u-text-align--center\@md

HTML のクラスに @ を使う例です。SCSS / CSS では @ をエスケープします(\@)。チームがエスケープを嫌うなら、--md ではなく -md や _md に変えてください。どちらでも、flocss の Element は触らない、がルールです。

対象は次の 25 種です。全部を毎回出力する必要はありません。使うものだけマップに載せる。

余白・サイズ: margin(四方向と上下左右のまとめ)、padding(同様)、width、height、gap

レイアウト: display、overflow、justify-content、justify-items、justify-self、align-content、align-items

テキスト: text-align、font-size、font-weight、letter-spacing、text-transform、white-space、line-height、vertical-align

装飾: object-fit、border-radius、box-shadow、text-shadow、background-blend-mode

レスポンシブは 6 段(xs / sm / md / lg / xl / xxl)を例にします。数値はカンプに合わせて書き換える。min-width のモバイルファーストです。

実務コード:マップとループ

ステップ1: _config.scss

$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  xxl: 1400px,
);

$space: (
  none: 0,
  xs: 4px,
  sm: 8px,
  md: 16px,
  lg: 24px,
  xl: 40px,
);

$sides: (
  top: top,
  right: right,
  bottom: bottom,
  left: left,
  block: block,
  inline: inline,
);

$align: (
  start: flex-start,
  end: flex-end,
  center: center,
  between: space-between,
  stretch: stretch,
);

block / inline は margin-block など論理プロパティ用です。不要ならマップから外す。

ステップ2: _utility.scss

方向付きの余白と、ブレークポイント付きの1プロパティを出す例です。全 25 種をこのファイルにコピペで完結、とはしません。同じ @mixin を、プロパティごとに呼びます。

@mixin mq($name) {
  $min: map-get($breakpoints, $name);
  @if $min == 0 {
    @content;
  } @else {
    @media (min-width: $min) {
      @content;
    }
  }
}

@mixin u-box($prop, $map: $space) {
  @each $size, $value in $map {
    @each $side-name, $side in $sides {
      .u-#{$prop}-#{$side-name}--#{$size} {
        #{$prop}-#{$side}: $value;
      }

      @each $bp, $min in $breakpoints {
        @if $bp != xs {
          .u-#{$prop}-#{$side-name}--#{$size}\@#{$bp} {
            @include mq($bp) {
              #{$prop}-#{$side}: $value;
            }
          }
        }
      }
    }
  }
}

@include u-box(margin);
@include u-box(padding);

@each $name, $value in $align {
  .u-align-items--#{$name} {
    align-items: $value;
  }
  @each $bp, $min in $breakpoints {
    @if $bp != xs {
      .u-align-items--#{$name}\@#{$bp} {
        @include mq($bp) {
          align-items: $value;
        }
      }
    }
  }
}

xs はベース(メディアクエリ無し)に相当させ、修飾子は sm 以上だけ出しています。xs 用クラスも欲しいなら、条件を外してください。

justify-content など残りは、$align と同じ形のマップを足してループをコピーします。box-shadow はトークンが少ないほど安全です。任意の影を全部クラス化しない。

ステップ3: HTML

flocss のブロックは残し、例外だけ u- を足します。

<h2 class="c-card__title u-margin-bottom--sm u-text-align--center@md">
  見出し
</h2>

HTML 上は u-text-align--center@md と書きます。ビルド後の CSS セレクタは .u-text-align--center\@md です。修正が「md 以上で中央」なら、.c-card__title に --center を増やさない。

運用で先に決めること

ベースは flocss。Utility は、1ページ限りの例外、納品前の微差、ディレクションで変わった余白。コンポーネントの常態(カードの既定余白)まで u- に逃がすと、HTML のクラスが長くなり、flocss の意味が薄れます。崩壊、というより、どちらを直すかが分からなくなります。

ファイルサイズは、JS の Tree-shaking と同じようには減りません。SCSS は書いた分が出力されます。拾う運用は次です。

  • マップに、使うサイズとプロパティだけ残す
  • 影や background-blend-mode は、使う案件だけ @include
  • どうしても全出ししたあとに削るなら、PurgeCSS などの未使用削除。クラス名に @ がある場合は、セーフリストが要ることがあります

プロパティ別 命名マップ

プロパティ

クラス規則

値・方向

使用例

margin

u-margin-{side}--{size}

side: top/right/bottom/left/block/inline。size: $space

u-margin-top--md

padding

u-padding-{side}--{size}

同上

u-padding-inline--sm

width / height

u-width--{token}

auto, full(100%), トークン幅

u-width--full

gap

u-gap--{size}

$space

u-gap--md

display

u-display--{value}

block, flex, grid, none

u-display--none\@sm

overflow

u-overflow--{value}

hidden, auto

u-overflow--hidden

justify-content

u-justify-content--{name}

$align

u-justify-content--between

justify-items

u-justify-items--{name}

start, center, stretch

u-justify-items--center

justify-self

u-justify-self--{name}

同上

u-justify-self--end

align-content

u-align-content--{name}

$align

u-align-content--center

align-items

u-align-items--{name}

$align

u-align-items--center\@lg

text-align

u-text-align--{value}

left, center, right

u-text-align--center\@md

font-size

u-font-size--{token}

デザインの段階

u-font-size--sm

font-weight

u-font-weight--{token}

400, 700 など

u-font-weight--bold

letter-spacing

u-letter-spacing--{token}

狭い/標準

u-letter-spacing--wide

text-transform

u-text-transform--{value}

uppercase 等

u-text-transform--uppercase

white-space

u-white-space--{value}

nowrap, pre-wrap

u-white-space--nowrap\@sm

line-height

u-line-height--{token}

見出し/本文

u-line-height--tight

vertical-align

u-vertical-align--{value}

middle, top

u-vertical-align--middle

object-fit

u-object-fit--{value}

cover, contain

u-object-fit--cover

border-radius

u-radius--{token}

$space または専用

u-radius--md

box-shadow

u-shadow--{token}

少数のトークン

u-shadow--sm

text-shadow

u-text-shadow--{token}

使うときだけ

u-text-shadow--sm

background-blend-mode

u-bg-blend--{value}

multiply 等。常用しない

必要なページだけ

\@md は「そのブレークポイント以上」。上書きの詳細度は、ユーティリティ同士が同じなら、HTML の後ろのクラス順や、出力順に依存します。同じプロパティを二重に付けない。

まとめ:例外用の道具を、先に用意する

納品直前の想定外な工数が無くなる保証はありません。ブロックを汚さず余白を足せる経路があると、修正の場所が決まります。時短と品質の両立、はトークンを増やしすぎない運用とセットです。

余白ルールとブレークポイントを揃えた SCSS の切り方、flocss と Utility の境界の相談は、相談・お問い合わせからどうぞ。