すべて個人的な考えです。都度更新。
使用される要素の最小サイズが Atom(原子)
よく例にあるのがボタン(<button>ボタン</button>
)です。これは「クリックで何かしらアクションを起こす」という役割だけの要素だからです。
<pre><code>...</code></pre>
はコードを表示するための構成で、2つの HTML 要素で構成されています。これは Atom なのかすが、僕は Atom に分類しています。2つの要素を使っていますが、単にコードの入れる場所って役割以外に使うことないからです。
Atom と Atom に分類し使うこともできると思いますが、それらを単体で使わないのであれば恐らく単に細分化しすぎで、やはりatom + atom = atom
となるんじゃないかと思います。「この役目を果たすための最小サイズのラインはどこだろう?」と分類する感じで考えています。
OOCSS
OOCSSというのはオブジェクト指向CSSと呼ばれるCSS設計方法で、スタイル付けをスキン(見た目)とストラクチャ(構造)に分けて考えようという設計方法です。スキンは色とか装飾系だけをまとめたセレクタのことで、ストラクチャは幅、高さ、余白とか見た目以外のスタイルをまとめたセレクタです。
Atom では「できる」を保証します。実際にどんな見た目になるかは上位層が決めます。
フォームの中では幅100%
だけどヘッダーでは300px
で使いたい<input>
など、こういうものは上位層でそういった構造スタイルを付けるようにします。
// molecule
const SearchOfTopMenu = () => {
return (
{/* ... */}
{/* ... */
);
}
Atomic では上位層に行くほど使いまわしの回数は減るはずで、どんどん具体的な内容にもなっていくかなと思うので、具体的になってから初めて構造は付ければ良いかなと思います。
大抵デザインから Atomic を作ろうとするとあるレベルで要素をどんどん分解して最後に組み立てるだけとなってしまいがちですが、コンポーネントを作る段階ではなるべく「この要素はここで使うから」みたいな具体的な背景も頭の中から落とすよう(考えないよう)にするといいかもしれないなと思います。
ロジックを持って、状態は持たない
これはHTMLの要素の動きに近いです。
ロジックは持ってもいいです。disabled
という属性値を持たせて、これが真ならアクションを起こせなくするや(まぁdisabled
なら CSS で制御できそうですが)、loading
がtrue
ならテキストをローディングアイコンにするような簡単なものなど。ただしそれらを状態として保持しないようにします。
const PostButton = ({loading = false, disabled = false, children}) => {
return (
);
};
//
// 使う
// 投稿
HTML でも<input disabled placeholder="...">
などで Atom 単位である程度動的に制御できるように作られています。disabled
を消せばまた入力できるようになるでしょう。ロジックを持って状態は持たないのは自然だと思います。
Functional Component で定義
実装する際は、あとで拡張しやすいように最低でも Functional Component として定義するといいかと思います。あと、TypeScript を使っている場合は自分の型で完結させたほうが後々変にならないだろう(少しは)とも思います。
ここから2019-06までの内容(アーカイブ)
<div>
や<span>
のようにある要素を組み上げるための部品が Atom です。
僕はよくstyled-componentsを使いますが、これで生成したコンポーネントは全て最小単位の部品で Atom に属すと考えれます。
// FlexはAtom
const Flex = styled.div`
display: flex;
`;
// MyFormはAtom
const MyForm = styled.form`
/* ... */
`;
// MyInputはAtom
const MyInput = styled.input`
/* ... */
`;
これらはこのように使えます。
Styled Components を使っていないなら単一要素の SFC と1対1で CSS ファイルを作成し管理するのがいいと思います。
foo
├─ index.jsx
└─ foo.css
// atoms/index.js
const Flex = props => ;
/* atoms/flex.css */
.atom-Flex {
display: flex;
}
属性値で見た目の情報を変える
HTML の<input>
にreadonly
やdisabled
といった属性を渡すとスタイルが変わるようにaria-*
やdata-*
といった属性を振り、それでスタイルを振り分けます。
const Flex = styled.div`
display: flex;
&[aria-orientation='vertical'] {
flex-direction: column;
}
`;
const FlexItem = styled.div`
flex: 0;
& + & {
margin-left: 1em;
}
&[aria-label='main'] {
flex: 0 1 1000px;
}
`;
//
// ...
//
//
//
//
使えそうなaria-*
属性一覧
aria-otientation
要素が縦並びか横並びかどうかaria-level
ネストしたレイアウトにaria-label
要素の区別にaria-hidden
要素を非表示にする時にaria-required
フォームの必須フィールドなどにaria-invalid
フォームでフィールドエラーを表示する時などにaria-checked
input[type=checkbox]
のチェック済スタイルにaria-selected
input[type=radio],select
などの選択済みスタイルにaria-busy
読み込み中などに
追記 (2019-01) - 使えるaria-*
属性一覧
と思いましたが、要素にはもともとデフォルトでrole
が割り当てられていて、このrole
にこのaria-*
は相応しくないというようなルールがあるようです。なので適当に上の属性を当てているとその辺りで Lighthouse のアクセシビリティのスコアが結構下がってしまいます。
僕的にはaria-*
を使ってのスタイル制御は分かりやすく管理しやすいと思っているので、aria
をdata
に変えたもの(data-hidden
)を今は使っています。