【SCSS】Bootstrapのようにボタンの文字色と背景色を自動生成したい

  • URLをコピーしました!

こんにちは。すずきです。

Bootstrapのようにボタンの色を指定すると、文字色とホバー色が自動で指定されるのが便利と思い
Bootstrap以外でも使えるように自作して見ました。

目次

実際のコード

こちらが実装したコードです。
HTMLSCSSで実装しています。

See the Pen ボタン色に合わせてテキストカラー自動設定 by すずき (@k-suzuki3533) on CodePen.

<div class="container">
  <a href="#" class="button">ボタン</a>
  <a href="#" class="button button--black">ボタン</a>
  <a href="#" class="button button--blue">ボタン</a>
  <a href="#" class="button button--indigo">ボタン</a>
  <a href="#" class="button button--purple">ボタン</a>
  <a href="#" class="button button--pink">ボタン</a>
  <a href="#" class="button button--red">ボタン</a>
  <a href="#" class="button button--orange">ボタン</a>
  <a href="#" class="button button--yellow">ボタン</a>
  <a href="#" class="button button--green">ボタン</a>
  <a href="#" class="button button--teal">ボタン</a>
  <a href="#" class="button button--cyan">ボタン</a>
  <a href="#" class="button button--deep-purple">ボタン</a>
  <a href="#" class="button button--light-blue">ボタン</a>
  <a href="#" class="button button--light-green">ボタン</a>
  <a href="#" class="button button--lime">ボタン</a>
  <a href="#" class="button button--amber">ボタン</a>
  <a href="#" class="button button--deep-orange">ボタン</a>
  <a href="#" class="button button--brown">ボタン</a>
  <a href="#" class="button button--blue-gray">ボタン</a>
</div>
// -----------------------------------------------------------------
//色の変数登録
// -----------------------------------------------------------------
//文字色としても使用
$white: #ffffff;
$black: #000000;

$blue: #42a5f5;
$indigo: #5c6bc0;
$purple: #ab47bc;
$pink: #ec407a;
$red: #ef5350;
$orange: #ffa726;
$yellow: #ffee58;
$green: #66bb6a;
$teal: #26a69a;
$cyan: #26c6da;
$deep-purple: #7e57c2;
$light-blue: #29b6f6;
$light-green: #9ccc65;
$lime: #d4e157;
$amber: #ffca28;
$deep-orange: #ff7043;
$brown: #8d6e63;
$blue-gray: #78909c;

// -----------------------------------------------------------------
//マップの生成
// -----------------------------------------------------------------
$button-colors: (
  "white": $white,
  "black": $black,
  "blue": $blue,
  "indigo": $indigo,
  "purple": $purple,
  "pink": $pink,
  "red": $red,
  "orange": $orange,
  "yellow": $yellow,
  "green": $green,
  "teal": $teal,
  "cyan": $cyan,
  "deep-purple": $deep-purple,
  "light-blue": $light-blue,
  "light-green": $light-green,
  "lime": $lime,
  "amber": $amber,
  "deep-orange": $deep-orange,
  "brown": $brown,
  "blue-gray": $blue,
);

// -----------------------------------------------------------------
//function
// -----------------------------------------------------------------
// 背景色に合わせた文字色の設定
@function button-text-color($value) {
  // 色のrgb値をそれぞれ取得
  $r: red($value);
  $g: green($value);
  $b: blue($value);
  // 明度の計算
  $brightness: (($r * 299) + ($g * 587) + ($b * 114)) * 0.001;
  // rgb値0~255の中間。デザインによって微調整する。
  @if ($brightness >=128) {
    // 背景が明るい場合の文字色
    @return $black;
  } @else {
    // 背景が暗い場合の文字色
    @return $white;
  }
}

// 背景色に合わせたホバー時背景色の設定
@function button-hover-bg($value) {
  $r: red($value);
  $g: green($value);
  $b: blue($value);
  $brightness: (($r * 299) + ($g * 587) + ($b * 114)) * 0.001;
  @if ($brightness >=128) {
    // 明度を15%下げる
    @return darken($value, 15%);
  } @else {
    // 明度を15%上げる
    @return lighten($value, 15%);
  }
}

// -----------------------------------------------------------------
//ベースデザインの指定
// -----------------------------------------------------------------
.button {
  display: inline-block;
  color: inherit;
  text-decoration: none;
  border: solid 1px;
  padding: 0.5rem 3rem;
  transition: all 0.3s ease;
}

// -----------------------------------------------------------------
//色毎の指定
// -----------------------------------------------------------------
@each $color, $value in $button-colors {
  .button--#{$color} {
    color: button-text-color($value);
    border-color: $value;
    background-color: $value;

    &:hover,
    &:focus {
      background-color: button-hover-bg($value);
      border-color: button-hover-bg($value);
    }
  }
}

使用する色を設定する

最初に作成したいボタンの色と、テキストの色を登録します。
使いたい色をそれぞれ変数に入れ、マップで出力できるようにします。

// -----------------------------------------------------------------
//色の変数登録
// -----------------------------------------------------------------
//文字色としても使用
$white: #ffffff;
$black: #000000;

$blue: #42a5f5;
$indigo: #5c6bc0;
$purple: #ab47bc;
$pink: #ec407a;
$red: #ef5350;
$orange: #ffa726;
$yellow: #ffee58;
$green: #66bb6a;
$teal: #26a69a;
$cyan: #26c6da;
$deep-purple: #7e57c2;
$light-blue: #29b6f6;
$light-green: #9ccc65;
$lime: #d4e157;
$amber: #ffca28;
$deep-orange: #ff7043;
$brown: #8d6e63;
$blue-gray: #78909c;

// -----------------------------------------------------------------
//マップの生成
// -----------------------------------------------------------------
$button-colors: (
  "white": $white,
  "black": $black,
  "blue": $blue,
  "indigo": $indigo,
  "purple": $purple,
  "pink": $pink,
  "red": $red,
  "orange": $orange,
  "yellow": $yellow,
  "green": $green,
  "teal": $teal,
  "cyan": $cyan,
  "deep-purple": $deep-purple,
  "light-blue": $light-blue,
  "light-green": $light-green,
  "lime": $lime,
  "amber": $amber,
  "deep-orange": $deep-orange,
  "brown": $brown,
  "blue-gray": $blue,
);

関数を定義する

文字色の関数を定義する

次にボタンの背景色によって文字色を変更する関数を定義します。
下記のコードで取得した色($value)から、rgb値をそれぞれ取得しています。

  // 色のrgb値をそれぞれ取得
  $r: red($value);
  $g: green($value);
  $b: blue($value);

取得したrgb値から、色の明度を算出します。
W3Cでアルゴリズムが公開されているので、そちらを参考にしました。

また、SCSSの除算が推奨されていないので、乗算に変換して記述しています。

// 明度の計算
$brightness: (($r * 299) + ($g * 587) + ($b * 114)) * 0.001;

最後に算出された数値によって、文字色の指定をしています。
rgb値0~255の中間で128を指定していますが、ここはデザインによって微調整が必要かと。

// rgb値0~255の中間。デザインによって微調整する。
@if ($brightness >=128) {
  // 背景が明るい場合の文字色
  @return $black;
} @else {
  // 背景が暗い場合の文字色
  @return $white;
}

ホバー色の関数を定義する

文字色と同じ要領でホバー時の色の変化を定義します。
ほとんど同じですが、違う点は下記

@if ($brightness >=128) {
  // 明度を15%下げる
  @return darken($value, 15%);
} @else {
  // 明度を15%上げる
  @return lighten($value, 15%);
}

下の色の明度によってホバー時に明るくするか、暗くするか指定しています。
色の変更方法についてはこちらの記事でも解説しています。

デザインの指定

関数の設定が終わったので、最後に出力するCSSを記述します。
今回は.buttonでベースデザインの指定をし、.button--色で色毎の指定をしています。

// -----------------------------------------------------------------
//ベースデザインの指定
// -----------------------------------------------------------------
.button {
  display: inline-block;
  color: inherit;
  text-decoration: none;
  border: solid 1px;
  padding: 0.5rem 3rem;
  transition: all 0.3s ease;
}

// -----------------------------------------------------------------
//色毎の指定
// -----------------------------------------------------------------
@each $color, $value in $button-colors {
  .button--#{$color} {
    color: button-text-color($value);
    border-color: $value;
    background-color: $value;

    &:hover,
    &:focus {
      background-color: button-hover-bg($value);
      border-color: button-hover-bg($value);
    }
  }
}

終わりに

Bootstrapではボタンの色に応じて文字色とホバー色が自動で指定してくれるので、
便利だなーと思い、Bootstrap以外でも同じように使えるよう自作して見ました。

もし良ければ使用して見てください。

参考にさせて頂いた記事

Web制作に使えるおすすめの書籍

私が実際に購入して役に立った書籍を紹介します。
気になる本があればぜひ読んでみてください!

  • URLをコピーしました!
目次