この記事は最終更新日から 2 年以上が経過しており、内容が古くなっている可能性があります。
jQuery プラグインの slick は、簡単にスライダーが表示できてとても便利であるが、先日仕事で slick を使った際に slick 絡みのトラブルが発生した。
slick イベント「setPosition」とは
タブやモーダルなど、ページ読み込み時に非表示になっているコンテンツ内で slick をそのまま使うと高さが取れずにheight: 0px
となり、領域が潰れて表示されないという問題がある。
この問題を回避するために、slick はsetPosition
というイベントを用意している。setPosition
は、位置やサイズが変更された時に再取得を行うイベントである。
/* タブをクリックした際に発火
.tab クリックするタブ
.slider 対象のスライダー */
$(".tab").on("click", function () {
$(".slider").slick("setPostion");
});
このイベントによって、タブ切り替えで非表示コンテンツが表示になった時に、要素の高さが取れるようになる。
しかし、slick 対象にsetPosition
を指定したにもかかわらず、なぜか効かないという状況が発生した。焦って「slick setPosition 効かない」で検索してみても、setPostion
イベントを追加するだけで無事解決!(上記の 3 行を添えて)みたいな記事しかヒットしない。まるで、「setPostion
で解決しない」という状況自体が存在しないようである。
とはいえ、setPostion
で解決できない状況は今まさに目の前で起こっていた(回想風)。
setPosition が効かない状況および現象
どのような状況でどのような現象が起こったのかを整理してみる。
状況:タブコンテンツと slick する要素の関係が親と曾孫
現象:タブを切り替えると非表示コンテンツの高さが大きくなる
最初は、タブコンテンツと slick する要素が親-子ではなく親-曾孫と、階層が深くなったためsetPosition
が効かないのではないかと疑った。しかし、コンテンツの高さが潰れるどころか逆に大きくなっている点が、単なるsetPosition
効いていない問題ではないように思えた。
setPosition が効かない原因
chrome デベロッパーツールで確認したところ、空白部分が破線ストライプに紫色の領域になっているのが分かった。
破線ストライプに紫といえば、flex や grid で余白が発生した時に付く色である。
当ブログの例(flex の子要素同士の余白が紫地に破線ストライプ)
スライダー要素の css を確認すると、display: flex; flex-wrap:wrap;
が付与されていた。リストを flex で折り返しの横並びにしたものを、そのまま slick のスライドコンテンツとして突っ込んでいたため、このような css プロパティが付いていたのだった。
これは flex と slick の干渉と言うべきか…?恐らくは、flex が何らかの悪さを働いたがためにスライダーに謎の余白が生じたというのが実態だろう。どういう原理でそうなったのかまでは分からないが。
こうして flex に対する疑惑が深まったため、スライダー要素から flex プロパティを取り除いた上でsetPosition
を適用すると、タブ切り替えで非表示コンテンツが表示されるようになった。無事解決したのはよかったが、それまでに 4 ~ 5 時間ほど費やす羽目になった。
まとめ
slick させる要素に flex 関係の css プロパティが付いていたら直ちに取りましょう。いや、flex をかけたコンテンツをそのままスライダーにぶち込むにするのは止しましょうと言うべきか。
ネットで解決方法を探っても見つからなかったのは、今までそういう無茶なことをする人が居なかったからでしょう。