【CSS設計】FLOCSSって何?読みやすいCSSの書き方を説明します
こんにちは。あっきーです。フリーのwebプログラマーとしてホームページ制作やサービスを作っている、
最近、夜活人間から朝活人間へと恐るべき進化を遂げた者です。
今回は「CSS設計の一つFLOCSSって超使えるよ」というテーマで話していきます。
CSSを書いている方でこんな経験したことありません?
- 文字色とか背景とか変えたいけどどこに書いたか分からなくなった
- クラスの名付け方に迷った
- ちょっとした装飾にいちいち固有のクラスをつけるのはだるい
CSSって自由に書けるし、初学者にとっても優しいプログラミング言語なので、こういう困難にぶつかることは日常茶飯事なんですね。
このような「ごちゃごちゃ」を解決する方法がこのFLOCSSというものです。
詳しく見ていきましょう。
あと、SASSを使うにあたってwebpackという機能も使っていくのでこれらの知識は最低限もっておきましょう。
FLOCSSはCSS設計の一つ
FLOCSSというのはCSSの書き方のテンプレートのことです(読み方は「フロックス」)。
「CSSをきれいに書く方法を考えましょう」というのを「CSS設計」と呼ぶのですが、CSS設計は研究されていて、何パターンかあります。
そのうち最も良い(と個人的に思っている)のがFLOCSSです。
FLOCSSはCSSファイルを3つの種類に分ける
cssファイルを原則3つのカテゴリーにわけて設計していきます。そのカテゴリーというのが以下の通り
- Foundation(初期設定):サイト全体の初期設定を書いたもの
- Layout(共通部分の設定):ヘッダーとかフッターとか共通で使われるもの
- Component(部品の設定):部分部分で使うもの
またComponentは3つに分かれます。
- component(使いまわし要素):ボタンなどサイト内で使いまわせるもの
- project(大きめの部分的に使う要素):componentを複数使って構成されるもの
- utility(ちょっとした装飾):「文字を赤にする」など1つだけの機能をもつもの
具体例を挙げながら説明しますが、ポイントは「CSSを機能別に分割していきますよ」ということです。
さっそく手を動かしながら書き方を見ていきましょう。
・・・の前に準備です。
sassやwebpackの準備
まず、sassやwebpackを使えるようにインストールします。
package.json
ファイルを作り、以下をコピペしてください。
{
"name": "test",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev": "webpack --mode development",
"production": "webpack --mode production",
"watch": "webpack --mode development --watch"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"autoprefixer": "^10.2.5",
"css-loader": "^5.2.0",
"import-glob-loader": "^1.1.0",
"mini-css-extract-plugin": "^1.4.0",
"node-sass": "^5.0.0",
"node-sass-glob-importer": "^5.3.2",
"postcss-loader": "^5.2.0",
"sass-loader": "^11.0.1",
"style-loader": "^2.0.0",
"webpack": "^5.28.0",
"webpack-cli": "^4.6.0"
},
}
あとはnpm install
をすれば必要なものがインストールされます。
また、webpack.config.js
を作成し以下を書いてください。
// output.pathに絶対パスを指定する必要があるため、pathモジュールを読み込んでおく
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const globImporter = require('node-sass-glob-importer');
module.exports = {
// モードの設定、v4系以降はmodeを指定しないと、webpack実行時に警告が出る
mode: 'production',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
// 対象となるファイルの拡張子(scss)
test: /\.scss$/,
// sassファイルの読み込みとコンパイル
use: [
// cssファイルを書き出すオプションを有効にする
{
loader: MiniCssExtractPlugin.loader,
},
// cssをバンドルするための機能
{
loader: "css-loader",
options: {
// オプションでcss内のurl()メソッドを取り込まない
url: false,
// ソースマップの利用有無
sourceMap: true,
// Sass + PostCssの場合は2を指定
importLoaders: 2,
},
},
// PostCssのための設定
{
loader: "postcss-loader",
options: {
//postcss側でもソースマップを有効
sourceMap: true,
postcssOptions: {
// ベンダープレフィックスを自動付与する
plugins: ["autoprefixer"],
},
},
},
// sassをバンドルするための機能
{
loader: "sass-loader",
options: {
// ソースマップの利用有無
sourceMap: true,
// importer: globImporter(),
},
},
{
loader: 'import-glob-loader'
}
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "style.css",
}),
],
// source-map方式でないと、CSSの元ソースが追跡できないため
devtool: "source-map",
};
次にsrc
フォルダを作成しその中にindex.js
を作成します。ここに以下を記述。
import "./style.scss";
これで、style.scss
(これから作る)の内容がcssファイルに書き換えられるようになります。
FLOCSS用のフォルダを作成
次は先ほど見たようにファイルを分割するようのフォルダを作成しましょう。
src
フォルダの中にsass
フォルダを作成します。
その中に以下のような構成でフォルダを作成してください。
/sass
|- foundation
|- layout
|- object
|- component
|- project
|- utility
最後にsrc
フォルダ直下にstyle.scss
を作成し、以下のように編集します。
@import './sass/foundation/**';
@import './sass/layout/**';
@import './sass/object/**';
ここでは、sass
フォルダにあるすべてのファイルを一度style.scss
で統合しています。
その後index.js
によってcssファイルに書き換えられます。
(今回の設定の場合、dist/style.css
が作られます。)
これで、準備は整いました。
FLOCSSのfoundation、layout, objectの機能
では、FLOCSSの3つのカテゴリーについて実際に手を動かしながら説明していきます。
foundation
:基本設定を作ってみる
foundation
フォルダにはサイト全体の設定を行います。具体的には以下の通り。
- pタグやh2タグなど、各セレクタの初期設定(
_reset.scss
) - sassで使う変数の定義(
_variables.scss
) - sassで使う関数(mixin)の定義(
_mixin.scss
)
ちなみに、ファイルの名前の付け方は決まっていて
- クラス名をそのままつける(
.l-header
について書くならファイル名はl-header.scss
) - アンダーバー(_)+クラス名(
.l-header
について書くならファイル名は_header.scss
)
詳しくは以降で。当サイトでは2つ目を採用しています。
セレクタの初期設定を作る
htmlタグには最初からある程度レイアウトがついているものがあります。
pタグ,hタグにはmargin-bottom
がついていますし、ulタグにはpadding-left
がデフォルトで設定されています。
他にもhタグの文字サイズだったり、aタグの文字色だったりも初期設定がされています。
webサイトを作る時にこういう設定が邪魔なことが多いので自分用に初期設定をしましょう。
ここでは省略します。
変数を定義する(_variables.scss
)
sassでは変数を定義することができ、これによってコードの記述が楽になります。
以下3つを定義しておくと後々便利だと思います。
- 色
- サイズ
- フォント
例としていくつか設定してみましょう。
//color
$blue : #00bfff;
$light-blue : #87cefa;
//size
$spacer : 1rem;
$text-lg : 1.25rem;
関数を定義する(_mixin.scss
)
また、sassでは関数を定義することができます。よく使う組み合わせを関数でまとめておくと記述量が減らせて見やすくなります。例として以下を書いてみましょう。
//flexの設定
@mixin flex($justify: center, $align:center) {
display: flex;
justify-content: $justify;
align-items: $align;
}
よく使う例としてflex
です。
基本的にjustify-content
とalign-items
がセットになるので関数にまとめておくと楽です。
layout
:サイトで共通する要素を設定する
layoutではサイト全体で使う要素の設定を行います。サイト全体で使うものと言えば以下のタグですね。
header
main
footer
nav
例として、ヘッダーに用に作ってみます。_header.scss
を作成して以下を記述。
.l-header {
width: 100%;
height: 50px;
padding: $spacer;
}
いくつか注意があります。
- サイズなど全体の設定のみを行う
l-
の形でクラスを定義する
まず、layout部分では横縦幅や余白の設定だけをします。
そして、クラス名は原則l-
から始まるようにします(このlはlayoutの頭文字)。
フッターについてならl-footer
、navタグについてならl-nav
といった具合です。
これは他のカテゴリーでも同じです。
- component →
c-
- project→
p-
- utility→
u-
また、先ほどファイル名について触れたんですが、このl-
とかの接頭語をそのまま使うか、_
に書き換えるかのどちからで名付けてください。
また、layoutは基本的にファイル数も記述量も少ないので安心してね。
object
:部分要素を設定する
ここが一番重要です。ここは3つに分かれています。
component
:再利用できる部分
component
には複数の場所で使える汎用性ありの要素について設定します。
bootstrapの知識がある人はそれと見比べてもらえばOKです。
例えばbootstrapでボタンを使いたいとき以下のように書きますよね。
<button class="btn btn-primary">ボタン</button>
これです。これがcomponentです。
1つボタンの装飾を作っておけばどこでも使えるようになるわけです。
試しに作ってみましょう。_button.scss
を作成して、以下のように記述しましょう。
.c-button {
padding: $spacer;
border: none;
border-radius: 10px;
margin: $spacer;
background: $blue;
outline: none;
transition: 300ms;
&:hover {
background: $light-blue;
}
}
componentなのでクラス名はc-
で始まります。
また最初に作った変数も使ってあげるとなお良いですね。
また、htmlにコードを書きましょう。
<a href="" class="c-button">もっと見る</a>
これで表示するとリンクボタンが出来上がります。
もう一つ例を出しましょう。_box-content
を作成して以下を記述。
.c-box-content {
margin: $spacer;
width: 300px;
height: 300px;
box-shadow: 1px 3px 6px #acacac;
transition: 300ms;
&:hover {
transform: translateY(-10px);
}
&__img {
img {
width: 100%;
}
}
&__title {
font-weight: bold;
font-size: 18px;
}
}
そして、htmlでコードを書きます。
<div class="c-box-content">
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div>
<h2 class="c-box-content__title">こんにちは。</h2>
<p class="c-box-content__description">プログラミングって楽しいよね</p>
</div>
するとカーソルを載せたときにふわっと浮くような部品が出来上がります。
ファイルごとに機能を分けるので、複数のものを書かないでくださいね。ボタンならボタンだけの機能を書きます。
こんな感じで、使いまわしできそうなものはcomponentでまとめていきます。
project
:特定の場所で使う大きめの部品
ブログとかを作る時ってサイドバーにプロフィールを載せたり、トップページに記事一覧などを載せたりしますよね。
「プロフィール」や「記事一覧」はコンポーネントにするには大きすぎるので、projectに入れてしまいます。
試しにやってみましょう。ここではランキングを作ってみます。
_ranking.scss
を作成し以下を追加。
.p-ranking {
background: #ececec;
&__content {
@include flex
}
}
htmlでは以下のように記述。
<div class="p-ranking">
<div class="p-ranking__content">
<div class="c-box-content">
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div>
<h2 class="c-box-content__title">1位!!</h2>
<p class="c-box-content__description">やった1位!</p>
</div>
<div class="c-box-content">
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div>
<h2 class="c-box-content__title">2位!!</h2>
<p class="c-box-content__description">まあまあ2位!</p>
</div>
<div class="c-box-content">
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div>
<h2 class="c-box-content__title">3位!!</h2>
<p class="c-box-content__description">ミスった3位!</p>
</div>
</div>
<div class="d-flex justify-content-end">
<a href="" class="c-button">もっと見る</a>
</div>
</div>
(一部bootstrapを使ってます。)
これで実行してみるとこんな感じになります。
このように、大きめの部品はprojectにまとめていきます。
utility
:ちょっとした装飾
上の例で、「1位」の文字だけ赤文字にしたいとします。
普通にcssをやっている方ならこんな方法が思い浮かぶかもしれないですね。
nth-child
などを使って指定する- 新しくクラスを作る
ただ、nth-child
を使うとちょっと複雑になりますし、文字色のためだけにクラスを作るのも気が引けます。
そこで使うのがutilityです。
Bootstrapで見ると分かりやすいんですが、文字色を青にする場合text-primary
クラスに付けるだけでOKです。
こんな感じで、「文字色を青にする」や「余白を15px広げる」という1つだけの機能を持ったクラスをutilityにまとめていきます。
今回の例では、_text-red.scss
をつくって以下を書きます。
.u-text-red {
color : tomato;
}
そして、htmlのランキング最初の要素にこのクラスをつけます。
<div class="c-box-content">
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div>
<h2 class="c-box-content__title u-text-red">1位!!</h2> <!-- ←このh2タグにu-text-redをつける -->
<p class="c-box-content__description">やった1位!</p>
</div>
こうすると「1位」の文字だけ色が赤に変わります。
このように、ちょっとした装飾をするために使われるのがutilityの部分です。
以上でFLOCSSの各カテゴリーを見てきました。後はちょっとだけ補足です。
クラス名の書き方
クラス名の書き方なんですが、MindBEMdingという方式を取り入れてます。
{接頭語}-{ブロック}__{要素}--{装飾}
先ほどのボタンの例を見るとこういう記法を使っているのが分かります。
<div class="c-box-content"> <!-- c-が接頭語、box-contentがブロック -->
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div> <!-- imgが要素 -->
<h2 class="c-box-content__title u-text-red">1位!!</h2> <!-- titleが要素 -->
<p class="c-box-content__description">やった1位!</p> <!-- descriptionが要素 -->
</div>
このようにすることで各要素の意味が分かりやすくなったり、後の修正にも使えます。
ここでは装飾が出てきませんでしたが、例えば「1位!!」を赤文字にしようとu-text-red
を使いましたが、代わりにc-box-content__title--red
を用意してあげることで赤文字にすることができます。
// _ranking.scss
.p-ranking {
background: #ececec;
&__content {
@include flex
&__title { //追加
&--red {
color : tomato;
}
}
}
}
<div class="c-box-content">
<div class="c-box-content__img"><img src="dist/img/TSU1994064_TP_V4.jpg" alt=""></div>
<h2 class="c-box-content__title--red">1位!!</h2> <!-- 変更 -->
<p class="c-box-content__description">やった1位!</p>
</div>
layoutとprojectの違い
「大きな部品をまとめる」という意味ではlayoutとprojectは似ていますが、この2つは使い分けます。
- layout : 全サイトに共通(ヘッダーとかフッターとか)
- project : 一部のページで使う
layoutはほとんど書くことがありませんが、projectは量が多くなることが一般的です。
componentとprojectの違い
また、componentとprojectも似ているので混乱しそうですが、ここも明確に違いをつけましょう。
- component: どのページでも使える部品。固有の意味は持たない
- project: 一部のページで使う部品。固有の意味を持つ
例えばc-button
やc-box-content
はあらゆる場所で使えます。
また、これらに特定の意味は持っていません。言い換えれば使い方次第で意味が変わります。
c-buttonはリンクやフォームのボタンに使えますし、c-box-contentは記事一覧、ランキング、モーダルウィンドウなどに
使えます。
一方p-ranking
はあまり使いまわしができません(頑張ればできるけど)。
「ランキングを表示する」というためにしか使われないからです。
これは言い換えれば「ランキングを表示する」という特定の意味を持っています。
超ざっくり言えば「projectは複数のcomponentで成り立つよ」です。
まとめ:CSSSは重要です
ということで以上です。やってみて分かったと思いますが非常に整理されていますよね。
1つのファイルのコード量が減りましたし、機能別にファイルを分けているので修正も容易です。
クラス名に迷うことも無くなります。
大きなものを作ったり複数人でやる場合はこうした設計が生きてくるので活用してください。
それでは、良い1日を過ごしましょう。
スポンサードサーチ
人気記事英語学習用SNSをLaravelで作ってみた【システム解説あり】