こんにちは。
今年の新潟は例年より雪が少ないみたいです。
寒がりなので、はやく暖かくなるといいなぁ、コタツ欲しいなぁ、コタツで仕事したいぁと思うこの頃です。
さて2016年1月12日でInternet Explorer 8・9・10 のMicrosoftサポートが打ち切られまして、CSSを書く人間としては一足先に春が来たのかもしれないなぁと頭の中がポカポカするわけですが、これまで古いIEさんに遠慮してできなかったことを、どんどんやっていかなきゃいけないわけです。
Internet Explorer 8・9・10 のサポート終了[過去記事]
そんな中、実案件でついにFlexboxを使う機会があったので、喜びの舞を踊ったときのお話です。今回は失敗談になります。ちょっとはまりました…
やりたかったレイアウト
ヘッダー部分で起こったことなのですが、まずやりたかったこと、完成系はヘッダーの左にロゴ、右側にメニューという、まぁありきたりなものです。DEMOの「OK!!」の形にしたかったのですね。
調べながらやってみて、コード的にはこんな感じみたいですね。以下勉強したときの抜粋です。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div class="flex"> <div class="flex-child"> Logo </div> <div class="flex-child"> <nav> <ul> <li>menu</li> <li>menu</li> <li>menu</li> <li>menu</li> </ul> </nav> </div> </div> |
CSS(sass)
1 2 3 4 5 6 7 |
.flex{ display: flex; justify-content: flex-end; &-child:nth-of-type(2){ margin-left: auto; } } |
親要素を「display:flex;」にすると子要素が横並びになって、「justify-content: flex-end;」で子要素を右寄せ。メニューの入った子要素を「margin-left: auto;」にすることで、ロゴは左寄せ。
ふむふむ、天地のセンターもできるし、floatでやってたときよりずっと簡単だなぁ。やっぱりCSSってすごいなぁ。
とまぁホクホクしてたんですが、ここからハマります。
昔のSafariでふっとんだ
お勉強は済んだのでコード書きます。
HTMLはさっきと一緒です。CSSはこんな感じです。
対応していないブラウザ用にベンダープレフィックスつけてます。
CSS(sass)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.flex{ display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: end; -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; overflow: hidden; &-child{ width: 50%; &:nth-of-type(2){ margin-left: auto; } } } |
「Mac10.6.8 safari5.1.10」確認したところ…
あれ、メニューが消えた…
困ったのでちょっと実験してみました。「Mac10.6.8 safari5.1.10」の実験スクリーンショット。
実験の結果、起こったことの確認をすると「.flex-child」に数値で幅指定して、メニューの方に「margin-left: auto;」したら、全体の幅(今回は960pxで試しました)の向こう側にメニューが押し出される。親要素「.flex」に「overflow: hidden;」が指定してあるから、まるでメニューが消えたように見えるマジック!!
これどういうことなんですかね、「display: -webkit-box;」って何だろう?って解釈なのかな?
かといって幅を明示しないと「margin-left: auto;」がいまいちうまくいかない。
試しに1個目の「.flex-child」だけ幅指定してみたら、先頭に変な隙間ができてしまいました…
ともあれ、このsafariのぶっ飛ばしを解消できず、泣く泣く次の方法を探す旅に出ます…
「justify-content: space-between;」ならいけるんじゃない!?
困ってしまったので苦肉の策にでます。今回は「.flex-child」が2個なので「justify-content: space-between;」でいけるんじゃなかろうか?
ちなみに「justify-content: space-between;」は
flexアイテムは最初と最後のアイテムは端に、残りは等間隔で配置されます。
ということなので、2個しかない今回は両方が端にぴったりくっつくはず!
なんだこれで解決じゃないですか。
後に謎の空間があります…
コードはこんなです。※実際のコードとは若干違いますが、わかりやすくするためこうしてあります。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div class="flex flex-between clearfix"> <div class="flex-child"> Logo </div> <div class="flex-child"> <nav> <ul> <li>menu</li> <li>menu</li> <li>menu</li> <li>menu</li> </ul> </nav> </div> </div> |
CSS(sass)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
.flex{ display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: -o-flex; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; &-between{ -webkit-box-pack: justify; -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; } } .clearfix:after{ content: ''; display: table; clear: both; } |
これでうまく、いかなかった…
よくわからない隙間がメニューの後にできちゃいました。これは何でしょう??
神様がお前にはまだFlexboxなんて100年早すぎるとおっしゃっているのでしょうか…
ちなみにこの現象はいろいろなブラウザで確認できました。
ということは、バグではなくて、きっと正しい挙動で、私のミスですね。しょんぼりです。
原因は疑似要素?
CSSをいじくって確認してみたら、原因はclearfixにあったみたいです。正確にいうと疑似要素:afterにあるようです。
試しに「.clearfix:after」の「content」プロパティに文字列を入れてみると、上の画像の「??」の部分に表示されます。実験的にロゴの方の「.flex-child」に疑似要素:beforeを仕込んでみると、今度はロゴの手前に空間ができます。
親要素にdisplay: flex;を設定していると疑似要素もFlexアイテとして扱われるということなんですかね?さっきのsafariのぶっ飛びに比べると何となくそんなような気もしなくはないですかねー
ということで、疑似要素を削除して解決です。
※第一なんでこのfloatもしてないのにclearfixが必要だったのかと言われますと、消し忘れです(苦笑)もともとFlexbox使わずに組んであった所を後から修正してたんですよね。
そしたらこんな素敵な現象に出逢えて私はなんてラッキーなんでしょう!
とはあんまり思えませんでした…
感想
正直これくらいのものなら、floatでもなんでも、別にFlexboxにこだわる必要はなかったですが、今後の勉強を兼ねて。
今回はうまくいかなかったサンプルですが、Flexbox使ってみた感想としては、「楽」ですね。floatと絶対配置とtable-cellと、いろんなレイアウトの仕方はありますが、とりあえずこれだけでかなりいけそうな気がします。
もっと使いたおしていかないといけないかな、という感想です。
そうしないと今回みたいな現象にぶつかった時に、また悩んでしまいますからね。
Flexboxはまだ対応していないブラウザ、ベンダープリフィックスが必要なブラウザがあります。ご使用の際はご確認の上ご使用ください!
参考にさせていただいたサイト様
「これからのCSSレイアウトはFlexboxで決まり!」Webクリエーターボックス様