DartSassでのカラー管理とフォント周り

2022/07/05 追記

この記事に記載している管理法をアップデートしました。
カラー管理を再考したので、その記録

少し前にLibSassが非推奨になる!とTwitterがザワザワしていましたよね。
その時にDartSassには乗り換えていた勢なんですが、なんだかSassをうまく使いこなせてないなぁとモヤっていたので、改めて勉強し直しております。
ひとまずカラーとフォント周りを分かりやすく効率的に管理し、コーディングスピードを1秒でも早くするべく試行錯誤したのでその記録です。

ビルトインモジュールという存在

今回久しぶりにSassについていろいろとググっていると、なんだか初見なビルトインモジュールさん…
さらに調べると、なんとDartSassではスラッシュを使った除算(割り算)は非推奨!
これまで何の疑問も持たずにスラッシュ多用してました…
代わりにビルトインモジュールを使用するのですが、実際の例がこちら。

sample.scss
@use "sass:math"; // ビルトインモジュール
.contents {
  width: math.div(100px, 5);
}

// コンパイル後
.contents {
  width: 20px;
}

簡単にいうと@useでモジュールを読み込んで、CSSの関数との競合をなくしてこーぜ!って感じです。
詳しい解説はこちらの記事が分かりやすかったのでぜひ。

Sass: Built-In Modulesを覗くと、計算以外にもカラーなどいろいろ種類があってへぇ~~が止まらないです。

特にカラーなんて使いどころありまくりそうですね。
ということで、この便利システムを使いつつ効率化を図っていきます!

関数を使ってカラー管理

カラー管理をしようと思ったきっかけは、Sassで色を管理する色々な方法 - QiitaというQiita記事。

たまたま目にして、もうウロコがでてくるのを抑えきれず!!!
すぐさまカラー管理に取り組みました🍃

これまでの管理方法

わりとこのタイプの人多いんじゃないかなぁと思うのですが、私はこれまで変数でカラーコードをベターっと記述していました。

variables/_color.scss
// text color
$color-text-default: #2B2B2B;
$color-text-gray: #707070;

// title color
$color-title: #333;

// background color
$color-body: #fff;
$color-background-gray: #EDEDED;

大規模なサイト制作をしているわけでもなく、チーム制作ではなかったので、なんとかこれで問題も起きずに済んでいたって感じです。
カラフルなサイトだったりしたら、ごっちゃになってしまうのがモヤモヤポイントでした。(私の記述法がよくないだけかも)

さっそくカラー管理にトライ!

と、その前に私のSassファイル構成をさらっとご紹介。
ちなみにPRECSSが好きなので、接頭辞がblだったりelだったりします。

Directory Tree
└─ sass
   ├─ foundation // 基礎ファイル
   │ ├─_base.scss
   │ ├─_reset.scss
   │ └─_index.scss
   ├─ functions // 関数管理
   │ ├─_color.scss
   │ ├─_font.scss
   │ ├─ ...
   │ └─_index.scss
   ├─ mixins // mixin管理
   │ ├─_responsive.scss
   │ ├─_hover.scss
   │ ├─ ...
   │ └─_index.scss
   ├─ variables // 変数管理
   │ ├─_breakpoints.scss
   │ ├─_colors.scss
   │ ├─_others.scss
   │ ├─ ...
   │ └─_index.scss
   ├─ layout // レイアウトに関するファイル
   │ ├─_header.scss
   │ ├─_main.scss
   │ ├─_footer.scss
   │ ├─ ...
   │ └─_index.scss
   ├─ object // モジュールに関するファイル
   │ ├─ component
   │  │ ├─ _bl.scss
   │  │ ├─ _el.scss
   │  │ └─ _index.scss
   │ ├─ javascript
   │  │ ├─ _js.scss
   │  │ ├─ ...
   │  │ └─ _index.scss
   │ ├─ page
   │  │ ├─ _top.scss
   │  │ ├─ ...
   │  │ └─ _index.scss
   │ └─ utility
   │    ├─ _hp.scss
   │    ├─ ...
   │    └─ _index.scss
   └─ style.scss

mixinvariablesglobalファイルでまとめようかとも思ってるんですが、少し迷い中です。
まとめたら記述は少し楽になるかもだけど、そしたらDartSassの名前空間がつけれる意味ってなんだろう思うんですが、う~ん…
ここはもう少し勉強が必要そうです。

マップ変数を作成

variables/_color.scss
// palettes
// --------------------------------------------------------------------------
$black: #333;
$mildBlack: #2B2B2B;
$white: #fff;
$gray: #707070;
$lightGray: #EDEDED;
$silverGray: #A0A0A0;

//color map
// --------------------------------------------------------------------------
$colors: (
    color-body-background: $white,
    color-block-background: $lightGray,
    color-global-text: $mildBlack,
    color-global-icon: $gray,
    color-headingLv2-text: $black,
    color-headingLv2-border: $silverGray,
    color-info-border: $silverGray,
    color-contact-btn: $silverGray,
    color-contact-border: $silverGray,
);

パレットとして使用カラーを変数でまとめ、マップを作成しました。
直接マップにカラーコードを記述しない理由としては、一目で紐づいている色を分かりやすくするためです。
この考えはこちらの記事を参考にさせていただきました。
変更に強いSassの色管理プラクティス - Qiita

色の名前はすっごく悩んだんですが、上記の記事でも紹介されている「Name that Color」というサイトを参考にしつつ考えています。

関数を作成

functions/_color.scss
@use "sass:map";
@use "../variables" as *;

@function colors($key) {
    @return map.get($colors, $key);
}

先ほど作成したマップを簡単に使用できるよう関数を作成しました。
ここで活躍してくれるのがビルトインモジュール!

@use "sass:map";を記述し、mapモジュールを読み込みます。
そしてmap.get関数(指定したキーの値を返してくれる関数)を使用して、カラー管理の@functionを作成します。

最近map-getからmap.getへメソッド名が変更されました。

関数を使用する

関数ファイルを読み込んで、実際に作成した関数を使用します。
functionファイルの名前空間を*にして、関数使用時に宣言なしに使用できるようにしましたが、あんまりよくないことかも…
名前空間にアスタリスクを使用することによるデメリットも、もう少し理解を深めて記述を再試行していこうと思います。
とりあえず現段階ではこれで!

foundation/_base.scss
@use "../functions/" as *;
@use "../variables/" as var;

body {
  background: colors(color-body-background);
  color: colors(color-global-text);
}

コンパイル後はこんな感じになります。

dist/style.css
body {
  background: #fff;
  color: #2b2b2b;
}

うまくいきました~👏

@eachを使用しなかった理由

安田学さんの記事では@eachを使用して、処理を自動化する方法も紹介されています。
でも今回のカラー管理においては、それを使用しませんでした。
理由はBootstrapみたいな感じになって、個人的にしっくりこないなあと思ったから。(アンチBootstrapではないですよ!)

例えば記事内の例であげられているSNSカラーの場合は、@eachで自動化するのがとても便利そうです。
しかし全カラーを自動化すると!importantが必要な状況になってしまったりしないかなあと思っています。
ただこれは私の勉強不足故に使いこなせないだけの可能性が高いので、ここも同様に勉強を続けます。

関数を使ってフォントを管理

フォントに関しては、font-familyfont-sizeの関数を作成しました。
font-familyに関しては上記のカラー管理とほぼ一緒なので、さらっといきます。

font-family の管理

variables/_others.scss
$myriad: myriad-pro, sans-serif;
$poppins: poppins, sans-serif;
$basic: YuGothic,'Yu Gothic','Hiragino Kaku Gothic ProN','ヒラギノ角ゴ ProN W3',sans-serif;

$font: (
    font-global: $myriad,
    font-heading: $poppins,
    font-lead: $basic,
)
functions/_font.scss
@use "sass:map";
@use "../variables" as *;

@function font-family($key) {
  @return map.get($font, $key);
}
foundation/_base.scss
@use "../functions/" as *;
@use "../variables/" as var;

body {
	font-family: font-family(font-global);
}
dist/style.css
body {
  font-family: myriad-pro, sans-serif;
}

カラー管理の方法と変わりないですね。
ちなみにWebフォントを直接読み込んでいるので@fontfaceは使用していません。

フォントサイズの単位をremに統一させる

TAK さんの記事を参考に、pxからremへ変更させる関数を作っていきます。

関数を作成

ここでもビルトインモジュールの登場!
@use "sass:math";を記述して、mathモジュールを読み込みます。
今回の関数では除算(割り算)をしたいので、math.div関数を使用していきます。

まずはpxなどの単位を取り除くstrip-unit関数を記述します。
詳しいコード解説はこちらの記事が分かりやすかったので、リンクを置いておきます。
Sassで数値から単位を除去する

functions/strip-unit.scss
@use "sass:math";

@function strip-unit($number) {
    @if type-of($number) == 'number' and not unitless($number) {
        @return math.div($number, ($number * 0 + 1));
    }

    @return $number;
}

そしてstrip-unit関数ファイルを読み込ませた先で、pxからremに変更する関数を記述します。
ほぼTAKさんの記事にあるコードそのままです。ありがとうございます

functions/_font.scss
@use "sass:math";
@use "./strip-unit" as *;

@function rem($px, $base: 16px) {
  $value: $px;

  // 単位がpx以外の場合は警告を出してそのまま返す
  @if (unit($px) != 'px') {
    @warn 'rem()の引数にpx以外の値を指定しても計算できません';
    @return $value;
  }

  $value: math.div(strip-unit($px), strip-unit($base)) * 1rem;

  @return $value;
}

関数を使用する

foundation/_base.scss
body {
  font-size: rem(16px);
}

コンパイル後はこうなります。

dist/style.css
body {
  font-size: 1rem
}

この他にも、変数を引数として渡すことも可能です。

variables/_size.scss
$lv1FontSize: 120px;
foundation/_base.scss
@use "../functions/" as *;
@use "../variables/" as var;

body {
  font-size: rem(var.$lv1FontSize);
}
dist/style.css
body {
  font-size: 7.5rem;
}

便利すぎて泣く!!!

さいごに

こんな感じで粗削りではありますが、カラーとフォントを管理することが出来たかなと思います。
改めてSassの表面部分しか理解できてなかったなぁと反省です。
今回もっと理解を深めたいと思った点は、

  • その他のビルトインモジュールの活用法
  • 名前空間を使うことの意味
  • @eachを使っての管理方法の模索

です。
知れば知るほど便利なSassを、これからも勉強していきたいと思います。

それでは、どろんっ☁️