エンジニアの三浦です。
業務で新規サービスを構築する中で、カラーコードの定義方法のベストプラクティスがわからず、手戻りが発生するケースがあったので、自戒も込めて記事に残します。
経緯
基本的にWebアプリは特定の色に制限して配色を決定します。 よって開発着手段階で、エンジニア、デザイナー間でどのカラーコードをどのくらいの割合で使用するのか共通認識をとっておくことで、画面設計通りのWebアプリ開発が可能になります。
弊社では基本的にデザイナーが作った画面設計を元にエンジニアがデザインも込みで実装を進めるのですが、ここで以下の問題が発生しました。
- ① デザイナーが画面設計内で定義しているカラー変数とエンジニアが使っているカラー変数が異なる
- ② エンジニアがカラーコードを直接CSSで当てている箇所があり保守が大変になる
- ③ CSSフレームワークが提供するコンポーネントを使用している箇所で意図しない色が発生する
何が問題なのか
一番の問題はデザイナーが定義している画面設計と異なる色が使われてしまうことです。これによって画面設計段階のUIが保たれず、成果物のUXを損ねかねません。
解決策
①は、CSSフレームワークで表現できるカラー変数おけるデザイナーの認識が異なるためです。カラー変数を実際に使うのはエンジニアなので、認識違いを発見した都度デザイナーに確認をとることで回避できます。
②、③は、エンジニアがカラーコードの直接指定をせず、カラー変数を使用して色をあてることで回避できます。ここでのカラー変数は個別で新しく変数を作成するのではなく、CSSフレームワーク内で使われているカラー変数を上書きします。
ここで③について詳しく見ていきます。
③の問題の再現
(使用した環境は記事末尾に記載しています)
- Next.jsのプロジェクトをTypeScriptオプションで作成します。
$ yarn create next-app --typescript
$ cd verify_css_modules_behavior_app $ yarn dev
- 必要なパッケージを追加します。
$ yarn add bootstrap $ yarn add react-bootstrap $ yarn add sass
- index.tsxを以下に修正します。
// index.tsx import type { NextPage } from 'next' import { Button } from 'react-bootstrap' const Home: NextPage = () => { return ( <div className='d-flex justify-content-center align-items-center min-vh-100'> <Button variant='primary' > テスト </Button> </div> ) } export default Home
- globals.cssの拡張子をscssファイルに変更して、中身を書き換えます。
// globals.scss @import '~bootstrap/scss/bootstrap';
- _app.tsxのインポートを更新します。
// _app.tsx import '../styles/globals.scss' // 変更 import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return <Component {...pageProps} /> } export default MyApp
- http://localhost:3000/にアクセスします。
- BootstrapのPrimaryのボタンが表示されるのが確認できます。
- ここで、Bootstrapで定義されているprimaryの変数を更新してみます。
// globals.scss $primary: red; @import '~bootstrap/scss/bootstrap'; :root { $primary: $primary; }
- 再度、http://localhost:3000/にアクセスします。
- Primaryが更新されてボタンが赤色に変わりましたが、ボタン内のテキストの色が何故か白から黒に変わっているのがわかります。
- このようにCSSフレームワークのコンポーネントは、理想的な配色がされるようにチューニングされています。
CSSフレームワークの管理から外れるとは?
- 自前で新しい変数を定義したり、カラーコードを直接指定したりすることです。
- CSSフレームワークの管理から外れてカラーコードを設定することで、意図しない場所へ影響が出てしまいます。
- Bootstrapで定義されている変数の一覧は以下なので、これを上書きして使うようにします。 github.com
Bootstrapの変数を上書きする具体例
// scss-docs-start theme-color-variables $primary: $blue !default; $secondary: $gray-600 !default; $success: $green !default; $info: $cyan !default; $warning: $yellow !default; $danger: $red !default; $light: $gray-100 !default; $dark: $gray-900 !default;
// app.scss $font-family-sans-serif: 'Noto Sans JP', 'Yu Gothic', '游ゴシック', YuGothic, '游ゴシック体', 'ヒラギノ角ゴ Pro W3', 'メイリオ', sans-serif; $primary: #69709e; $secondary: #00a0e9; $purple: $primary; $danger: #e95384; $warning: #f6ab00; @import '~bootstrap/scss/bootstrap'; :root { @each $color, $value in $purples { --#{$variable-prefix}#{$color}: #{$value}; } @each $color, $value in $grays { --#{$variable-prefix}#{$color}: #{$value}; } }
まとめ
以上のように、アプリで使用するCSSフレームワークに応じて、都度エンジニア、デザイナー間でカラー変数の認識を合わせて開発を進めることで、手戻りなく画面設計通りのアプリ開発ができるようになると思います。
初めて使うフレームワークだと、このカラー変数の定義方法の調査を後回しにして、カラーコード直指定で開発を進めてしまうケースがありました。100%徹底する必要はないかもしれませんが、将来的な手戻りを防止するためにも気をつけていきたいです。
環境
- Next.js
- ReactBootstrap