Angular Flex-Layout 入門
はじめに
Angular には公式から flex-layoutというFlexbox と Responsive API を使って Layout してくてるディレクティブが提供されています。
使いこなすことで劇的にCSSの量が減らせるため、今後を考え一度時間をかけて学びまとめます。
また、本家に素晴らしいdemoページ があるのでそちらも参照ください。
angular flex-layout
例のごとく stackblitz 上に Demo を作成しています。
- 列と行が入れ子になった flex-layout の作り方
- スマートデバイス、PC等の画面サイズが異なる場合のレイアウトの作り方
- グリッドリストと flex-layout の組み合わせ方
flex-layout と material をinstall
今回は stackblitz でしか利用しないので stackblitz上でのライブライの import についてです。
とは言ってもとても簡単。 app.module.ts
に import したいClassやらを書くだけで、自動的にpackageのインストールをするかを問われます。
また、依存ライブラリがあれば、それも聞いてくれます。
なんて簡単なんだ。
Nest した flex-layout
行と列が入れ子になったレイアウトを考えます。
作りたいのは下の図の通りです。
大きな枠として1行目はフルサイズ、2行目は2列、3行目もフルサイズとなっていて、2行目の各列の中で行と列を入れ子にしています。
まずは大きな枠を作ります。
1つの fxLayout="column"
の中に 3つの fxLayout="row"
があります。
<div fxLayout="column"> <!-- Column-1 --> <div fxLayout="row" fxFlex="50px" style="background-color: #74edfd" fxLayoutAlign="center center"></div> <!-- Column-2 --> <div fxLayout="row" style="height: 75px"> <!-- Column-2 Row-1--> <div fxFlex="40" fxFlexFill style="background-color: #fd7474"></div> <!-- Column-2 Row-2--> <div fxFlex="60" fxFlexFill style="background-color: #e8fd74"></div> </div> <!-- Column-3 --> <div fxLayout="row" style="height: 75px; background-color: #74fd86"></div> </div>
この時点でこんな感じ。
2行目をさらに入れ子にしてみます。
<!-- Column-2 Row-1-->
を見ると fxLayout="column"
を指定しています。
中をcolumnに分割したい場合は外側のdivに対してfxLayout="column"
を指定するだけで良さそうです。
同様にrowに分割したい <!-- Column-2 Row-2-->
では fxLayout="row"
を指定しています。
<!-- Column-2 --> <div fxLayout="row" style="height: 75px"> <!-- Column-2 Row-1--> <div fxLayout="column" fxFlex="40" fxFlexFill style="background-color: #fd7474" fxLayoutAlign="space-between strech"> <div fxLayout="row" fxFlex="20px" style="background-color: #ffa1a1" fxLayoutAlign="center center">column2-1 row1</div> <div fxLayout="row" fxFlex="20px" style="background-color: #ffa1a1" fxLayoutAlign="center center">column2-2 row1</div> <div fxLayout="row" fxFlex="20px" style="background-color: #ffa1a1" fxLayoutAlign="center center">column2-3 row1</div> </div> <!-- Column-2 Row-2--> <div fxLayout="row" fxFlex="60" fxFlexFill style="background-color: #e8fd74" fxLayoutAlign="space-around strech"> <div fxFlex="30" style="background-color: #f1fac0" fxLayoutAlign="center center">column2, row2-1</div> <div fxFlex="30" style="background-color: #f1fac0" fxLayoutAlign="center center">column2, row2-2</div> <div fxFlex="30" style="background-color: #f1fac0" fxLayoutAlign="center center">column2, row2-3</div> </div> </div>
3行目はOffsetの例をあげています。
やんごとなき理由により親要素から指定したOffsetを当てたい場合があるかもしれません。
その場合は子要素にfxFlexOffset
を指定することでOffsetが当たります。
<!-- Column-3 --> <div fxLayout="row" style="height: 75px; background-color: #74fd86"> <div fxFlex="20" fxFlexOffset="10" style="background-color: #b5ffbf" fxLayoutAlign="center center">column3 row1</div> <div fxFlex="80" fxFlexOffset="10" style="background-color: #b5ffbf" fxLayoutAlign="center center">column3 row2</div> </div>
以上で入れ子になったflex layoutを作ることができました。
ここまでは基礎ですね。
flex-layout break point
近年はPCだけでなくスマホ等のスマートデバイスへの考慮が必須です。
従来mediaクエリを書くことで対応してきましたが、flex-layoutでは fxFlexを活用することである程度対応することができそうです。
flex-layout ではこのページに break point がまとまっています。
独自のbreak pointを設定することもできますが、基本的にはこの break point と不等号(gt / lt)を使ってレイアウトを指定します。
fxLayout
に対してbreak pointを指定することで row と column を変更できます。
fxFlexOrder
に対してbreak pointを指定することで要素の順番を変更できます。
fxFlex
に対してbreak pointを指定することで親要素に対する大きさを変更することができます。
fxHide
に対してbreak pointを指定することで指定した要素を非表示にすることができます。
<mat-card-content> <div fxLayout="column"> <!-- Header --> <div fxLayout="row" fxFlex="50px" style="background-color: #74edfd" fxLayoutAlign="center center">header</div> <!-- Main --> <div fxLayout="row wrap" style="height: 150px"> <div fxFlexOrder="1" fxLayout="row" fxLayout.xs="column" fxFlex.xs="100" fxFlex.gt-xs="30" style="background-color: #fd7474" fxLayoutAlign="center center">side nav</div> <div fxFlexOrder="5" fxLayout="row" fxFlex.xs="100" fxFlex.gt-xs="70" fxFlex.gt-sm="50" style="background-color: #e8fd74" fxLayoutAlign="center center">article</div> <div fxFlexOrder="10" fxLayout="row" fxHide.xs fxHide.sm fxFlex.gt-sm="20" style="background-color: #74fd86" fxLayoutAlign="center center">toc</div> </div> <!-- Footer --> <div fxLayout="row" fxFlex="50px" style="background-color: #74edfd" fxLayoutAlign="center center">footer</div> </div> </mat-card-content>
これだけでも相当のユースケースをカバーできそうですがdemoページにあるように ngClass
または ngStyle
に対してもbreak pointが仕込めるようです。 もうメディアクエリだこれ
<div fxFlex class="fxClass-all" ngClass.xs="fxClass-xs" [ngClass.sm]="{'fxClass-sm': hasStyle}" [ngClass.md]="{'fxClass-md': hasStyle, 'fxClass-md2': hasStyle}" [ngClass.lg]="['fxClass-lg', 'fxClass-lg2']"> </div>
Grid list と flex-layout
最後は Grid list との組み合わせです。
画像やCardをngForでダーッと並べる時に使いますね。
fxLayout="row wrap"
を指定した中に fxFlex="25" fxFlex.sm="33.3" fxFlex.xs="50" *ngFor="let tile of tiles"
のように画面サイズに応じた割合を指定することでgrid-tileの個数を指定できます。
xsの時は2つ、smの時は3つ、その他は4つ、という指定です。
<div fxLayout="row wrap"> <div fxFlex="25" fxFlex.sm="33.3" fxFlex.xs="50" *ngFor="let tile of tiles"> <mat-grid-list cols="1" rowHeight="1:1"> <mat-grid-tile [style.background]="tile.color"> {{ tile.text }} </mat-grid-tile> </mat-grid-list> </div> </div>
まとめ
Angular Flex-Layout の3つのユースケースをまとめました。
活用することでCSSの量をかなり減らすことができそうです。
また、Angularチームが公式に提供してくれているため、Material Componentsとの組み合わせで苦労することもなさそうです。