矢印付きのカルーセルではなく、自動・一定のスピードで横方向に流れるスライダーを作りたい。
わざわざJavaScript使うのもな…と思い「自動スクロール css」などで検索したら、CSSアニメーションで実装できそうな記事を見つけた。
だいたいこのURLの通りに作成したが、作成時気を付けるべきことが色々出てきたので備忘録。
1.画像の大きさの指定
参考記事では固定幅だったが、今回はvwで指定。%だとbodyの横幅基準に縮んでしまい横長の要素群を用意できないので、レスポンシブで伸縮させたい場合は必ずvw指定することになる。
一度に見える画像を4枚としたいなら、
width: calc( 100vw / 4);
と指定すればよい。
2.必要な複製要素
参考記事でも説明されているが、仕組みとしては、
画像の入ったulが右から左にゆっくり移動する⇒後ろから全く同一の要素がついてくる⇒アニメーションの最初に戻る で、
あたかも無限にループしているように見える、というもの。
その性質上、つねに左右にループした要素が存在しているように見せなくてはならず、そのため参考記事では「同じ要素(ul)を3つ並べる」ことで対処していた。
要素を並べる数は、スライドグループの横幅に依存する。スライドの枚数が少ない=横幅が少ないほど、あたかもループしているかのように、複製して設置する要素を増やさないといけない。
固定数なら問題ないが、数が運用上変化しうるところは最低幅に合わせて画像のulを用意する必要がある。
反対にいえば、スライドの横幅が常に画面幅を超えていれば、要素を複製して後ろに置く必要はない。
※性質上、最低2枚は必要。
3.枚数が変わるとスピードが変わってしまう
どの枚数でもスピードが一定に見えるよう、枚数によって出力するcssを変更し、animationのduration設定を調整した。今回MovableTypeのテンプレートに組み込んだので、そちらの演算でやってしまったが、keyframeのdurationにはcalc()は使えないとのこと…
CMSテンプレートでない場合は、個別に設定するか、早さが変わるのは仕様とするか、Sassの変数で入れるかする必要があるかもしれない。
.LogoWrapper .Logo .LogoList{
animation: loop-slide <mt:Var name='logoLen_1st' op='*' value='6' />s infinite linear 1s both;
}/*スライド数を代入した変数に倍数をかけて値を算出する*/
4.animation-play-state: paused と animation指定の優先度に気を付ける
参考記事にもあるが、ホバー時に画像のアニメーションが停止する仕組みを組み込んでいる。以下はheadタグのstyleタグに記述。同箇所に、前述のanimationの指定もある。外部cssファイルに記述した際は!importantありでも効かなかった。
.Logo:hover .LogoList{
animation-play-state: paused !important;
}
5.IE11で問題が…
完成形はこんな感じだが、
IE11で見ると…
なんかちっちゃ~
もうIEのこと、無視していいとは思うのだけど…vwか?calcか?と色々調べるにdisplay:flexがまた悪さをしている模様。
参考記事:https://personal.loudandproud.me/flexbox-ie-image-bug/
子要素(今回は個々の画像スライドにあたるli要素)に以下を設定。
flex-shrink: 0;
さぁ直ったろう。
裏に重なってる……
横にはみ出るべきところをあくまで中に収まって折り返している雰囲気がある…
再び調べて、これか…?という記事を見つけた。
参考記事:https://ameblo.jp/problo/entry-10298479437.html
親要素が伸びてくれない場合はwidth:100%か、下記を親要素に足す。
display:inline-block;
そのまま足すと他の要素に影響が出てしまったので、ラッパー要素.LogoWrapperを作成しそこに指定。
無事に解決。
参考コード
<div class="LogoWrapper">
<div class="Logo">
<ul class="LogoList">
<li><img src="/assets/test1.png" alt=""></li>
<li><img src="/assets/test2.png" alt=""></li>
<li><img src="/assets/test3.png" alt=""></li>
</ul>
<ul class="LogoList">
<li><img src="/assets/test1.png" alt=""></li>
<li><img src="/assets/test2.png" alt=""></li>
<li><img src="/assets/test3.png" alt=""></li>
</ul>
<ul class="LogoList">
<li><img src="/assets/test1.png" alt=""></li>
<li><img src="/assets/test2.png" alt=""></li>
<li><img src="/assets/test3.png" alt=""></li>
</ul>
</div>
</div>
.LogoWrapper{
display:inline-block;
}
.Logo{
display: flex;
overflow: hidden;
flex-flow: row nowrap;
}
.LogoList {
display: flex;
flex-flow: row nowrap;
margin: 0;
padding:0;
}
.LogoList > li{
display: inline-block;
width: calc( 100vw / 6);
margin: 0 0.3vw;
flex-shrink: 0;
}
.LogoList img{
height: 100%;
width: 100%;
}