複数列かつ縦並べのliタグをやっつける方法・改

前回記事ではわざわざMixinまで作ってGrid Layoutを使った解決法を紹介しました。
しかし・・・よく考えたら実はもっと簡単な方法がありまして。
四角い車輪を発明してしまったような気分ですけども、めげずに解説していきます。
例となるお題の条件等は前回記事を参照ください。
プロセスが違うだけで出力結果は変わらないのですが、
書き方は微妙に変えてあるので別途デモを用意しました。
Flexboxを使った解法
関係ない記述とかはすっ飛ばしてます。
display: gridから始まる一連のスタイルはいらないです。
(現行ブラウザの対応だけなら)ベンダープレフィックスもいらないです。
IEのために子要素に無理矢理どうのこうのも不要です。
そう、最初からこうすれば済む話だった・・・。
一応解説しときますとflex-flow: column wrap;で
「縦並びかつ横に折り返し」という設定をしていて、
あとは折り返し対象となる縦幅と横幅を指定、という運びになっております。
簡単ですね。いたって簡単。
こんなん思いつかないとかアホの極みですね。→アホの書いた記事
ま、まぁその、こういう単純な折り返しだったからFlexboxで済んだだけですからね。
「じゃあやっぱりGrid Layout要らないじゃん!」とか思っちゃダメですよ。
『RWDでスマホサイズの時は下に置いて、そうでない時は横に…』
みたいな場合ではやっぱりGrid Layoutが賢い選択だと思いますよ。
そ、そう!Gridちゃんはレスポンシブでこそ輝く子なんだ!めんどくさいけど
とか言い訳を残して締めくくります。
・・・と思いきや。
またしても立ちはだかるIE
うん、「また」なんだ。済まない。 (´・ω・`)
確かにベンダープレフィックスもIE11用のCSSハックも要らないとは書きました。
でもやっぱIEは別途対策がいるんです。とてもつらい。
上述のようにCSSを書き換えても
IEだと列が折り返されずに項目が縦並びになってしまうんす。
2~3時間ぐらい格闘した結果分かりました。
よく分かんないけどIEのバグっぽいということが分かりました。
参考:
アイテムが潰れた / min-height, min-widthが効かない|flexboxのバグに立ち向かう(flexboxバグまとめ)
参考URLではmin-heightに関する言及ですが、
なんかmax-heightでも同様の症状っぽいです。
アイテムがコンテナの高さを知らない模様
ってことで、アイテムがコンテナのmax-heightを超えていたとしても
無視してどんどん項目が下に積まれてしまうってな話みたいです。エーン
IEでの解決策を考える
max-heightではなくheightを使う
今回みたいにホバー領域が関わってくると使えない場合も出てくる方法ですが、
基本的にこれが一番いい方法だと思います。
利点:
簡単。上述のCSS(貼り付けたソース部分)のmax-heightをheightに変えるだけ
欠点:
必ずしもリストの高さが322pxとは限らないので、今回のケースの場合は相応しくない
(項目数が7個未満の場合が考えられる)
flex-flow: columnしている部分を囲む要素を追加する
下記のソースも参照。
利点:
上記の欠点を解消できる。
項目数が2個や3個の時でもホバー領域は適正に動く
欠点:
CSSだけでなくHTMLを書き換える必要がある
こんな感じで書き換えればいいと思います。が…
さて、ここで今回のお題を振り返ってみましょう。
・・・何もかも裏目だな!
じゃあもうこんな感じの該当コンテナを囲むJSとか書けばいいんじゃないですかね(なげやり)。
結局最後はゴリ押しのDOM操作!
IEはアホの子!
終わり!!(えー)
脱線
これで解決(?)したので記事の内容としては終わりなんですけど、蛇足的補足をば。
デモで使ったテクニックの一つに、『ナビゲーションをふわっとアニメーションで表示』
させようとしたした所があるんス。
参考:アニメーションする例(ふわっとする)
こういうやつってdisplay: noneをホバーに応じて書いたり消したり
するのがメジャーなんですけど、それだとアニメーションできないんすよね。
(JS書けばどうとでもなるけど)
参考:アニメーションしない例(ふわっとしない)
だから、display要素で表示を制御しようとせず
『ホバー時にopacityの値をアニメーションさせつつ変化させ、
該当箇所だけを可視化させている』
というカラクリで動かしていたんすよ。
発生した課題
で、デモ上では上手く機能してるんですけど…
デモの記述を上の例に倣ってFlexboxの記述に変えるとホバー領域がバグるんス。
どういうことかっていうとこういうことです。
ギギギ・・・。
確かにふわっと表示されてるのでそこは問題ないのですが、本来であれば
『左端の親項目をホバーした状態で子のリスト群が展開』
されなければならんわけで。
この状態だとリストとは無関係な領域をホバーしているにも関わらず、
子のリスト群が展開されてしまっているのです。
その原因
原因は簡単なんす。
opacityで透過しているとはいえ、リストは画面上に存在しているためです。
一見目に見えないけど実体はあるカメレオンみたいな状態なんで、
ホバーすると出現してしまうのです。
これがdisplay: noneだと上記の問題は起こらないのですよ。
なぜかというと非ホバー時には画面上から”消して”ますからね。
ただ、display: noneだと先述の通りアニメーションが効きません…。
デモ上では、
非ホバー時:width, heightを0に、overflow: hiddenに。z-indexとopacityを0
ホバー時:width, heightをautoに、overflow: visibleに。z-indexとopacityを1
みたいな感じで逃げてたんすけどね。
(非ホバー時の領域は縦横0pxにするみたいな邪法的な解決法です)
これだとFlexboxで組んだ時はうまく動いてくれないみたいでして。
解決策
全ての子要素の幅と高さが0なら自ずと親要素もホバー可能な領域を持たなくなるわけで。
親要素の表示条件を満たしている時だけdisplay: block;にしておけば、
上の方に貼ったGIF動画のような怪現象にも悩まされなくなるという寸法です。
・・・ぶっちゃけ何言ってんだコイツ状態かもしれないですけど、
いちおう「こういうトリッキーなことをやってみたよ」という紹介です。
おわりに
信じられないぐらい長い記事になってしまいました。
こんなに時間をかけるつもりは無かったのに・・・。
ところで、前回および今回のデモではPugを使ってHTMLを出力してたので
また別の機会にPug体験談みたいな記事も書こうかなと思ってます。
-
前の記事
複数列かつ縦並べのliタグをやっつける方法 2018.05.18
-
次の記事
テキストの見栄えを整えるCSS Tips 2018.06.30