RSCSSとFlexboxを使ってまるっと1ページコーディングしてみた。


自分なりの静的サイト構築をまとめます。 シチュエーション的には 「カンプが上がってきたものをコーディングする」 みたいな感じです。

今回は、「RSCSS」 という設計思想に基づいて作成していきます。

いくつかの簡単なルールがありますが、作りながら出てきたルールを書いていきます。 最後にまとめと、すべてのルールを書いたリンクをご紹介しますので、これを読む前にRSCSSを覚えてくる必要はありません。

注意:あくまでCSS設計について考えるという点で、セマンティクスやアクセシビリティに関する完璧なことは書かれていません。もしよければ、言及いただければと思います!また、スクリーンショットを完全に再現しておらず、余白などは大きく差異の発生しない範囲で簡略化しているものもあります。

必要な人のためにコードをすべて記述していますが、適宜読み飛ばして頂いてかまいません。 また、Sassでの利用を前提とした設計思想ですので、scss形式での記述をしています。

まずデザイン見渡す。

デザインがあがってきて一番やってはいけないことは突然コーディングを始めることです。
「料理の本を開いて突然料理を始める」 くらいアウトです。
最後まで見渡さずに突然ステップ1からはじめていくと、大抵、ステップ5くらいになって、「ここで200°のオーブンで焼きます」 みたいなことが突然でてきて 「なにそれ材料に書いてない!うちにあるのは電子レンジだけよ!」 みたいな状態になったことはありませんか? わたしはあります。ざっと見渡せばわかったはずなのに。

そういうことを防ぐためにも、ページカンプをざっくり見渡します。 デザイナーの意図を読み取ってあげるのが大切です。 デザイナーは意味もなく素敵デザインを追い求める芸術家ではありません。 彼らはデザイナーである以上ロジックに基づいてデザインをしています。

例えば、統一感を出すために意図的に使いまわされているスタイル なんかがあったりすることに気づくでしょう。

ざっくり分けて考える

コーディングをするまえに、ざっくりとセクション分けをします。 分ける理由としては、以下のような理由があります。

私なりに分けた結果がこちらです。

suda_layout.jpg

では、それぞれのセクションごとに組み込んでいきましょう。

ヘッダー編

機能で分けて考える(ヘッダー)

そうです、まだ分けて考えるんです。 機能で分けた1つ1つを、RSCSSでは 「Component(コンポーネント)」 として考えます。

ここでの分け方も厳密な正解はありません。 「機能」をある程度の目安としてください。

私なりにヘッダーを機能ごとに分けた結果が次の通りです。

suda_component.jpg

このように、「サイトタイトル」Componentと「アイキャッチ(バナー)」Componentの二つに分けて考えます。 それぞれ別の機能を持っているもので、お互いに独立していますね。 私は、「お互いに独立しているか?」 というのも機能で分離する目安にしています。

では、それぞれコーディングしていきます。

サイトタイトル

スクリーンショット 2016-12-01 4.07.01.png

「サイトタイトル」Componentは以下の2パーツで構成されています。

この構成要素をRSCSSでは Element(要素) と呼びます。 コードは次の通りです。

バズる→スダる

.site-title { >.logo { margin-bottom: 10px; } >.description{ font-size: 14px; } }

ここで使っているRSCSSの記述ルールはこちら

また「レイアウト用のスタイル」とは、以下のようなものとされています。

但し、width,heightに関しては、アバターアイコンやロゴなどはどうしても指定する必要があったりするため、必要に応じて使用を許可されています。 また、position: relative; についても、Elementの絶対配置に必要となる場合がありますので適宜使用してください。

では、続いて「アイキャッチ(バナー)」Componentを作成しましょう。

アイキャッチ(バナー)

スクリーンショット 2016-12-01 4.07.42.png

.hero-banner { width: 100%; height: 400px; background-image: url(https://placehold.jp/1100x500.png); background-size: cover; background-position: center; background-repeat: no-repeat; }

このように、Elementを持たないComponentもあります。 ここでは高さを固定し、背景画像にバナーを設定しています。

では、それぞれのComponentを配置する作業に移りましょう。

機能で分けたものをレイアウト(共通ヘッダー)

共通ヘッダー内の二つのコンポーネントをレイアウトします。 その時は「共通ヘッダー」Componentを考えます。 先ほど作った「サイトタイトル」Componentと「アイキャッチ(バナー)」Componentは構成要素、すなわちElementとして考えます。

//topを付与

バズる→スダる

//bannerを付与
.common-header { display: flex; flex-direction: column; padding: 10px 0; >.top { margin-bottom: 10px; } >.banner{/**/} //※記述なし、省略化 }

もしくはSassの@extendを用いて以下のようにもできます。

//*もともとあった.site-titleを削除

バズる→スダる

//もともとあった.hero-bannerを削除
@import .site-title; @import .hero-banner; .common-header { display: flex; flex-direction: column; padding: 10px 0; >.top { @extend .site-title margin-bottom: 10px; } >.banner{ @extend .hero-banner } }

お好みの運用を選んでいきましょう。僕は前者の方が好きです。 今後はこの記事では前者による記述を行っていきます。

フッター編

機能で分けて考える(フッター)

suda_footer.jpg

サイトタイトル

スクリーンショット 2016-12-01 4.08.51.png

よく見ると、「サイトタイトル」Componentは「共通ヘッダー」のものと見た目が少し違うことがわかりますね。 ここは、以下のようにしましょう。

//-centerを付与

バズる→スダる

.site-title { >.logo { margin-bottom: 10px; } >.description{ font-size: 14px; } &.-center{ // display: flex; // flex-direction: column; //追加記述 align-items: center; // } // }

-centerのように、見た目違いを表す-で始まるclassを「Variants」と言います。 site-title.scssに記述を追加しました。 最近話題のFlexboxを使って中央揃えレイアウトをしてみました。

コピーライト

スクリーンショット 2016-12-01 4.09.25.png

.copyright-block { line-height: 1.5; font-size: 12px; }

RSCSSのルール「Componentを表す部分は単語2つを-でつなぐ」のために2単語が思いつかないときは ブロック要素なら

インライン要素なら

などのような表し方を推奨されています。

機能で分けたものをレイアウト(フッター)

ヘッダー同様、作成したComponentをElementとして考えていきます。

.common-footer { display: flex; flex-direction: column; align-items: center; padding: 20px; >.title { margin-bottom: 20px; } >.copyright {/**/} //記述なし、省略化 }

サイドバー編

機能で分けて考える(サイドバー)

Componentに分けてみるとこんな感じになりました。

suda_sidebar.jpg

プロフィールカード

suda_sidebar_profile.jpg

内容的にいろいろ突っ込みどころの多いプロフィールComponentですが作成しましょう。 (Twitterのフォローボタンについてはtwitter側で生成するページがあるので割愛します)

スダシュウゴのプロフィール

スダシュウゴ

茨城県を中心に活動しているフリーのWebデザイナー。おっぱいへの執着心が強い。
『コソアドデザイン』代表

.profile-card { padding: 40px 15px 10px; position: relative; background: white; >.title { padding: 3px 20px; background: #13b0fc; color: white; position: absolute; top: 0; left: 0; font-weight: bold; } >.image { flex-grow: 0; } >.name { font-size: 20px; line-height: 2; } >.description { margin-top: 10px; font-size: 14px; line-height: 1.6; } }

ここではComponentにposition: relativeを指定していますが、Element配置に使用しているため問題ありません。

問い合わせボタン

スクリーンショット 2016-12-01 4.10.10.png

fa fa-envelopeは「fontawesome」に使用するclassです。aria-hidden="true"はスクリーンリーダーから見えなくするための記述で、説明は割愛します。

お問い合わせはコチラ! .basic-button { display: flex; padding: 10px 15px; color: white; align-items: center; background: #dd8500; >.icon { padding-right: 10px; border-right:1px solid white; margin-right: 10px; width: 20px; } >.label { text-decoration: none; font-weight: bold; } }

人気の記事リスト

suda_sidebar_articlelist.jpg 記事カードそのものが1つの機能をもつComponentで、リストはその集合体と考えるのが良さそうですね。

記事カード単体のコードは次の通りです。

.article-card { display: flex; >.metabox { display: flex; flex-direction: column; padding-left: 10px; } >.metabox >.title { font-size: 16px; margin-bottom: 10px; } >.metabox >.count { font-size: 10px; } }

RSCSSの推奨事項として、Sassで書く時のネスト階層は2段階までに抑えるというものがあります。 なので、上記のようにあえてネストを避けた記述をしています。

また、Elementの命名ルールに従い.meta-boxのようにしたいところを.metaboxのように1単語にくっつけています。

人気の記事リスト全体のコードは次の通りです。

.hot-articles { >.heading { font-weight: bold; line-height: 2; } >.list { padding: 0; list-style-type: none; display: flex; flex-direction: column; } }

最初、記事カード単品を<div>で書いていたのに、リストでは<li>になっていることにお気付きですか? このように、すべてclassでの運用を行っているため、要素を変更することができるのです。 これはすべてclassで運用している利点でもあります。

また、今回はセマンティクスを無視したマークアップをしていますが、適宜<div><section><header><footer>などに変えても問題ありません。classセレクタのみで運用することで要素の変更にも強いCSSになります。

機能で分けたものをレイアウト

ヘッダー、フッターと同様に、サイドバーComponentを考えます。 コードは下記のようになります。

スダシュウゴのプロフィール

スダシュウゴ

茨城県を中心に活動しているフリーのWebデザイナー。おっぱいへの執着心が強い。
「コソアドデザイン」代表

お問い合わせはコチラ!
.side-section { display: flex; flex-direction: column; >.profile { margin-bottom: 20px; } >.contact { margin-bottom: 20px; } }

メイン編

もう慣れてきましたか? 最後のセクションです。 suda_layout_main.jpg

機能で分けて考える(メイン編)

ページネーション

スクリーンショット 2016-12-01 4.06.27.png

.pagination-link { list-style-type: none; padding: 20px 0; display: flex; align-items: baseline; > .number,.next { border: 1px solid #ccc; padding: 5px 8px; font-size: 13px; text-transform: capitalize; &.-current { font-size: 16px; } &:not(:last-child) { margin-right: 5px; } } .link { text-decoration: none; } }

-currentのように、VariantがElementについています。 Variantは、Elementにもつけることができます。

RSCSSに直接関係するものではありませんが :not(:last-child) という擬似クラスに注目してください。 これは、「最後の子要素以外」 を表しています。 今までは、すべての要素にstyleを指定したあと:last-childに打ち消しスタイルを当てていたことが多いかと思いますが、この記述だけでスマートに表現できます。

記事カード

スクリーンショット 2016-12-01 4.12.11.png

記事カードですが、これはサイドバーの記事カード単品Componentに投稿日とタグが増え、タイトルの装飾が変わったものですね。 これを全く別コンポーネントと解釈するか、見た目違いと解釈するかは人次第ですが、私だったらここは見た目違いと考えます!

article-cardsにElementを追加し、.titleはVariantsで調整をかけましょう。 また、レイアウト用コンポーネントとして.row-itemsを作成しました。

.article-card { display: flex; >.metabox { display: flex; flex-direction: column; padding-left: 10px; } >.metabox >.title { font-size: 16px; margin-bottom: 10px; } >.metabox >.count { font-size: 10px; } >.metabox >.time { font-size: 14px; margin-right: 10px; } >.metabox >.layout-row { display: flex; align-items: baseline; } .categoryicon,.tagicon,.timeicon { margin-right: 10px; } .categoryitem,.tagitem { text-decoration: none; font-size: 12px; color:#666 ; } &.-large >.metabox >.title { text-decoration: none; font-weight: bold; color: #333; } }

今回の例だと、ネストが深くなりすぎるので追加したElementはComponent化したほうがいいかもしれません。

あとはこのカードたちを並べましょう。 :not(:last-child)を使って最後のアイテム以外に破線ボーダーを加えたらよさそうですね。

.article-list { >.item:not(:last-child) { padding-bottom: 20px; margin-bottom: 20px; border-bottom: 1px #ccc dotted; } }

シェアボタン

スクリーンショット 2016-12-01 4.13.16.png

これらは問い合わせボタンの色違いアイコン違いですね。 Variantsでbackgroundを変更すると早そうです。 一気にリストのComponentまで作ってしまいましょう。

.basic-button { display: flex; padding: 10px 15px; text-decoration: none; color: white; align-items: center; &.-contact { background: #dd8500; } &.-twitter { background: #55acee; } &.-facebook { background: #3b5998; } &.-google { background: #dc4e41; } &.-pocket { background: #f03e51; } &.-hatebu { background: #00a5de; } &.-line { background: #25af00; } >.icon { padding-right: 10px; border-right: 1px solid white; margin-right: 10px; width: 20px; } >.label { font-weight: bold; } } .sns-share { display: flex; padding: 0; list-style-type: none; flex-wrap: wrap; justify-content: space-between; li{ width: calc(100%/3 - 10px); &:nth-child(-n+3){ margin-bottom: 10px; } } }

これでメインコンテンツのすべてのコンポーネントが出揃いました。 あとは、メインセクションComponent内に配置しましょう。

機能で分けたものをレイアウト(メイン)

.main-section { padding: 30px 50px; background: white; }

セクションをページ内に配置する

一番最初に4つに分けたセクションが出揃いました。 あとはこれらをページ内に配置するだけです。

方針としては、サイドバーとメインエリアを左右に並べるための.content-sectionというComponentを挟んでレイアウトをしていきます。

.content-section { display: flex; justify-content: center; >.main-section { flex-basis: 740px; margin-right: 20px; } >.side-section { flex-basis: 320px; } }

仕上げに全体の調整をします。

.all-wrap { width: 1080px; margin: 0 auto; >.header { margin-bottom: 10px; } >.main { margin-bottom: 10px; } }

以上でコーディングが終了しました。

まとめ

RSCSSというCSS設計についてより引用 (公式ガイドラインの和訳をされています。本記事でRSCSSに興味を持たれた方はご一読ください)。

参考リンク

サンプルページは茨城のフリーランスデザイナー/カメラマンのスダシュウゴ氏のページを使用させていただきました。 スダ部 コソアドデザイン

公式ガイドライン RSCSS.io RSCSSというCSS設計について

最後に

この記事は スダ Advent Calendar 1日目の記事です。 CSS設計に迷える人達に少しでも手助けになれればいいなと思います。 最後までお読みいただきありがとうございました。