先日、1年ほど前に仕事でiPad用に作ったサイトを触っていると、floatを利用した箇所が大きく崩れることがあることが分かった(いつもではないし、崩れ方も異なる)。
確か下記のようなCSSでした。
ul{ width:90%; margin:0 auto; padding:0; list-style:none; } ul > li{ float:left; width:33.33333%; height:50px; line-height:50px; box-sizing:border-box; border:1px solid black; text-align:center; font-size:25px; }
家に帰って実装してみて試してみると再現されなかったので違うかもしれませんが、とにかく上記のレイアウト指定ならリストは3列の並びになるはずなのに、3つ並んでる行もあれば2つしかない行もあるし1つしかない行もあったわけです。
調べてみたらiOS8のバグのようでした。
参考:iOS8でリストのレイアウトが崩れたら : のり記
参考:W3GさんはTwitterを使っています: “iOS8 SafariのCSSレンダリングが不安定化になるのは特定のJS実行下で発生する模様。pushStateでnth-childが効かなくなると。http://t.co/bO2Kasuyk3 他にもcliclイベント発火でfloatが無効されたりJSとの因果関係で不安定化する”
最初は、『display:inline-block』で対処するか。と思ったのだけど、試してみると全て2行表示になってしまった。inline-blockを指定した要素は改行すると隙間ができてしまうんですよね。対処方法はあるのは知ってるのですが(参考:inline-blockを並べた場合に発生する「隙間」を消去するCSS » INSPIRE TECH)、勉強がてらFlexboxを使ってみることにしました。
例えば先ほどのスタイル指定だと、下記のようにすれば同じレイアウトになります。
ul{ width:90%; margin:0 auto; padding:0; list-style:none; display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; } ul > li{ width:33.33333%; height:50px; line-height:50px; box-sizing:border-box; border:1px solid black; text-align:center; font-size:25px; }
ただ、これだとちょっと古いブラウザだとレイアウトが崩れます。そこで、Flexboxの『flex-wrap』が指定してるかどうか調べたうえで、指定できるならFlexboxを、指定できないならfloatを指定することにしました。
CSS
ul > li{ width:33.33333%; height:50px; line-height:50px; box-sizing:border-box; border:1px solid black; text-align:center; font-size:25px; } .flex{ display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: -o-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; } .float > li{ float:left; }
JavaScript(jQuery使用)
var $flexUl = $('#float-container ul'); if( ('webkitFlexWrap' in $flexUl[0].style) || ('flexWrap' in $flexUl[0].style)){ $flexUl.addClass('flex'); }else{ $flexUl.addClass('float'); }
実行結果:ios8でのfloatバグ対応
Flexboxは結構前から知ってはいたのですが、実装されてるブラウザも少なく、ころころ仕様も変わるもんだから利用を避けてたのですが、最近になって十分に使えるようになってきたようです(参考:これからのCSSレイアウトはFlexboxで決まり! | Webクリエイターボックス)。いろいろなプロパティがあってややこしいのですが、機会があればまた使ってみようと思います。
コメント