【18-5】Flexboxの古い仕様とベンダープレフィックスまとめ

最終更新日:2017年09月23日  (初回投稿日:2016年12月26日)

フレキシブルボックスは今のところ勧告候補(2016年記)ですが、それまで下記のように変遷してきました。

  1. box仕様:2009年7月 ドラフト(display: box という形でコンテナを作りました)
  2. flexbox仕様:2012年3月 ドラフト(display: flexbox という形)
  3. flex仕様:2016年の今現在の 勧告候補(display: flex という形)

しかも、↑長い年月をかけて何度も変わってきたので、古めのブラウザは古い仕様に対応していたり、しかもベンダープレフィックスが必要なままだったりします。
じゃあ「どう書けば古めのブラウザにも対応できるのか」について今回まとめておこうと思います。

Flexboxを使ったデモページも作ってみたので、いろいろなブラウザで見てみてください。

本日のINDEX
  1. Flexboxの古い仕様とベンダープレフィックス
  2. Flexbox対応をめぐる各ブラウザの問題点いろいろ
  3. Flexbox導入に関するまとめ
  4. Flexboxの書き方(仕様&ベンダープレフィックス)
    1. Flexコンテナを作る display: flex
    2. 全Flexアイテムの横方向を揃える justify-contentプロパティ
    3. 各Flexアイテムのフレキシビリティを決める flexプロパティ
    4. 全Flexアイテムを並べる方向や 改行を決める flex-flowプロパティ
    5. 全Flexアイテムの縦方向の揃え方を決める align-itemsプロパティ
    6. アイテム個別に縦方向の揃え方を決める align-selfプロパティ
    7. 複数行の縦方向の揃え方を決める align-contentプロパティ
    8. Flexアイテムの表示順を変える orderプロパティ
  5. Flexbox のデモページを作ってみた

Flexbox に関しては、記事を分けています。

【18-1】Flexbox を使おう!(display:flexでFlexboxを作る)
display: flex で「Flexコンテナ」を作ります。
flex-basis、flex-grow、flex-shrink、justify-contentプロパティを使ってみます。
【18-2】Flexbox内のボックスの配置方法を指定しよう
flex-wrap、flex-directionプロパティを使います。
【18-3】Flexbox内の縦(垂直)方向を揃えよう
align-items、align-self、align-contentプロパティを使います。
【18-4】Flexboxの orderプロパティで表示順を自由に変えよう
orderプロパティを使います。
(ちょっとメモ)Flexbox をシミュレーションできるサイト2件
シミュレーションしてみると、わかりやすい!
【18-5】Flexboxの古い仕様とベンダープレフィックスまとめ ←今日はココ
Flexboxの各ブラウザの対応やベンダープレフィックスについて。

Flexboxの古い仕様とベンダープレフィックス

まず、ブラウザのどのバージョンにベンダープレフィックスが必要かを Can I use で見てみました。

これ↑は、2016年2月の時点での Can I use の表示です。
2016年12月時点で Can I use では Android4.3は切り捨てられていましたが、一応この記事では取り上げておきます)

Notes(注意点)では、次のコトがわかります↓

  • Android 4.3 は「box仕様」に対応で、ベンダープレフィックス(-webkit-)付きで書く
    そして「box仕様」は flexアイテムの折り返し(wrap)はできません
  • IE10 は「flexbox仕様」に対応。ベンダープレフィックス(-ms-)付きで書く
  • iOS 8.4 までの Safari はベンダープレフィックス(-webkit-)付きで最新の「flex仕様」に対応

整理してみました。オールドバージョンのブラウザでの対応状況です。
古い仕様(box仕様とflexbox仕様)は、ベンダープレフィックス無しの書き方は無いんですね。

Flexbox を古いブラウザにも対応させるには、次の5コをセットで書く必要あり。(めんどくさいけど)
● box仕様でベンダープレフィックス「-webkit-」が付いたもの
● box仕様でベンダープレフィックス「-moz-」が付き

● flexbox仕様でベンダープレフィックス「-ms-」付き(IE10だけだけど)
● flex仕様でベンダープレフィックス「-webkit-」付き
● 最後にベンダープレフィックス無しの標準仕様

ただ、残念なことに「box仕様」では「flex-wrap(アイテムを折り返す)」ができないんです。
一応box-linesプロパティ」ってのがあったんだけど、どのブラウザでも実装無し。
ですので flexアイテムが多いときは、折り返すことなく一列に延々と連なりはみ出します。

アイテムが少なくて折り返さないなら問題ないけどね。
折り返しが必要なレイアウトで、box仕様のブラウザ(Android4.3とか)を対象にする場合は...残念ながら Flexbox をあきらめて、display: inline-block とかでやるほうがイイです。

Flexbox対応をめぐる各ブラウザの問題点いろいろ

「Can I use」に記載されているKnowm issues(既知の問題点)はこちら↓

  • IE11 は「min-height」を指定していると、垂直方向にアイテムを正しく揃えない
  • IE10IE11 で、flexコンテナに「flex-direction: column」を指定してて、「height」の指定無く「min-height」の指定をしてたら、子の flexアイテムのサイズを正しく計算できない
  • Safari 10より前 では、Flexコンテナ内がマルチラインになるとき、1行の中にいくつアイテムを置くか計算する時に、アイテムに min-width, max-width, min-height, max-height を指定していたらその値を無視し、代わりにアイテムの flex-basis の値を(それがautoなら単にアイテムの width を)使う(ver.10で修正されたそうです)
  • Firefox は、<button>要素が Flexbox で使えない(ver.52では大丈夫だとか)
  • Safari で子の flexアイテムの「高さを%」で指定すると認識されない
    Chromeでも同じ問題がありましたが ver.51で修正されたそうです)
  • IE10 は flexプロパティのデフォルト値は「0 0 auto」
    (IE10 は1つ前の「flexbox仕様」なので。最新仕様の flex仕様のデフォルト値は「0 1 auto」)

けっこうバグありますね。Flexbox を使っていてウマく効かない時は、上記を確認して対処するってかんじですかね...。 Flexboxの問題のリストと回避策「Flexbugs」も見てみてください(英語だけど)

Flexbox導入に関するまとめ

ということで、現時点(2016年)の Flexbox導入について自分なりにまとめてみました。

IEではバグに注意
IE10以上なら、1つ前のflexbox仕様の書き方を追加すればなんとか使えそう。バグがいろいろあるので注意が必要ですが。IE9以下も対象にしたいなら導入は断念。
IE以外のブラウザは、旧仕様での書き方を追加すればOK
旧仕様(box仕様、flexbox仕様)の書き方を追加すれば、古いブラウザでも使えそう。
ただし Safariにはいくつかバグがあるので要注意。
ただし、最古の box仕様では「折り返し」ができない
box仕様では「折り返し」ができないので、折り返す必要があるレイアウトの場合は無理。
折り返しが無い ヘッダー内やフッター内のアイテムなら flexbox導入可能。

IE9や、最古の box仕様のブラウザ(Android4.3)の需要はそろそろ無くなる頃だと思いますので、Flexbox を活用する時期はもうすぐ来そうです。(あとはIE10や11がいつまで残るか...ですかね)

Flexboxの書き方(仕様&ベンダープレフィックス)

古い仕様に対応した旧バージョンのブラウザへの、ベンダープレフィックスの書き方まとめです。

各表の「仕様」の
いちばん上が「box仕様」(最古)
その次が「flexbox仕様」(前回ドラフト)
いちばん下が今の勧告候補の「flex仕様」(最新)黄色バック にしています。

サンプルCSSソースのセレクタは
.con = flexコンテナ(親要素)
.item = flexアイテム(子要素)
としています。コピペする時はご自分のサイトに合わせて書き換えて。

Flexコンテナを作る display: flex

仕様 プロパティ
box仕様 display box inline-box
flexbox仕様 flexbox inline-flexbox
flex仕様 flex inline-flex
.con {
  display: -webkit-box; /*Android4.3*/
  display: -moz-box;    /*Firefox21*/
  display: -ms-flexbox; /*IE10*/
  display: -webkit-flex; /*PC-Safari,iOS8.4*/
  display: flex
  }

displayプロパティだけは、ベンダープレフィックスをプロパティじゃなくて「値」のほうに付けるんだって。へ〜。
コレ以外(↓以降全部)はプロパティの頭にベンダープレフィックスを付けます。

全Flexアイテムの横方向を揃える justify-contentプロパティ

仕様 プロパティ 値(赤字はデフォルト値
box仕様 box-pack start end center justify
(distribute(= space-around)にあたる値は無い)
flexbox仕様 flex-pack start end center justify distribute
flex仕様 justify-content flex-start flex-end center space-between space-around
.con {
  -webkit-box-pack: justify; /*Android4.3*/
  -moz-box-pack: justify;    /*Firefox21*/
  -ms-flex-pack: justify;    /*IE10*/
  -webkit-justify-content: space-between; /*PC-Safari,iOS8.4*/
  justify-content: space-between
  }

box仕様では「distribute」「space-around」(両端に半分のスペースがある均等間隔揃え)にあたる値が無いので要注意です。

各Flexアイテムのフレキシビリティを決める flexプロパティ

仕様 プロパティ 値(赤字はデフォルト値
box仕様 box-flex 膨張率の数値(単位無し。マイナス不可)デフォルトは0.0
(コンテナ内に余剰スペースがあれば、これで割り当てた分だけ成長する)
box-flex-group 縮小率を正の整数で(単位無し)デフォルトは1
(各アイテムをグループにして収縮の優先順位を割り当てる。数字が大きいほうが縮小)
flexbox仕様 flex positive flexibility, negative flexibility, preferred size の3つをまとめる。(flex仕様のショートハンドと同じかんじ。個別の指定は無い)
デフォルトはnone(0 0 auto に相当)
flex仕様 flex-grow 膨張率の係数(単位無し。マイナス不可)デフォルトは0
flex-shrink 縮小率の係数(単位無し。マイナス不可)デフォルトは1
flex-basis 単位付き数値(長さ)デフォルトはauto
flex flex-grow, flex-shrink, flex-basis をまとめるショートハンド プロパティ
.con .item {
  -webkit-box-flex: 1.0; /*Android4.3*/
  -moz-box-flex: 1.0;    /*Firefox21*/
  -ms-flex: 1 0 auto;   /*IE10*/
  -webkit-flex: 1 1 auto; /*PC-Safari,iOS8.4*/
  flex: 1 1 auto;
  }

「box仕様」は、膨張率(box-flex)と 縮小率(box-flex-group)しかなく flex-basisは無し。
box-flex-group(縮小率)は正の整数で指定し、数が大きいほど縮小率が大きくなります。例えば、あるアイテムを「2」、また別のアイテムを「3」にしたら、「2」を指定したのは全アイテム(デフォの「1」)より小さくなり、「3」にしたアイテムはさらに小さくなるってかんじです。

「flexbox仕様」のデフォルト値は none ですが、これは 0 0 auto と設定したのと同じです。(W3C の flexbox仕様書The keyword ‘none’ is equivalent to "0 0 auto". と記されています)
最新の flex仕様の「0 1 auto」と異なるのでややっこしいですね。

さらにややっこしいのは、W3C の flexbox仕様書には、if omitted, the positive flexibility defaults to ‘1’, The negative flexibility defaults to ‘0’. the preferred size defaults to ‘0px’. (positive flexibility のデフォルト値は「1」、negative flexibility のデフォは「0」、preferred size のデフォは「0px」に(省略すると)なる)と書いてあるんです。何コレもうカオス!(笑)
私なりの解釈ですが↓
成長率はデフォが「成長あり(1)」で略すとこれになるけど、「flex: none」にしたら「0 0 auto(伸縮無しでサイズはauto)」になる という意味ではないかと...(苦)

全Flexアイテムを並べる方向や 改行を決める flex-flowプロパティ 

仕様 プロパティ 値(赤字はデフォルト値
box仕様 box-orient horizontal vertical inline-axis block-axis inherit
(アイテムを水平か垂直か、インライン軸かボックス軸に沿って並べる)
box-direction normal reverse inherit (アイテムの表示方向)
box-lines single multiple(折り返しの指定。flex-wrap にあたるモノ)
★注意★ ただし、このプロパティはベンダープレフィックス付けてもどのブラウザも実装無し。box仕様では折り返しは不可
flexbox仕様 flex仕様↓とまったく同じ。ショートハンドも同じです。
flex仕様 flex-direction row row-reverse column column-reverse
flex-wrap nowrap wrap wrap-reverse
flex-flow flex-direction, flex-wrapをまとめるショートハンド プロパティ
.con {
  -webkit-box-orient: vertical;   /*Android4.3*/
  -webkit-box-direction: reverse; /*Android4.3*/
  -moz-box-orient: vertical;      /*Firefox21*/
  -moz-box-direction: reverse;    /*Firefox21*/
  -ms-flex-flow: column-reverse;  /*IE10*/
  -webkit-flex-flow: column-reverse; /*PC-Safari,iOS8.4*/
  flex-flow: column-reverse;
  }

「box仕様」ではショートハンドが無いので、1コずつ書くしかないです。

そして「box仕様」では折り返し(flex-wrapにあたる)のプロパティ「box-lines」はあるけど、どのオールドブラウザも対応していないので、折り返しは指定できません。ず〜っと一列で連なって、普通にはみ出します。残念!

注意点です。
●IE10 では flexアイテムに「display: inline-block」を指定しないと、親に「-ms-flex-flow: wrap」と指定しても子アイテムを折り返さないそうです。
●IE10 と IE11 で、flexコンテナに「flex-direction: column」を指定して、「height」の指定無く「min-height」の指定をしてたら、子の flexアイテムのサイズを正しく計算できないんだって。

全Flexアイテムの縦方向の揃え方を決める align-itemsプロパティ

仕様 プロパティ 値(赤字はデフォルト値
box仕様 box-align start end center baseline stretch
flexbox仕様 flex-align start end center baseline stretch
flex仕様 align-items flex-start flex-end center baseline stretch
.con {
  -webkit-box-align: start; /*Android4.3*/
  -moz-box-align: start;    /*Firefox21*/
  -ms-flex-align: start; /*IE10*/
  -webkit-align-items: flex-start; /*PC-Safari,iOS8.4*/
  align-items: flex-start
  }

アイテム個別に縦方向の揃え方を決める align-selfプロパティ

仕様 プロパティ 値(赤字はデフォルト値
box仕様 (無し)
flexbox仕様 flex-item-align auto start end center baseline stretch
flex仕様 align-self auto flex-start flex-end center baseline stretch
.com .item {
  -ms-flex-item-align: center; /*IE10*/
  -webkit-align-self: center;  /*PC-Safari,iOS8.4*/
  align-self: center
  }

box仕様は、コレにあたるプロパティが無いので指定できません。

複数行の縦方向の揃え方を決める align-contentプロパティ

仕様 プロパティ 値(赤字はデフォルト値
box仕様 (無いのよ)
flexbox仕様 flex-line-pack start end center justify distribute stretch
flex仕様 align-content flex-start flex-end center space-between space-around stretch
.con {
  -ms-flex-line-pack: justify; /*IE10*/
  -webkit-align-content: space-between; /*PC-Safari,iOS8.4*/
  align-content: space-between
  }

box仕様は、コレにあたるプロパティも無くて指定できません。

Flexアイテムの表示順を変える orderプロパティ

仕様 プロパティ 値(赤字はデフォルト値
box仕様 box-original-group 正の整数(単位無し)デフォルトは1
flexbox仕様 flex-order 整数(単位無し)デフォルトは0
flex仕様 order 整数(単位無し)デフォルトは0
.item:last-child {
  -ms-flex-order: -1; /*IE10*/
  -webkit-order: -1; /*PC-Safari,iOS8.4*/
  order: -1
  }

/*box仕様では正の整数だけで書く必要があります*/
.item {
  -webkit-box-original-group: 2; /*Android4.3*/
  -moz-box-original-group: 2;    /*Firefox21*/
  }
.item:last-child {
  -webkit-box-original-group: 1; /*Android4.3*/
  -moz-box-original-group: 1;    /*Firefox21*/
  }

注意点です。
box仕様では正の整数(マイナスの値や0が無い自然数)だけで書く必要があるので、サンプルソースのように、あるflexアイテムを先頭に表示したかったら、まず他のアイテム全部を 1 以外の値にしてから、該当のアイテムを「1 =先頭」にします。

Flexbox のデモページを作ってみた

古い仕様にも対応させたデモページを作ってみたので、オールドブラウザでウィンドウサイズを拡大縮小して試してみてください。(↓画像クリックで別ウィンドウで開きます)

このサンプルは、コンテンツ部分だけでなくヘッダー部分にも Flexbox を使っています。
ヘッダー部分はスマホのように画面幅が小さくなっても折り返さないので問題ありません。
が、コンテンツ部分は画面幅に合わせて折り返す指定をしています。「box仕様」のブラウザでは折り返しの指定ができないので、コンテンツ部分のアイテムが、横一列に並んでしまいます。
こんなかんじ↓
折り返さないとこうなる

<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
〜略〜
</head>

<body>
<header>  <!-- ←これをFlexコンテナにする-->
 <h1>Flexbox Demo</h1>  <!-- ←このh1と下のnavが Flexアイテム-->
<nav>
 <ul>  <!-- ←ulもFlexコンテナにする-->
  <li><a href="#">MENU1</a></li>  <!-- ←liはulのFlexアイテム-->
  <li><a href="#">MENU2</a></li>
  <li><a href="#">MENU3</a></li>
  <li><a href="#">MENU4</a></li>
 </ul>
</nav>
</header>

<div id="container">  <!-- ←これをFlexコンテナにする-->

 <section>  <!-- ←sectionはFlexアイテムになります-->
  <a href="#"><img src="images/img1.jpg"></a>
  <h1><a href="#">TOPIX1</a></h1>
  <p>ダミーテキスト... </p>
 </section>
 <section>〜略〜</section>
 <section>〜略〜</section>
 <section>〜略〜</section>
 <section>〜略〜</section>
 <section>〜略〜</section>

</div>

<footer>
 <small>Copyright </small>
</footer>
</body>
</html>

CSSの抜粋を載せておきます。実際はメディアクエリも使っています。

/*header footer*/
header, footer {
	width:100%;
	z-index:2; /*他の要素よりレイヤーを上にして*/
	position:fixed; /*bodyに対してfixedにしています*/
	background:rgba(0,0,0,.5); 
	color:#fff}
header {
	padding:10px;
	/*flex*/
    display:-webkit-box;/*Android4,Safari5.1*/
	display:-moz-box;/*Firefox21*/
    display:-ms-flexbox;/*IE10*/
    display:-webkit-flex;/*safari(ios8)*/
    display:flex;
	/*justify-content*/
	-webkit-box-pack:justify;/*Android4.3*/
	-moz-box-pack:justify;/*Firefox21*/
	-ms-flex-pack:justify;/*IE10*/
	-webkit-justify-content:space-between;/*PC-Safari,iOS8.4*/
	justify-content:space-between}

/*header menu*/
header ul {
	/*flex*/
    display:-webkit-box;/*Android4*/
	display:-moz-box;/*Firefox21*/
    display:-ms-flexbox;/*IE10*/
    display:-webkit-flex;/*safari(pc,ios8)*/
    display:flex;}
header ul li {
	text-align:right;
	margin-left:3px}
header ul li::after {content:' |'}
header ul li:first-child {margin-left:0}
header ul li:last-child::after {content:''}
header ul li a {color:#fff}

/*layout*/
div#container {
	margin:auto;
	max-width:1000px; /*幅の上限を設けてアイテムは1行3コまでにしています*/
	padding-top:130px;
	text-align:left;
	/*flex*/
    display:-webkit-box;/*Android4*/
	display:-moz-box;/*Firefox21*/
    display:-ms-flexbox;/*IE10*/
    display:-webkit-flex;/*safari(pc,ios8)*/
    display:flex;
	/*flex-wrap*/
	/*「box仕様」には折り返しの指定がありません*/
	-ms-flex-wrap:wrap;/*IE10*/
	-webkit-flex-wrap:wrap;/*PC-Safari,iOS8.4*/
	flex-wrap:wrap;
	/*justify-content*/
	-webkit-box-pack:center;/*Android4.3*/
	-moz-box-pack:center;/*Firefox21*/
	-ms-flex-pack:center;/*IE10*/
	-webkit-justify-content:center;/*PC-Safari,iOS8.4*/
	justify-content:center}
div#container section {
	box-sizing:border-box;
	width:260px; /*flexアイテムの幅はwidthで限定しました(扱いやすいので)*/
	margin:25px;
	padding:10px;
	box-shadow: 1px 1px 2px #ccc;
	border-radius:15px;
	background:#fff}

次回予告

Flexboxに関しては今回でおわり。
Flexbox、おもしろいんだけどね。ちょっと前のブラウザを使っている人にはレイアウトが全体的に崩れて見える場合もあるんだよね。

実際ことしの夏に作ったサイトで、コンテンツ部分に Flexboxを使ったらクライアントのとこでまともに見れなかった。
Snow Leopard(MacOS 10.6)で Safari 5.1 だったんですね。そこで Safari 5.1 はbox仕様で「折り返しできない」ということを知りました。(で、この記事が書けたんだよねww)結局お客さんが自分のブラウザで見れないんじゃしょうがないので「display: inline-block」に直しました。
Safari 5.1 なんて日本全体では少ない需要だと思いますが、意外と印刷物のデザイン制作会社では多いです。
box仕様や flexbox仕様のブラウザを切り捨ててイイ時期が早く来ますように(そう遠くないと思うけどw)

さて、ここのところ CSS について書いていますが、
HTMLの要素でけっこう使うし大事な <svg>要素について、次回は書こうと思います。
SVGは HTMLなどと同じマークアップ言語ですが、それは Illustratorなどのベクターグラフィックを描けるアプリケーションを使って書き出せばOK。そのSVGを HTMLファイルにジカに貼るために使うのが <svg>要素です。

<svg>要素が終わったら、またCSSの続き(次はたぶん visibilityプロパティ)をやります。

関連記事
この記事をはてなブックマークに追加

やる気を保つためにランキングに参加しています。
応援してくださると すっごいやる気を出します! (笑)

初心者にも使いやすい(と思う)レンタルサーバー

最近よく「レンタルサーバーはどこがいい?」とご質問が来ます。
自分でも使っていてオススメなのはミニバード。管理画面がわかりやすくていい感じす。
仕事で使ってるロリポップもわかりやすい管理画面で、初めてでもすんなり使えると思います。
両方とも、なんといっても料金が安いです。初めてだとなるべく安いほうがイイですからね。

それよりちょっと料金は高いけど、高スペックでコスパが良く、信頼性も高いサーバといえば、やはりさくらのレンタルサーバと、XSERVER(エックスサーバー)だと思う。この2つは老舗でユーザーも多いので、質問する場がたくさんあり、初心者の方でもイケるだろうと思います。

レンタルサーバーは、たくさんあり過ぎて迷いますよね。近いうちに、初心者にも良さげなサーバーについて記事にまとめます。*記事をアップしたらココにもリンクを貼ります。

スポンサーリンク

コメントの投稿

スポンサーリンク
最新記事
Category
オススメの本
Links
Calendar
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
Archive
RSS Link
Profile

yuki★hata

Author : yuki★hata
せめて月1回の更新をめざします~。

メールフォームはこちら

スポンサーリンク
スポンサーリンク
Copyright © ほんっとにはじめてのHTML5とCSS3 All Rights Reserved.