20200226のCSSに関する記事は8件です。

Top 30+ CSS & CSS3 Interview Questions and Answers 2020

Mostly asked CSS & CSS3 Interview Questions with Answers in 2020. Reading these questions once will give you a ton of confidence, and you will be ready to move out for an interview. Let’s begin.

click here to read more
https://www.positronx.io/top-css-css3-interview-questions-and-answers/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

脱・AtomicDesign - HTML+CSSコーディングの粒度分類法(HTML Parts)

はじめに

HTML+CSSコーディング専用の粒度分類を紹介します。
この仕組みは、デザインやワイヤーフレームなどの視覚情報を分解することに焦点をあて、分解した対象を部品化する流れも併せてガイド化した汎用手法です。
世の中には、コーポレートサイト / ポータルサイト / サービスサイト / システム管理画面 / ブログサイト… といった様々な種別のサイト、Webページがありますが、これらの「完成予想図(視覚情報)」を同じ方法で分解して、コーディング用の部品にできます。

粒度と言えばAtomicDesignが有名ですが、この「HTML Parts」も粒度そのものの考え方についてはAtomicDesignの踏襲です。その上で「思考の入り方・捉え方」や「名称と定義」をコーディング側に寄せることで、CSS設計やコーディング業務を標準化しやすくしています。

※この記事は標準化ノウハウ公開の一環として書いています。
仕組みの概要や前提事項などについては「UltimateCoding 概要・前提事項」のエントリをご確認ください。

前置きとAtomicDesign

そもそもAtomicDesignをコーディング視点で評するのはお角違いかもしれませんが、業界の一部では"万能薬"として組み入れる試みがあったのも事実です。それほど、画期的かつ魅力的な概念でした。主題に入るまえに「なぜ万能になり得なかったのか」を簡単に箇条書きします。

AtomicDesignの特徴

  • 小さなものから積み上げていく概念と、多くのコーディングで必要となる分解の行動が相反する
  • TemplatesとPagesが別の意味を喚起してしまい、そのままコーディングに使うと混乱する
  • サイト種別や規模によっては、図のA側に欲しい粒度が一つ不足することがある

といった所でしょうか。良い解決方法があるかのもしれませんが「そのままの状態で万能か?」と言われたら、そうではないでしょう。これは、AtomicDesignが不出来といいたいのではなく、専用に作られていないものを転用して使おうとしても、やはりどこか無理が出てくる。というお話です。

HTML Partsの概要

では、本題の「コーディング側から考える粒度分類」の話です。
HTML Partsは、以下のようにデザインやワイヤーフレームを「大きなものから小さなものへと分解」する事で粒度を分類します。

視覚情報の分解ステップ
この方法は、改めて言われなくとも既に多くの制作者が自然とおこなっているであろう流れ・ステップです。こういった一般的な流れの上にガイドを沿えることで、思考による変換や再構築を発生させず、負担がかかりにくいものとして提起します。

また、これがもしAtomicDesignによって「システマチックに作られたプロダクト」であったとしても、同じように上から綺麗に分解できることでしょう。
AtomicDesignで作られたものの分解

実用の見通しと説明内容

粒度の概念を実際のコーディングに実用するためには、以下の3つの内容把握と、Sassファイル管理の仕組みが必要となります。

  1. 視覚情報の分解方法 を把握
  2. 部品再利用設計の考え方 を把握
  3. 粒度の定義 を把握

以降、上記の順に従って説明します。
Sassファイルの管理方法については、最後に要点を述べた上で、今後別の記事で詳しく説明します。

1 ・ 視覚情報の分解方法

まず1つめの、具体的にどのように分解するのかについての説明です。
方法はいたってシンプルで、分解する対象である「完成予想図」を用意し、以下の図のように大きなものから4つの粒度によって分解していきます。

視覚情報の分解方法
図は企業系サイトを例にしていますが、サービス系サイト、ポータル系、システム管理画面、LP、ブログなど、どんな種別であっても「Webページの視覚情報」がある限り、分解手順そのものは同じです。

また、上記の図と、この記事の情報は、過去記事「1段上のCSS設計・コーディングの概念図」の内容と連動しています。この記事を単独で読んでも意味は通じますが、より良く利用したい場合には併せてご覧下さい。
HCDCモデル図
図との対応としては、左の2つの概念を実用するためのガイドが「HTML Parts」です。「Block」が今回のBlockと等価で、「Parts」が、今回のModule / Component / Elementに細分類されます。

2 ・ 部品再利用設計の考え方

粒度の具体的な説明に移る前に、重要な考え方・ポイントを先に説明します。
何かというと「粒度分類と実装は別で考える」という事です。ここを一緒にして捉えると後で混乱のもとになるため、先に2つの意味を説明します。

1 ・分類は必ず発生している

まず、分類そのものは常に発生しています。どういうことかというと、仮に、デザインやワイヤーフレームを紙に印刷して、ペンで四角い線を引いて分解しながら囲っていったとします。もうこれ以上分解できない。という所まで線をひくと、実質、紙の上に全ての粒度が洗い出されたことになります。
そして、特定の部分を見て、「AtomicDesignではこれはAtomsと呼ばれている」とか、今回の「HTML PartsであればElementと呼ばれている」というように、変わりようのない定義・事実として認識できます。

これが、分類は必ず発生している。という意味です。そして、この時点では実装に関する決めごとは何も発生していません。決める(設計する)のは制作者です。

2 ・どのように部品化するのか

次に、部品をどのようなコードで実装するか。という話です。
判断・意思決定するのは1つだけ。「その対象(部品)を、グローバルに再利用するかどうか」です。これが、CSS設計が大きく切り替わるポイントとなります。

「グローバルに再利用する」とは、以下のようなものです。

これは、CSS設計手法の「OOCSS」と同じ方向にある手法で、システム管理画面やサービス系サイトなどの「システマチックなサイト」で利用したくなるものです。

もし、上記のように再利用しないのであれば、その部品は以下のように「上位粒度の所有物」としてスタイリングします。


これらの図をテキストでまとめると以下のようになります。

1・単体でグローバルに再利用できるCSSを書く
図:スタイリングパターンA
2・上位粒度の所有物となるCSSを書く
図:スタイリングパターンB
図:スタイリングパターンC

そして、これらを「サイト全体視点」と「部品単独視点」の2つの軸で判断していくことが、「CSS設計」の中核であり重要ポイントになります。

これらの前提を踏まえた上で、以下から粒度の説明をおこないます。

3 ・ 粒度の定義把握

各粒度の詳細説明です。
それぞれに細かな定義や判断基準などを記載していますが、先述の通り「粒度分類と実装は別」であり、これらはあくまで制作のためのガイドです。制作者の判断以上に強い立場ではありません。

レギュレーションによって「完全遵守・例外は認めない」と定めるなら話は別ですが、そうではないなら「その視覚情報をどのようにコード管理したいのか」という、制作者の意思・意図を優先し、"ねばならない"の思考に捕らわれることがないようご注意下さい。

1 ・ Block

Block(ブロック)は、情報の意味や役割的に自立・独立した領域や区画・塊です。
機能・役割・情報属性などの基準によって、制作者が「これ以上は他と同じにできない」と判断した範囲によって切り出します。

Block参考イメージ

多くの場合はdivによるコンテナに名前が与えられます。

Blockの粒度判断

粒度の判断は、主たる情報である「コンテンツ」と、ヘッダー・フッターなどの「フレーム」部分とで分けて考えることができます。具体的には以下のようになります。

  • コンテンツ
    • article section asideといったタグでマークアップできそうな範囲
    • 見出しに使うhタグを含むもの(文書上の暗示・省略されたものも含む)
    • 任意の構造体が入りそうなもの
  • フレーム
    • ルートのheader main footerや、nav の領域

また、これらは、プロジェクトやデザインの文脈によって解釈が異なるというのはあり得る話です。
例えば、同じブランディングエリアであっても、ヘッダーバーの中に小さくあるものと、ブラウザ全面に画像や動画が敷かれ、数点のリンクと共に中央に配されるようなブランディングエリアとでは解釈・役割が異なるでしょう。

Blockの部品作成方法

block/にSassファイルとして切り出してCSSを管理します。
もし、Blockの内部部品に「下位粒度のグローバルな再利用部品」(スタイリングパターンAで作られた部品)を設置する場合は、Blockはそれらの部品を設置するための枠組みのような役割にとどまるでしょう。
逆に、Block内部の部品を自分の一部としてスタイリングする場合は、先述のスタイリングパターンB・Cどちらかでスタイリングすることになります。

Blockのユースケース

コーポレートやブログ、ブランディング、LPなどの情報発信系サイトであれば、よほどの規模ではない限り、この分類でコード化は完成するのではないかと思います。
内部部品はスタイリングパターンB/C(※近年の慣例手法はCのBEM式)のみで作成し、同じ部品が何度か登場したとしても、パターンAの代わりに、SassのExtendやMixin機能で同一コードを流用して完成させるような方法です。

参考情報

余談・参考情報になりますが、bodyタグ直下に機能的・慣例的に設置する.wrapperといった命名の「全体包括要素」もBlockであると捉えると、「Block同士は恒常的にネストする」という意味が理解しやすくなります。※このとき、思考のつじつまが合いやすい命名は.siteです。

<body>
    <div class="site"><!--この中にあるのは「サイト」の表示用データ-->
        <div class="site-header"> <header></header> </div>
        <div class="site-main"> <main></main> </div>
        <div class="site-footer"> <footer></footer> </div>
    </div>
</body>

また、コンテンツのBlockも同じ構造を意識してマークアップすることで、サイト全体のコードがフラクタル構造(自己相似)となり、ルールが捉えやすくなります。(※サンプルはBEM記法で記載)

<div class="photo-gallery"><!--この中にあるのは「写真ギャラリー」表示用のデータ-->
    <section>
        <div class="photo-gallery__header"> <header></header> </div>
        <div class="photo-gallery__body"></div>
        <div class="photo-gallery__footer"> <footer></footer> </div>
    </section>
</div>

2 ・ Module

Module(モジュール)は、単体でも機能しそうな中程度の情報の塊です。
カードや、ギャラリーの1区画。会員証を模したようなもの、プロフィールのひと塊、ECサイトの商品一覧、メニューナビゲーションの1区画などが該当するでしょう。

Module参考イメージ

多くの場合はdivによるコンテナに名前が与えられます。

Moduleの粒度判断

粒度の判断は、コンテンツ部分とフレーム部分で分けて考えられます。
下位粒度のcomponentが集まったものと捉えるとイメージしやすいかもしれません。

  • コンテンツ
    • Blockほどの情報の規模感は無いが、単独でも機能しそうな視覚情報の塊
    • 場合によっては任意の構造体が入りそうなもの
    • その場でリピートして使われそうなもの
  • フレーム
    • ブランディングエリアや、コンタクト情報 等
    • ブランディングエリアや、サイトマップリンク、コンタクト情報 等

Moduleの部品作成方法

自身をグローバルな再利用部品として管理したい時に、module/ディレクトリに切り出して管理します。そうではないなら、この粒度のものは、上位粒度の持ち物としてスタイリングが完了しているはずです。

Moduleのユースケース/この粒度は必要か

ModuleはBlockと近い存在となります。特にBEM記法を使っているとBEMのBlockの概念と相まって「粒度が違えば全てModuleディレクトリに切り出さないといけないのか?」となる事もあるでしょう。そういった管理が煩雑になる場合は、Blockとして管理しても何も問題ありません。(究極は、制作者が混乱しなければよいのです)

では、定義の意味は?

「であれば結局は無法地帯では?」と思われるかもしれませんが、そうではありません。どんな時にこの粒度が有用かというと、1つは再利用の明示です。
Blockは最上位にあるため、どのように再利用しているのか、もしくはしていないのかはHTMLファイルを要調査。となりますが、Moduleディレクトリに置いただけで「どこかで必ず再利用されている中粒度部品」もしくは「どこで再利用してもよい中粒度部品」として意識づけできます。
最初にBlockのディレクトリにSassファイルを置いていても、後から上記のように明示したくなった場合は移動させることもできます。

システム開発との連動

もう1つ有用なパターンは、ECサイトやサービスサイトなどのシステムが絡む時です。
システム側のフロントテンプレートなどにおいて「モジュール」として切り出すものは、この粒度と同じ規模感になるものも多くあります。それぞれ同じModuleという名称のディレクトリで管理すれば、双方が意識上対応したものとして管理できます。

このように、実用時には必要に応じて使い分けられる粒度となります。

3 ・ Component

Component(コンポーネント)とは、見出しやボタン、リストや表組などの、単体でもその部品の機能や目的・情報が分かる小さな要素です。
ModuleやBlockから見れば、自分達を構成する小さな部品群で、下位粒度のElementのから見た時には、Elementの組み合わせがComponentであると表現できます。

Component参考イメージ

この粒度のものには「構造体」や「文書構造」が入ることはありません。
divspanのラッパーに名前を与えることもあれば、ul ol tableなどに名前を与えることもあるでしょう。

Componentの粒度判断

文書構造や構造体が入る余地・感覚が無いもので、かつ、以下の1~4のうち、1つでも当てはまればComponentとなります。

  • 視覚情報
    • 1・視覚情報として分割できる
  • HTMLコード
    • 2・HTMLタグがHTMLタグでラップされている
    • 3・内部を自然に拡張できる
    • 4・コードとして分割・分離できる

また、レンダリング結果はElementと同一になるが、コード側から見ればComponentと判断できるものがあります。以下のようなパターンです。

コード側から見てComponentになる例

imgタグ単体は後述するElementにあたりますが、これを<div class="image">などでラップすれば、.imageは立派なComponentです。「分解・分離できる状態」であり、後に内部にキャプションを入れるなど、「自然に拡張できる状態」になっています。

同様に、pタグだけの文章はElementの粒度にあたりますが、これを<div class="text_box">といったような命名のボックスでラップすれば、同様にComponentとなります。文章が追加されても、新たなpタグによって内部を自然と拡張できます。

Componentの部品作成方法

自身をグローバルな再利用部品としたい場合に、component/ディレクトリに切り出して管理します。そうではないなら、この粒度のものは、上位粒度の持ち物としてスタイリングが完了しているはずです。

Componentのユースケース

Componentをグローバルな再利用部品として作成・運用したくなるのは、システム管理画面やシングルアプリケーション系のプロダクト、ブログの記事内の部品、サービスサイトのUI部品などでしょう。
OOCSSの概念と併用する事が多くなるでしょうし、"既製品"としてBootstrapのようなCSSフレームワークを利用する事になるのかもしれません。

小規模でシステマチックではない静的サイトであれば、Blockの項に記載したとおり、Componentは全て上位粒度の持ち物としてスタイリングした方が効率よく管理できるでしょう。

部品の集まりをどう捉えるか

この粒度のものは、幾つかの部品が集まり特定の機能になる場合もあります。例えば、ボタンが複数横に並んで連結されていれるような場合です。これはComponentの集まりである。と捉える事もできますし、divでラップして「ナビゲーション」という意味の名前を与えればModuleにも、Blockにもできます。
つまり、そのプロジェクトにおいて、対象の部品をどのように管理したいか。という制作者の意思・意図が第一優先です。それをサポートするように、振り分けできる手立てが用意されている。という事になります。

参考情報

Componentは特性として2つの属性のものがあります。
1つは、テーブル(table)やリスト(ul,ol,dl)など、HTMLの仕様により内部構造が定められているものです。これらは、HTMLの仕様に従い内部を拡張できますが、使えるタグは限られています。

もう1つは、「アイコン+タイトル=メニュー項目」「ラジオボタン+テキスト=選択部品」とするなど、制作者の意図により小さな部品を組み合わせてComponentとしたものです。

※この区分けは粒度分類には影響しません。属性的に2つのものがあるという参考情報です。

4 ・ Element

Element(エレメント)は、表示上の面積に関わらず、視覚情報上もしくはコード上でもそれ以上部品分解できない最小の要素です。
Elementの組み合わせ、もしくは単体を何らかの要素でラップすれば、Componentとなります。

Element参考イメージ

imginputなど、直接レンダリングされるタグやspaniなどに名前を与える事があるでしょう。

Elementの粒度判断

それ以上分割分割できない要素で、一行のテキストや、ラジオボタン、チェックボックスなどです。無理に分割しようとすると、意図した情報伝達ができない、機能不全になる、コードとして成立しないといった不都合が起きるようなものが該当します。
また、粒度はレンダリング時の面積にとは関係がありません。いくら面積の広い画像を配置しようとも、imgタグレベルは一様にElementの粒度となります。どれだけ巨大なアイコンや、ラジオボタンを配置したとしても同じ事が言えます。

Elementの部品作成

自身をグローバルな再利用部品としたい場合に、element/ディレクトリに切り出して管理します。そうではないなら、この粒度のものは、上位粒度の持ち物としてスタイリングが完了しているはずです。

Elementのユースケース

この粒度をグローバルな再利用部品として作成・運用するとなると、独自にCSSフレームワークを作る。もしくは、ドラッグ&ドロップでサイトを作っていくようなサービスを構築する時でしょうか。※他にも用途はあるかもしれません

その他

プレフィックス

実用する際には、これらに名前を与えてからCSSプロパティを書くことになりますが、命名時のプレフィックスのルールはここでは定めません。(ガイドという立場として、特に奨励も制限もしません)
制作の必要性に応じて「再利用前提のものは m- c- e- を付与する」など、それぞれ使い勝手が良いように自由にルールを制定してください。

アイデア

これはまだ試せていませんが、1つのアイデアとして、この粒度分類を逆にデザインシステム側に反映できるかもしれません。コーディング側で最適化したものをデザインシステムに乗せられたなら、スムーズに連携できる可能性はあります。

粒度の総括

以上、4つの粒度をコーディングの側面から定義しました。
分類そのものの本質部分を見ればAtomicDesignのそれと非常に近いものですが、思考の入り方と語句の定義を変えただけで、人の認識や使用感は異なったものになります。
では、これが万人向けするのか。といえば、それは分かりません。しかし、少なくとも1つの組織と協力会社において使用する限り、破綻などの問題がゼロであることは事実です。

HCDCモデル図と今回の「HTML Parts」、そして、次回公開する「Sassファイルディレクトリ管理手法」によって、より多くのサイト種別に対応した設計がおこないやすくなります。

Sassファイル・ディレクトリ管理

これらの粒度の名称は、そのままSassファイル管理ディレクトリの名称として利用することになります。
部品化の方法としては、先述の通り「グローバルに再利用する場合」のみ、その粒度のディレクトリに部品を切り出して管理します。

しかし、これらを含めた全体をどのように管理するかは、また別の話となります。これはCSS設計の命題のひとつであり、概念を実務利用するための重要事項となります。

公開予定の手法
次回紹介するものは、プロジェクトごとにカスタマイズ可能なSassファイル管理の仕組みです。標準ルールを中心として、同じロジックでいくつものサイトタイプに柔軟に対応できます。

この記事作成時点での実務利用実績は以下の通りです。
コーポレートサイト / ポータルサイト / サービスサイト / システム管理画面 / ブログサイト / ECサイト(オンラインショップ) / ランディングページ(LP) / イントラサイト

この管理方法についての情報は、投稿次第こちらの記事からもリンクします。

関連記事

クレジット・その他

Ultimate Coding
概要・前提事項

この仕組みは、組織所属時に業務効率化のために構築したものであり、許可を得た上で設計者本人が個人活動として公開しています。商用の制作や開発には利用していただけますが、仕組みを販売したり媒体化するなどの、制作以外での商用化はご遠慮下さい。質問その他、何かあれば@croco_worksまでお声かけください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

脱・Atomic Design - HTML+CSSコーディングの粒度分類法(HTML Parts)

はじめに

HTML+CSSコーディング専用の粒度分類を紹介します。
この仕組みは、デザインやワイヤーフレームなどの視覚情報を分解することに焦点をあて、分解した対象を部品化する流れも併せてガイド化した汎用手法です。
世の中には、コーポレートサイト / ポータルサイト / サービスサイト / システム管理画面 / ブログサイト… といった様々な種別のサイト、Webページがありますが、これらの「完成予想図(視覚情報)」を同じ方法で分解して、コーディング用の部品にできます。

粒度と言えばAtomic Designが有名ですが、この「HTML Parts」も粒度そのものの考え方についてはAtomic Designの踏襲です。その上で「思考の入り方・捉え方」や「名称と定義」をコーディング側に寄せることで、CSS設計やコーディング業務を標準化しやすくしています。

※この記事は標準化ノウハウ公開の一環として書いています。
仕組みの概要や前提事項などについては「UltimateCoding 概要・前提事項」のエントリをご確認ください。

前置きとAtomic Design

そもそもAtomic Designをコーディング視点で評するのはお角違いかもしれませんが、業界の一部ではAtomic Designを"コーディングの万能薬"として組み入れようとする試みがあったのも事実です(今でも探せばそのようなブログ記事やサイトを見ることができます)それほど、画期的かつ魅力的な概念でした。

主題に入る前に、「Atomic Designは、なぜコーディングの万能薬にならなかったのか」を簡単に分析・箇条書きします。

Atomic Designの特徴

  • 小さなものから積み上げていく概念と、多くのコーディングで必要となる分解の行動が相反する
  • TemplatesとPagesが別の意味を喚起してしまい、そのままコーディングに使うと混乱する
  • サイト種別や規模によっては、図のA側に欲しい粒度が一つ不足することがある

といった所でしょうか。良い解決方法があるかのもしれませんが「そのままの状態で万能か?」と言われたら、そうではないでしょう。
しかしこれは、Atomic Designが不出来だとか、不完全であるといいたいのではありません。デザインを始原としたメンタルモデルや設計・方法論を説いた仕組みを、「同じ概念で作られていない他のプロジェクトのコーディング全て」に転用しようとしても、やはりどこか無理が出てくる。というお話です。

HTML Partsの概要

では、本題の「コーディング側から考える粒度分類」の話です。
HTML Partsは、以下のようにデザインやワイヤーフレームを「大きなものから小さなものへと分解」する事で粒度を分類します。

視覚情報の分解ステップ
この方法は、改めて言われなくとも既に多くの制作者が自然とおこなっているであろう流れ・ステップです。こういった一般的な流れの上にガイドを沿えることで、思考による変換や再構築を発生させず、負担がかかりにくいものとして提起します。

また、これがもしAtomic Designによって「システマチックに作られたプロダクト」であったとしても、同じように上から綺麗に分解できることでしょう。
Atomic Designで作られたものの分解

実用の見通しと説明内容

粒度の概念を実際のコーディングに実用するためには、以下の3つの内容把握と、Sassファイル管理の仕組みが必要となります。

  1. 視覚情報の分解方法 を把握
  2. 部品再利用設計の考え方 を把握
  3. 粒度の定義 を把握

以降、上記の順に従って説明します。
Sassファイルの管理方法については、最後に要点を述べた上で、今後別の記事で詳しく説明します。

1 ・ 視覚情報の分解方法

まず1つめの、具体的にどのように分解するのかについての説明です。
方法はいたってシンプルで、分解する対象である「完成予想図」を用意し、以下の図のように大きなものから4つの粒度によって分解していきます。

視覚情報の分解方法
図は企業系サイトを例にしていますが、サービス系サイト、ポータル系、システム管理画面、LP、ブログなど、どんな種別であっても「Webページの視覚情報」がある限り、分解手順そのものは同じです。

また、上記の図と、この記事の情報は、過去記事「1段上のCSS設計・コーディングの概念図」の内容と連動しています。この記事を単独で読んでも意味は通じますが、より良く利用したい場合には併せてご覧下さい。
HCDCモデル図
図との対応としては、左の2つの概念を実用するためのガイドが「HTML Parts」です。「Block」が今回のBlockと等価で、「Parts」が、今回のModule / Component / Elementに細分類されます。

2 ・ 部品再利用設計の考え方

粒度の具体的な説明に移る前に、重要な考え方・ポイントを先に説明します。
何かというと「粒度分類と実装は別で考える」という事です。ここを一緒にして捉えると後で混乱のもとになるため、先に2つの意味を説明します。

1 ・分類は必ず発生している

まず、分類そのものは常に発生しています。どういうことかというと、仮に、デザインやワイヤーフレームを紙に印刷して、ペンで四角い線を引いて分解しながら囲っていったとします。もうこれ以上分解できない。という所まで線をひくと、実質、紙の上に全ての粒度が洗い出されたことになります。
そして、特定の部分を見て、「AtomicDesignではこれはAtomsと呼ばれている」とか、今回の「HTML PartsであればElementと呼ばれている」というように、変わりようのない定義・事実として認識できます。

これが、分類は必ず発生している。という意味です。そして、この時点では実装に関する決めごとは何も発生していません。決める(設計する)のは制作者です。

2 ・どのように部品化するのか

次に、部品をどのようなコードで実装するか。という話です。
判断・意思決定するのは1つだけ。「その対象(部品)を、グローバルに再利用するかどうか」です。これが、CSS設計が大きく切り替わるポイントとなります。

「グローバルに再利用する」とは、以下のようなものです。

これは、CSS設計手法の「OOCSS」と同じ方向にある手法で、システム管理画面やサービス系サイトなどの「システマチックなサイト」で利用したくなるものです。

もし、上記のように再利用しないのであれば、その部品は以下のように「上位粒度の所有物」としてスタイリングします。


これらの図をテキストでまとめると以下のようになります。

1・単体でグローバルに再利用できるCSSを書く
図:スタイリングパターンA
2・上位粒度の所有物となるCSSを書く
図:スタイリングパターンB
図:スタイリングパターンC

そして、これらを「サイト全体視点」と「部品単独視点」の2つの軸で判断していくことが、「CSS設計」の中核であり重要ポイントになります。

これらの前提を踏まえた上で、以下から粒度の説明をおこないます。

3 ・ 粒度の定義把握

各粒度の詳細説明です。
それぞれに細かな定義や判断基準などを記載していますが、先述の通り「粒度分類と実装は別」であり、これらはあくまで制作のためのガイドです。制作者の判断以上に強い立場ではありません。

レギュレーションによって「完全遵守・例外は認めない」と定めるなら話は別ですが、そうではないなら「その視覚情報をどのようにコード管理したいのか」という、制作者の意思・意図を優先し、"ねばならない"の思考に捕らわれることがないようご注意下さい。

1 ・ Block

Block(ブロック)は、情報の意味や役割的に自立・独立した領域や区画・塊です。
機能・役割・情報属性などの基準によって、制作者が「これ以上は他と同じにできない」と判断した範囲によって切り出します。

Block参考イメージ

多くの場合はdivによるコンテナに名前が与えられます。

Blockの粒度判断

粒度の判断は、主たる情報である「コンテンツ」と、ヘッダー・フッターなどの「フレーム」部分とで分けて考えることができます。具体的には以下のようになります。

  • コンテンツ
    • article section asideといったタグでマークアップできそうな範囲
    • 見出しに使うhタグを含むもの(文書上の暗示・省略されたものも含む)
    • 任意の構造体が入りそうなもの
  • フレーム
    • ルートのheader main footerや、nav の領域

また、これらは、プロジェクトやデザインの文脈によって解釈が異なるというのはあり得る話です。
例えば、同じブランディングエリアであっても、ヘッダーバーの中に小さくあるものと、ブラウザ全面に画像や動画が敷かれ、数点のリンクと共に中央に配されるようなブランディングエリアとでは解釈・役割が異なるでしょう。

Blockの部品作成方法

block/にSassファイルとして切り出してCSSを管理します。
もし、Blockの内部部品に「下位粒度のグローバルな再利用部品」(スタイリングパターンAで作られた部品)を設置する場合は、Blockはそれらの部品を設置するための枠組みのような役割にとどまるでしょう。
逆に、Block内部の部品を自分の一部としてスタイリングする場合は、先述のスタイリングパターンB・Cどちらかでスタイリングすることになります。

Blockのユースケース

コーポレートやブログ、ブランディング、LPなどの情報発信系サイトであれば、よほどの規模ではない限り、この分類でコード化は完成するのではないかと思います。
内部部品はスタイリングパターンB/C(※近年の慣例手法はCのBEM式)のみで作成し、同じ部品が何度か登場したとしても、パターンAの代わりに、SassのExtendやMixin機能で同一コードを流用して完成させるような方法です。

参考情報

余談・参考情報になりますが、bodyタグ直下に機能的・慣例的に設置する.wrapperといった命名の「全体包括要素」もBlockであると捉えると、「Block同士は恒常的にネストする」という意味が理解しやすくなります。※このとき、思考のつじつまが合いやすい命名は.siteです。

<body>
    <div class="site"><!--この中にあるのは「サイト」の表示用データ-->
        <div class="site-header"> <header></header> </div>
        <div class="site-main"> <main></main> </div>
        <div class="site-footer"> <footer></footer> </div>
    </div>
</body>

また、コンテンツのBlockも同じ構造を意識してマークアップすることで、サイト全体のコードがフラクタル構造(自己相似)となり、ルールが捉えやすくなります。(※サンプルはBEM記法で記載)

<div class="photo-gallery"><!--この中にあるのは「写真ギャラリー」表示用のデータ-->
    <section>
        <div class="photo-gallery__header"> <header></header> </div>
        <div class="photo-gallery__body"></div>
        <div class="photo-gallery__footer"> <footer></footer> </div>
    </section>
</div>

2 ・ Module

Module(モジュール)は、単体でも機能しそうな中程度の情報の塊です。
カードや、ギャラリーの1区画。会員証を模したようなもの、プロフィールのひと塊、ECサイトの商品一覧、メニューナビゲーションの1区画などが該当するでしょう。

Module参考イメージ

多くの場合はdivによるコンテナに名前が与えられます。

Moduleの粒度判断

粒度の判断は、コンテンツ部分とフレーム部分で分けて考えられます。
下位粒度のcomponentが集まったものと捉えるとイメージしやすいかもしれません。

  • コンテンツ
    • Blockほどの情報の規模感は無いが、単独でも機能しそうな視覚情報の塊
    • 場合によっては任意の構造体が入りそうなもの
    • その場でリピートして使われそうなもの
  • フレーム
    • ブランディングエリアや、コンタクト情報 等
    • ブランディングエリアや、サイトマップリンク、コンタクト情報 等

Moduleの部品作成方法

自身をグローバルな再利用部品として管理したい時に、module/ディレクトリに切り出して管理します。そうではないなら、この粒度のものは、上位粒度の持ち物としてスタイリングが完了しているはずです。

Moduleのユースケース/この粒度は必要か

ModuleはBlockと近い存在となります。特にBEM記法を使っているとBEMのBlockの概念と相まって「粒度が違えば全てModuleディレクトリに切り出さないといけないのか?」となる事もあるでしょう。そういった管理が煩雑になる場合は、Blockとして管理しても何も問題ありません。(究極は、制作者が混乱しなければよいのです)

では、定義の意味は?

「であれば結局は無法地帯では?」と思われるかもしれませんが、そうではありません。どんな時にこの粒度が有用かというと、1つは再利用の明示です。
Blockは最上位にあるため、どのように再利用しているのか、もしくはしていないのかはHTMLファイルを要調査。となりますが、Moduleディレクトリに置いただけで「どこかで必ず再利用されている中粒度部品」もしくは「どこで再利用してもよい中粒度部品」として意識づけできます。
最初にBlockのディレクトリにSassファイルを置いていても、後から上記のように明示したくなった場合は移動させることもできます。

システム開発との連動

もう1つ有用なパターンは、ECサイトやサービスサイトなどのシステムが絡む時です。
システム側のフロントテンプレートなどにおいて「モジュール」として切り出すものは、この粒度と同じ規模感になるものも多くあります。それぞれ同じModuleという名称のディレクトリで管理すれば、双方が意識上対応したものとして管理できます。

このように、実用時には必要に応じて使い分けられる粒度となります。

3 ・ Component

Component(コンポーネント)とは、見出しやボタン、リストや表組などの、単体でもその部品の機能や目的・情報が分かる小さな要素です。
ModuleやBlockから見れば、自分達を構成する小さな部品群で、下位粒度のElementのから見た時には、Elementの組み合わせがComponentであると表現できます。

Component参考イメージ

この粒度のものには「構造体」や「文書構造」が入ることはありません。
divspanのラッパーに名前を与えることもあれば、ul ol tableなどに名前を与えることもあるでしょう。

Componentの粒度判断

文書構造や構造体が入る余地・感覚が無いもので、かつ、以下の1~4のうち、1つでも当てはまればComponentとなります。

  • 視覚情報
    • 1・視覚情報として分割できる
  • HTMLコード
    • 2・HTMLタグがHTMLタグでラップされている
    • 3・内部を自然に拡張できる
    • 4・コードとして分割・分離できる

また、レンダリング結果はElementと同一になるが、コード側から見ればComponentと判断できるものがあります。以下のようなパターンです。

コード側から見てComponentになる例

imgタグ単体は後述するElementにあたりますが、これを<div class="image">などでラップすれば、.imageは立派なComponentです。「分解・分離できる状態」であり、後に内部にキャプションを入れるなど、「自然に拡張できる状態」になっています。

同様に、pタグだけの文章はElementの粒度にあたりますが、これを<div class="text_box">といったような命名のボックスでラップすれば、同様にComponentとなります。文章が追加されても、新たなpタグによって内部を自然と拡張できます。

Componentの部品作成方法

自身をグローバルな再利用部品としたい場合に、component/ディレクトリに切り出して管理します。そうではないなら、この粒度のものは、上位粒度の持ち物としてスタイリングが完了しているはずです。

Componentのユースケース

Componentをグローバルな再利用部品として作成・運用したくなるのは、システム管理画面やシングルアプリケーション系のプロダクト、ブログの記事内の部品、サービスサイトのUI部品などでしょう。
OOCSSの概念と併用する事が多くなるでしょうし、"既製品"としてBootstrapのようなCSSフレームワークを利用する事になるのかもしれません。

小規模でシステマチックではない静的サイトであれば、Blockの項に記載したとおり、Componentは全て上位粒度の持ち物としてスタイリングした方が効率よく管理できるでしょう。

部品の集まりをどう捉えるか

この粒度のものは、幾つかの部品が集まり特定の機能になる場合もあります。例えば、ボタンが複数横に並んで連結されていれるような場合です。これはComponentの集まりである。と捉える事もできますし、divでラップして「ナビゲーション」という意味の名前を与えればModuleにも、Blockにもできます。
つまり、そのプロジェクトにおいて、対象の部品をどのように管理したいか。という制作者の意思・意図が第一優先です。それをサポートするように、振り分けできる手立てが用意されている。という事になります。

参考情報

Componentは特性として2つの属性のものがあります。
1つは、テーブル(table)やリスト(ul,ol,dl)など、HTMLの仕様により内部構造が定められているものです。これらは、HTMLの仕様に従い内部を拡張できますが、使えるタグは限られています。

もう1つは、「アイコン+タイトル=メニュー項目」「ラジオボタン+テキスト=選択部品」とするなど、制作者の意図により小さな部品を組み合わせてComponentとしたものです。

※この区分けは粒度分類には影響しません。属性的に2つのものがあるという参考情報です。

4 ・ Element

Element(エレメント)は、表示上の面積に関わらず、視覚情報上もしくはコード上でもそれ以上部品分解できない最小の要素です。
Elementの組み合わせ、もしくは単体を何らかの要素でラップすれば、Componentとなります。

Element参考イメージ

imginputなど、直接レンダリングされるタグやspaniなどに名前を与える事があるでしょう。

Elementの粒度判断

それ以上分割できない要素で、一行のテキストや、ラジオボタン、チェックボックスなどです。無理に分割しようとすると、意図した情報伝達ができない、機能不全になる、コードとして成立しないといった不都合が起きるようなものが該当します。
また、粒度はレンダリング時の面積にとは関係がありません。いくら面積の広い画像を配置しようとも、imgタグレベルは一様にElementの粒度となります。どれだけ巨大なアイコンや、ラジオボタンを配置したとしても同じ事が言えます。

Elementの部品作成

自身をグローバルな再利用部品としたい場合に、element/ディレクトリに切り出して管理します。そうではないなら、この粒度のものは、上位粒度の持ち物としてスタイリングが完了しているはずです。

Elementのユースケース

この粒度をグローバルな再利用部品として作成・運用するとなると、独自にCSSフレームワークを作る。もしくは、ドラッグ&ドロップでサイトを作っていくようなサービスを構築する時でしょうか。※他にも用途はあるかもしれません

その他

プレフィックス

実用する際には、これらに名前を与えてからCSSプロパティを書くことになりますが、命名時のプレフィックスのルールはここでは定めません。(ガイドという立場として、特に奨励も制限もしません)
制作の必要性に応じて「再利用前提のものは m- c- e- を付与する」など、それぞれ使い勝手が良いように自由にルールを制定してください。

アイデア

これはまだ試せていませんが、1つのアイデアとして、この粒度分類を逆にデザインシステム側に反映できるかもしれません。コーディング側で最適化したものをデザインシステムに乗せられたなら、スムーズに連携できる可能性はあります。

粒度の総括

以上、4つの粒度をコーディングの側面から定義しました。
分類そのものの本質部分を見ればAtomic Designのそれと非常に近いものですが、思考の入り方と語句の定義を変えただけで、人の認識や使用感は異なったものになります。
では、これが万人向けするのか。といえば、それは分かりません。しかし、少なくとも1つの組織と協力会社において使用する限り、破綻などの問題がゼロであることは事実です。

HCDCモデル図と今回の「HTML Parts」、そして、次回公開する「Sassファイルディレクトリ管理手法」によって、より多くのサイト種別に対応した設計がおこないやすくなります。

Sassファイル・ディレクトリ管理

これらの粒度の名称は、そのままSassファイル管理ディレクトリの名称として利用することになります。
部品化の方法としては、先述の通り「グローバルに再利用する場合」のみ、その粒度のディレクトリに部品を切り出して管理します。

しかし、これらを含めた全体をどのように管理するかは、また別の話となります。これはCSS設計の命題のひとつであり、概念を実務利用するための重要事項となります。

公開予定の手法
次回紹介するものは、プロジェクトごとにカスタマイズ可能なSassファイル管理の仕組みです。標準ルールを中心として、同じロジックでいくつものサイトタイプに柔軟に対応できます。

この記事作成時点での実務利用実績は以下の通りです。
コーポレートサイト / ポータルサイト / サービスサイト / システム管理画面 / ブログサイト / ECサイト(オンラインショップ) / ランディングページ(LP) / イントラサイト

この管理方法についての情報は、投稿次第こちらの記事からもリンクします。

関連記事

クレジット・その他

Ultimate Coding
概要・前提事項

この仕組みは、組織所属時に業務効率化のために構築したものであり、許可を得た上で設計者本人が個人活動として公開しています。商用の制作や開発には利用していただけますが、仕組みを販売したり媒体化するなどの、制作以外での商用化はご遠慮下さい。質問その他、何かあれば@croco_worksまでお声かけください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 249日目

100日チャレンジの249日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
249日目は、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

1pxのborder付けた画像をChromeでズームした時に現れる隙間を消す方法

CSSでimg要素の周囲に1pxのborderを付けた画像をChromeで表示した時、ズームで拡大していくと下図のように左右borderと画像の端との間にわずかな隙間が生じる現象に遭遇しハマったので、解決方法をここに書きます。

動作環境
macOS 10.14 (Mojave), Retinaディスプレイ(Radeon Pro 575), Chrome 79

chrome-1px-border-gap-sample_w800.png
図の上段が問題のレイアウトで、li要素で囲んだ2つのimg要素をフロートで配置したものです。
画像出典: Lorem Picsum Images from Unsplash

HTML(要点のみ)
<div class="grid">
  <ul class="img-list">
    <li class="box1">
      <img src="https://picsum.photos/id/1001/1222/454" alt="">
    </li>
    <li class="box2">
      <img src="https://picsum.photos/id/326/590/454" alt="">
    </li>
  </ul>
</div>

CSS(要点のみ)
ul {
  list-style-type: none;
}
.grid {
  width: 930px;
  margin: 0 auto 40px;
}
.img-list {
  overflow: hidden;
}
.img-list li {
  float: left;
  width: 297px;
  margin-right: 19px;
}
.img-list li:last-child {
  margin-right: 0;
}
.img-list .box1 {
  width: 613px;
}
.img-list img {
  box-sizing: border-box;
  width: 100%;
  height: auto;
  vertical-align: bottom;
  border: 1px solid blue;
}

画像の枠線はimg要素に対してborder: 1px solid blueで付けています。このサンプルでは、Chromeで125%に拡大した時に問題の“隙間”が現れました。丸で囲った部分を拡大したのが下段の図です(デバイスピクセル比=2のモニタで確認しています)。左側がChrome、右側がFirefox1で表示したものです。Firefoxでは隙間なくぴっちりと画像の周囲に枠線が描かれるのに対して、Chromeでは1px分の隙間を入れられてしまいました。

隙間の振る舞い

今回のサンプルコードに関していえば、borderの隙間が発生する条件は倍率125%に加えていくつかあるようです。

ブラウザのウィンドウ幅が奇数ピクセルになると発生する

隙間を見分けやすくするため、画像を囲むli要素の背景色を赤#ff0000にしました。125%に拡大した後、ブラウザのウィンドウ幅を大きくしていくと、隙間が出たり消えたりするのがわかります(下図)。1395pxとか幅が奇数ピクセルの時に隙間が現れ、偶数ピクセルでは隙間が消えます。
video_125p_edit.gif

包含ブロックに左右margin: autoが設定されていると発生する

サンプルのコードでは、包含ブロックdiv.gridmargin: 0 auto 40pxを設定しているのですが、このプロパティを消すと隙間が消えます!(下図) しかし、デスクトップ版のページレイアウトに左右marginを使わないわけにはいかないので、これは対策には使えません。
video_125p_margin_edit.gif

解決策

Chromeで隙間を消す方法は意外に簡単でした。CSSでたった1行、borderの太さをthinに変えるだけ。
参考にした解法: Borders disappear in Chrome when I zoom in

img {
  /* border: 1px solid blue; */
  border: thin solid blue;
}

やってみましょう。下図で上側がborder: thin ...、下側がborder: 1px ...です。拡大率125%でウィンドウ幅を変えても、thinに設定した方は隙間が生じないことがわかります。また、80%に縮小した時、border: 1pxの方は、左側のborderが消えてしまうのに対して、thinの方はちゃんとborderが描かれます。
video_125p_fix_edit.gif

サンプルのコード: https://codepen.io/kaz_hashimoto/pen/NWqpqPV

自分の環境で確認したデスクトップ版ブラウザのうち、今回の現象が発生するのはChromeだけでした。

確認したブラウザ

  • macOS: Chrome/Firefox/Safari/Opera
  • Windows 10: IE11/Edge(従来版)

Chrome以外は従来どおりのborder: 1px ...方式で大丈夫そうなので、実際の案件ではJavaScriptを使ってブラウザ判定し、UAがデスクトップ版Chromeの場合のみbodyにclassをセットして、CSSルールを分けるようにしておきました。要点だけ書くとこんな感じ。

img {
  border: 1px solid blue;
}
.chrome-pc img { /* JavaScriptでbodyにclass="chrome-pc"をセットしておく */
  border: thin solid blue;
}

  1. Firefoxはメニューに125%の拡大がないため、このアドオンで倍率を設定: Default Zoom 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLとCSSで魔法陣を描いてみる

そもそも魔法陣って?

創作作品でよく見る、モンスターが召喚されたりするときに下にひいてあるアレ。
「魔法陣」というのはいわゆる創作作品で描かれる演出用の陣の名称で、実在の魔術で使われるガチな方のやつは「魔法」と呼ばれて区別される。

魔法陣はだいたい「円の中と外を魔術的に遮断する」という目的の元に作成される結界。なので、その中に悪魔を召喚するのではなく、むしろ魔法使いが魔法陣の中に立つのが正しい利用法なのだそう。というか、そうしないと召喚した悪魔や精霊に襲われてしまう。
(なお、お祈りや魔除けとしての魔法陣も存在する。)

ちゃんとした魔術的儀式をやって魔法陣を使うには「聖別」という下準備が必要らしいが、ブラウザやウェブサーバーを聖別することはいろんな意味で不可能なので、本記事ではあくまで「魔法陣」の作り方を記述していくことにする。Let's 悪魔召喚♪

構造解説

完成図がこちら。
1582636266722.jpg

See the Pen Magic Circle example by CSS by Yomogenium (@yomogenium) on CodePen.

CSSで魔法陣を作るにあたってカギとなるのは、CSSの一つ、「position」。
最大のポイントは以下の部分。

position: absolute
絶対位置への配置となります。親ボックスにpositionプロパティのstatic以外の値が指定されている場合には、親ボックスの左上が基準位置となります。親ボックスにpositionプロパティのstatic以外の値が指定されていない場合には、ウィンドウ全体の左上が基準位置となります。
出典: http://www.htmq.com/style/position.shtml

つまり、複数の要素に連続してposition:absolute;を使えば、要素同士の干渉を防ぎつつ図形を重ねられるのだ。
CSSで魔法陣を描くのは確かに困難だ。だが、魔法陣に使われる図形を個々で作成していけば、そこまで難易度の高い工作にはならないのではないだろうか?

そういう設計思想で作ってみた。うまくいった。
以下がhtmlソースだが、比較的見やすいものになっている。

html
<div class="base">
    <!-- 外側の輪 -->
    <div class="pattern01"></div>

    <!-- 輪状に並ぶ文字 -->
    <div class="pattern02 rune">
        <span>P</span>
        <span>r</span>
        <span>o</span>
        <span>t</span>
        <span>e</span>
        <span>g</span>
        <span>o</span>
        <span> </span>
        <span>H</span>
        <span>o</span>
        <span>r</span>
        <span>r</span>
        <span>i</span>
        <span>b</span>
        <span>i</span>
        <span>l</span>
        <span>i</span>
        <span>s</span>
    </div>

    <!-- 内側の輪 -->
    <div class="pattern03"></div>

    <!-- ヘキサグラム -->
    <div class="pattern04">
        <p></p>
        <p></p>
        <p></p>
        <p></p>
        <p></p>
        <p></p>
    </div>

    <!-- アクセント -->
    <div class="pattern05">
        <div>
            <p class="rune">v</p>
        </div>
    </div>
</div>

ここに準備のためのCSSを書き加え、以下のようにしてから、工作スタートだ。

html
<style>
body{
    background-color: black;
}

.base{
    position: relative;
    width: 300px;
    height: 300px;
    background-color: black;
}

/* 具体的に言えば、「pattern01~pattern04は中心が親要素の中心と重なる位置に来る」という効果。 */
.pattern01, .pattern02, .pattern03, .pattern04{
    position: absolute;
    margin: auto;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}
</style>

<div class="base">
    <!-- 外側の輪 -->
    <div class="pattern01"></div>

    <!-- 輪状に並ぶ文字 -->
    <div class="pattern02 rune">
        <span>P</span>
        <span>r</span>
        <span>o</span>
        <span>t</span>
        <span>e</span>
        <span>g</span>
        <span>o</span>
        <span> </span>
        <span>H</span>
        <span>o</span>
        <span>r</span>
        <span>r</span>
        <span>i</span>
        <span>b</span>
        <span>i</span>
        <span>l</span>
        <span>i</span>
        <span>s</span>
    </div>

    <!-- 内側の輪 -->
    <div class="pattern03"></div>

    <!-- ヘキサグラム -->
    <div class="pattern04">
        <p></p>
        <p></p>
        <p></p>
        <p></p>
        <p></p>
        <p></p>
    </div>

    <!-- アクセント -->
    <div class="pattern05">
        <div>
            <p class="rune">v</p>
        </div>
    </div>
</div>

外側の円

これはかんたん。

html
<style>
.pattern01{
    border: 2px solid white;
    border-radius: 50%;
    width: 95%;
    height: 95%;    
}

</style>

<div class="pattern01"></div>

[uploading-0]()

widthheightの値は親である.baseを参照しているので、そこから適度に縮めればよい。これは以降の図形でも同じ。
ちなみに、border-radiusの値を50%にすると、どんなサイズの要素でも完全な円形になる。

円形に並ぶ文字

この部分を制作するにあたって、こちらのサイトが大きな助けになった。
https://mail.conifer.jp/csstest/css-circle-text.html

このサイトで使っているのはこちらの応用。
やっていることは箇条書きにするとざっくり以下の通りだ。

  • 文字を一文字ずつ区切る
  • 一文字ごとに異なる傾斜をつける (その角度は、360° ÷ 文字の数。今回は18文字なので360 ÷ 18 = 20、つまり20°ずつ傾ければいい。)
  • その文字が含まれる要素に高さをつける
  • transform-originで回転の中央軸を本来の位置からずらす
  • 出来上がった円形文字は本来の位置からズレるので、position:absoluteを使って正しい位置に戻す

この5つができていれば、おかしな形になることはないだろう。
transform-originについてはhttps://developer.mozilla.org/ja/docs/Web/CSS/transform-originを参照のこと。)

呪文には、ハリーポッター・シリーズに登場する防衛呪文、「Protego Horribilis」(18文字)を使うことにした。


コード。長いので折りたたみ
html
<style>
.pattern02{
    width: 95%;
    height: 95%;
}

/* top、bottom、left、right、heightは%で指定しよう。親要素のサイズに合わせて可変するので、幅や位置を微調整する必要がなくなるからだ。 */
.pattern02 span{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 49%;
    color: white;
    height: 50%;
    transform-origin: bottom center;
}

.pattern02 span:first-of-type{
    transform: rotate(0deg);
}
.pattern02 span:nth-of-type(2){
    transform: rotate(20deg);
}
.pattern02 span:nth-of-type(3){
    transform: rotate(40deg);
}
.pattern02 span:nth-of-type(4){
    transform: rotate(60deg);
}
.pattern02 span:nth-of-type(5){
    transform: rotate(80deg);
}
.pattern02 span:nth-of-type(6){
    transform: rotate(100deg);
}
.pattern02 span:nth-of-type(7){
    transform: rotate(120deg);
}
.pattern02 span:nth-of-type(8){
    transform: rotate(140deg);
}
.pattern02 span:nth-of-type(9){
    transform: rotate(160deg);
}
.pattern02 span:nth-of-type(10){
    transform: rotate(180deg);
}
.pattern02 span:nth-of-type(11){
    transform: rotate(200deg);
}
.pattern02 span:nth-of-type(12){
    transform: rotate(220deg);
}
.pattern02 span:nth-of-type(13){
    transform: rotate(240deg);
}
.pattern02 span:nth-of-type(14){
    transform: rotate(260deg);
}
.pattern02 span:nth-of-type(15){
    transform: rotate(280deg);
}
.pattern02 span:nth-of-type(16){
    transform: rotate(300deg);
}
.pattern02 span:nth-of-type(17){
    transform: rotate(320deg);
}
.pattern02 span:nth-of-type(18){
    transform: rotate(340deg);
}
</style>

<div class="pattern02">
    <span>P</span>
    <span>r</span>
    <span>o</span>
    <span>t</span>
    <span>e</span>
    <span>g</span>
    <span>o</span>
    <span> </span>
    <span>H</span>
    <span>o</span>
    <span>r</span>
    <span>r</span>
    <span>i</span>
    <span>b</span>
    <span>i</span>
    <span>l</span>
    <span>i</span>
    <span>s</span>
</div>

ここを行った直後の状態がコレ。
1582633697492.jpg

ここでは「上が外向き」になるように並んでいるが、逆に「下が外向き」の状態にすることも可能だ。

css
.pattern02 span{
    position: absolute;
    top: 50%;
    bottom: 0;
    left: 49%;
    color: #ffffff;
    padding-top: 44%;
    transform-origin: top center;
}

1582639027901.jpg

※位置や形状を調整するときはbackgroundで正方形を表示させて行うとよい。

フォント(文字の書体)の変更

魔法陣を作るうえで要となるのが、判読不可能な謎言語、だろう。
どうせ作るなら厨二臭いカッコいいディティールにこだわりたい、と思って探していたら、なんとルーン文字のフォントが配布されていた。しかも無料で。
あるものは使うべし、というわけで、筆者はここからフォントをダウンロードして使うことにした。

以下配布サイト's。
https://coliss.com/articles/freebies/free-font-which-cannot-read.html
https://sitebk.com/summary/ancient-font/

フォントの適用方法はこちらのサイトに記載されていたので割愛。
とりあえず手元のサーバー、あるいはパソコンに置き、その上で@font-faceをかければどうにかなるだろう。
ただ、拡張子が.otf.ttfのままではうまく動作しないので、きちんと.woffに変換することは忘れずに。woffファイルへの変換はこちらのサイトから可能だ。
一応、コードも貼っておく。

css
@font-face {
  font-family: 'runefont';
  src: url('./rune.woff') format('woff');
}
.rune{
    font-family: runefont;
}

あ、フォント適用したら以下のようになった。

1582633899884.jpg

内側の円

「外側の円」と仕組みは同じ。だが、外側の円に比べて幅を小さくしてある。

html
<style>
.pattern03{
    border: 2px solid white;
    border-radius: 50%;
    width: 83%;
    height: 83%;
}
</style>

<!-- 内側の輪 -->
<div class="pattern03"></div>

1582634245395.jpg

なんだかそれっぽくなってきたぞ。

六芒星(ヘキサグラム)の描画

仕組み自体は上に挙げた「円形に並ぶ文字」と大差ない。
星型多角形……通称「n芒星」は、辺の本数自体は通常の正多角形と変わらないので、傾ける角度さえ正しければ、あとは辺の長さ(=width)と中心からの距離(=height)を調整してやればよいのだ。

html
<style>
.pattern04{
    width: 83%;
    height: 83%;    
}
.pattern04 p{
    border-top: 2px solid white;
    width: 86%;
    height: 50%;
    transform-origin: center;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
.pattern04 p:first-of-type{
    transform: rotate(0deg);
}
.pattern04 p:nth-of-type(2){
    transform: rotate(60deg);
}
.pattern04 p:nth-of-type(3){
    transform: rotate(120deg);
}
.pattern04 p:nth-of-type(4){
    transform: rotate(180deg);
}
.pattern04 p:nth-of-type(5){
    transform: rotate(240deg);
}
.pattern04 p:nth-of-type(6){
    transform: rotate(300deg);
}
</style>

<!-- ヘキサグラム -->
<div class="pattern04">
    <p></p>
    <p></p>
    <p></p>
    <p></p>
    <p></p>
    <p></p>
</div>

完成するとこのようになる。
1582634573542.jpg

ふつうの多角形を生成したい場合であっても、基本的にwidthとheight以外は変える必要がない。
ノーマルな六角形verにしたのが以下のコードである。

css
<style>
.pattern04{
    width: 83%;
    height: 83%;    
}
.pattern04 p{
    border-top: 2px solid white;
    width: 50%;
    height: 86%;
    transform-origin: center;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
.pattern04 p:first-of-type{
    transform: rotate(0deg);
}
.pattern04 p:nth-of-type(2){
    transform: rotate(60deg);
}
.pattern04 p:nth-of-type(3){
    transform: rotate(120deg);
}
.pattern04 p:nth-of-type(4){
    transform: rotate(180deg);
}
.pattern04 p:nth-of-type(5){
    transform: rotate(240deg);
}
.pattern04 p:nth-of-type(6){
    transform: rotate(300deg);
}

1582651192128.jpg

※ここには書いていないが、五芒星、七芒星でも同様の仕組みで作成できた。

アクセントの作成

実際の魔法陣を見てみるとわかるが、ただ単にきれいな図形を並べただけのものは少ない。
むしろモノホンの魔法陣ほど、幾何学性とはかけ離れたデザインをしている気もしなくはない。
というわけで、魔法陣に華を添えるアクセントも作成していく。

作るのは画像の真ん中にある月のようなパーツ。(スピログラフ、というらしい。)

[uploading-0]()

1582636266722.jpg

これは2つの円を重ねて月のように見せているもの。特に特殊な技術は使っていない……はず。

html
<style>
.pattern05{
    position: absolute;
    top: 40%;
    left: 40%;
    border: 2px solid white;
    border-radius: 50%;
    width: 18%;
    height: 18%;
    background: white;
}
.pattern05 div{
    border: 2px solid white;
    border-radius: 50%;
    width: 73%;
    height: 73%;
    position: absolute;
    top: 0%;
    left: 0%;
    background: black;
}
.pattern05 div p{
    color: white;
    font-size: 22px;
    text-align: center;
    height: 1em;
    width: 1em;
    margin: auto;
    vertical-align: baseline;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}
</style>

<!-- アクセント -->
<div class="pattern05">
    <div>
        <p class="rune">v</p>
    </div>
</div>

完成。

1582636266722.jpg

おわりに

CSSで魔法陣を作るにあたり、色々見て回っていた。
もう既に作ってる人がいて、激しく落ち込んだ。

https://coliss.com/articles/build-websites/operation/design/alchemy-circles-generator.html

余談

手作業だとなかなか手間なので、Javascriptで自動化できないものかと模索中しました。
別記事で。

円形に並ぶ文字」の自動化

参考文献

https://mail.conifer.jp/csstest/css-circle-text.html

http://slpr.sakura.ne.jp/qp/polygon-spirograph/

https://www.ho-yu.ed.jp/club-news/science/1688.html

https://ja.wikipedia.org/wiki/%E6%98%9F%E5%9E%8B%E5%A4%9A%E8%A7%92%E5%BD%A2

https://theorthodoxworks.com/study/various-polygon-in-css/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【OnsenUI】画面遷移とアニメーションの設定方法

こんにちは。
OnsenUIの学習中につまずいた、画面遷移の方法をまとめてみます。

画面遷移

main.js
if (page.id === 'page1') {
  page.querySelector('#switch_button').onclick = function() {
    document.querySelector('#myNavigator').pushPage('page2.html',slide);
  };
} else if (page.id === 'page2') {
  page.querySelector('#return_button').onclick = function() {
    document.querySelector('#myNavigator').popPage(slide);
  };
};

画面遷移には、pushPage popPageメソッドを使用します。
引数にはあらかじめ作成したページと、アニメーションを指定します。(poppageにはアニメーションのみ)

アニメーションの設定

main.js
let slide = {
  animation: 'slide',onTransitionEnd: function(){}
};

animationには任意の値を指定できます。
OnsenUIで用意されているアニメーションは以下の4つ。

  • slide
  • lift
  • fade
  • none

参考文献

OnsenUIの基礎-OnsenUI

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

chat-spaceを作ろう①

アプリケーションを立ち上げる

ターミナル
rails new chat-space -d mysql
アプリ立ち上げ アプリ名 データベース指定
cd ~/ディレクトリを移動

rails db:create
データベース作成

事前準備

Hamlを導入する

gemfile
gem 'haml-rails'
ターミナル
bundle install
rails haml:erb2haml
拡張子.erbのファイルを,hamlになる

sassを準備する

app/assets/stylesheets/application.css
の中身を全て削除し、拡張子を.scssに変更

reset scssの設定(今回はYUI3を使用)

assets/stylesheetsディレクトリ内に部分テンプレート_reset.scssファイルを作成
その中にYUI3をコピペする

assets/stylesheets/application.scss
@import "./reset";
作成した_reset.scssファイルを読み込む

application.scssに読み込むことでアプリケーション全体に適用される様になる

今日はここまで!
見本サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む