Flexboxの最新テクニック! メディアクエリはなし、同じCSSで4つの異なるレイアウトに対応したフォームを実装
Post on:2022年1月26日
メディアクエリはなし、同じHTMLとCSSで、親コンテナの幅に応じて4つの異なるレイアウトに対応したフォームを実装するFlexboxの最新テクニックを紹介します。
もちろんコンテナクエリもなしです。
同じコードでフォームをどこにでも配置でき、コンテンツでもサイドバーでもフォームは最適にレイアウトされます。Flexboxの最新のテクニックを使用すると、CSSで明示的に定義しなくても、レイアウトの柔軟性を得られます。
まずは、実際の動作をデモページでご覧ください。
サイズを変更して見るには、右上「Edit on CodePen」をクリックして別タブでご覧ください。
See the Pen
Flexbox Responsive Form by Adam Argyle (@argyleink)
on CodePen.
ラベルが付いているデモページはこちら。
See the Pen
Flexbox Responsive Form (now with labels for a11y) by Angelique (@angeliquejw)
on CodePen.
フォームのHTMLは、非常にシンプルです。
1 2 3 4 5 |
<form> <input type="text" placeholder="Name"> <input type="email" placeholder="Email Address"> <input type="submit" value="Subscribe"> </form> |
4つの異なるレイアウトを実装するCSSです。他のスタイルは省略しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
form { display: flex; flex-wrap: wrap; & > input { flex: 1 1 10ch; margin: .5rem; &[type="email"] { flex: 3 1 30ch; } } } |
CSSにすると、こんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
form { display: flex; flex-wrap: wrap; } form > input { flex: 1 1 10ch; margin: .5rem; } form > input[type="email"] { flex: 3 1 30ch; } |
CSSの仕組みを簡単に説明します。
ラッパーのform
には、display: flex;
が定義されており、すべてのflexアイテムが水平の1行に収まるように設定されています。flex-wrap: wrap;
を加えることで、1行に収まらない場合に行を折り返すように設定されています。
これにより、3つのinput
要素が、1行・2行・3行に配置されます。
次に、3つのinput
要素のCSSを見てましょう。
3つのinput
にflex: 1 1 10ch;
、e-mail
にflex: 3 1 30ch;
が定義されており、これがこの実装の最大のポイントです。
flex
は、flex-grow
とflex-shrink
とflex-basis
のショートハンドです。
flex-grow: 1;
は、全てのflexアイテムは同じサイズになります。flex-shrink: 1;
は、flexアイテムが残りのアイテムと比較してどのくらい縮まるかです。flex-basis: 10ch;
は、flexアイテムを10chに指定し、残りは最初の大きさに従います。1ch
単位はフォントの「0」文字の幅に相当します。
参考: flexプロパティ(伸長係数・縮小係数・初期サイズを定義)
3つのinput
要素の初期サイズはflex-basis
の値、10ch, 30ch, 10ch になり、合計値は 50ch になります。配置するスペースが50ch以上の場合(アイテムがスペースに収まる場合)は、1行に配置されます。
1番目のレイアウト
各input
要素の幅はflex-grow
の比率になります。submit
の幅がtext
より小さいのは、text
とsubmit
のflex
値は同じですが、ボタンタイプの要素はコンテンツのサイズがわずかに異なるため、通常の入力フィールドよりも小さくなります。
この3つのinput
要素を1行に配置するスペースが十分ではない場合は、行に折り返されます。3つすべてにflex-grow: 1;
が定義されており、他の要素と行を共有しないため、3つすべてが行の幅全体に拡大します。margin: .5rem;
があるため、全幅より少し小さいです。
4番目のレイアウト
幅を少し広くします。
text
とe-mail
の2つを1行に配置するスペースが十分でない場合、e-mail
が行に折り返されます。text
とsubmit
のflex
値は同じですが、ボタンタイプの要素はコンテンツのサイズがわずかに異なるため、通常の入力フィールドよりもわずかに小さくなります。そのため、e-mail
とsubmit
は1行に収まります。これで、2行になりました。text
の幅はflex-grow: 1;
で行の幅全体に拡大され、e-mail
の幅はflex-grow: 3;
の比率で拡大されます。
3番目のレイアウト
幅をさらに少し広くします。
text
とe-mail
の2つを1行に配置するスペースが十分な場合、submit
が行に折り返されます。text
とe-mail
の幅はflex-grow
とflex-basis
の比率になり、submit
の幅はflex-grow: 1;
で行の幅全体に拡大されます。
2番目のレイアウト
元ネタは、下記ツイートからです。
4 layouts for the price of 1, thanks flex 👍
css
form {
display: flex;
flex-wrap: wrap;& > input {
flex: 1 1 10ch;
margin: .5rem;&[type="email"] {
flex: 3 1 30ch;
}
}
}view source on Codepen 👇https://t.co/Q8H5ly2ZIe pic.twitter.com/y6HqxClILZ
— Adam Argyle (@argyleink) January 14, 2020
sponsors