左右にスライドする形式のスライダーを「スライダー/左右移動型(レスポンシブ)」として投稿済みであるが、このタイプは、戻るボタン(左側のスライドを登場させる)をクリックすると左方向のスライドショーに切り替わる。世の中で使われている多くのスライダーの場合は、戻るボタンで左方向に戻っても、右方向へのスライドショーが展開する。
そこで、スライドショーは常に右方向で展開するタイプのスライダーを作成することにした。
ただし、css animation の制約で、進行中のanimationを続けてスタートすることができないということがあり、戻るボタンをクリックして前のスライドに戻り、再びクリックしたスライドに戻った時に戻るボタンをクリックしたケースでは動作しない。こう言ったケースはまれだと思い、実用的には使えるのかなということで、ここに投稿します。このような現象を回避する方法としては、進行中のanimationをjavascriptで削除する方法がweb上で多数紹介されているので、そちらを参考にしていただきたい。
サンプル(DEMO)
本サンプル表示用HTML
<div id="stage"> <input type="radio" id="back1" name="gal"> <input type="radio" id="back2" name="gal"> <input type="radio" id="back3" name="gal"> <input type="radio" id="back4" name="gal"> <input type="radio" id="back5" name="gal"> <input type="radio" id="next1" name="gal"> <input type="radio" id="next2" name="gal"> <input type="radio" id="next3" name="gal"> <input type="radio" id="next4" name="gal"> <input type="radio" id="next5" name="gal"> <div id="photos"> <div id="photo0" class="pic"><img src="wp-images/5.jpg"> </div> <div id="photo1" class="pic"><img src="wp-images/1.jpg"> <label for="back1"><div id="left1" class="b_left"><span><</span></div></label> <label for="next1"><div id="right1" class="b_right"><span>></span></div></label> </div> <div id="photo2" class="pic"><img src="wp-images/2.jpg"> <label for="back2"><div id="left2" class="b_left"><span><</span></div></label> <label for="next2"><div id="right2" class="b_right"><span>></span></div></label> </div> <div id="photo3" class="pic"><img src="wp-images/3.jpg"> <label for="back3"><div id="left3" class="b_left"><span><</span></div></label> <label for="next3"><div id="right3" class="b_right"><span>></span></div></label> </div> <div id="photo4" class="pic"><img src="wp-images/4.jpg"> <label for="back4"><div id="left4" class="b_left"><span><</span></div></label> <label for="next4"><div id="right4" class="b_right"><span>></span></div></label> </div> <div id="photo5" class="pic"><img src="wp-images/5.jpg"> <label for="back5"><div id="left5" class="b_left"><span><</span></div></label> <label for="next5"><div id="right5" class="b_right"><span>></span></div></label> </div> <div id="photo6" class="pic"><img src="wp-images/1.jpg"> </div> </div> <div style="padding:28%;"></div> </div>
本サンプル表示用CSS
/* 表示画面 */ #stage { position: relative; max-width: 600px; margin: 0 auto; overflow: hidden; } /*全ての写真を水平一列に格納したdiv、#photosに, スライドショーの animation を設定*/ #photos { position:absolute; top:0; width:100%; animation: imgPassToLeft0 30s infinite; -webkit-animation: imgPassToLeft0 30s infinite; } /*各写真の並び位置を設定 #photo1, #photo2, #photo3, #photo4, #photo5 */ #photo0 { left: 0%; } #photo1 { left:100%; } #photo2 { left:200%; } #photo3 { left:300%; } #photo4 { left:400%; } #photo5 { left:500%; } #photo6 { left:600%; } .pic { position:absolute;top:0;width:100%; } /*写真サイズを可変に*/ .pic img { width:100%; } /* 全てのラジオボタンを非表示に */ #back1,#back2,#back3,#back4,#back5,#next1,#next2,#next3,#next4,#next5{ display: none; } /*送りボタン文字(<、>)の設定*/ .b_left span, .b_right span { position: absolute; font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; font-size: 40px; font-weight: bold; opacity:0; top: 40%; color:#EEE; } .b_left span { left: 5%;; } .b_right span { left: 85%; } /*ボタン文字hover時の設定*/ .pic:hover > label div span { opacity:1; color:#EEE; } .pic label div span:hover { color:#f00; cursor:pointer; } /* 各送りボタンクリック時のanimation設定 */ #next1:checked ~ #photos { animation: imgPassToLeft1 30s infinite; animation-delay: -4.8s; -webkit-animation: imgPassToLeft1 30s infinite; -webkit-animation-delay: -4.8s; } #next2:checked ~ #photos { animation: imgPassToLeft2 30s infinite; animation-delay: -10.8s; -webkit-animation: imgPassToLeft2 30s infinite; -webkit-animation-delay: -10.8s; } #next3:checked ~ #photos { animation: imgPassToLeft3 30s infinite; animation-delay: -16.8s; -webkit-animation: imgPassToLeft3 30s infinite; -webkit-animation-delay: -16.8s; } #next4:checked ~ #photos { animation: imgPassToLeft4 30s infinite; animation-delay: -22.8s; -webkit-animation: imgPassToLeft4 30s infinite; -webkit-animation-delay: -22.8s; } #next5:checked ~ #photos { animation: imgPassToLeft5 30s infinite; animation-delay: -28.8s; -webkit-animation: imgPassToLeft5 30s infinite; -webkit-animation-delay: -28.8s; } #back1:checked ~ #photos { animation: toRight1 6s 0s forwards, imgPassToRight1 30s 6s infinite; } #back2:checked ~ #photos { animation: toRight2 6s 0s forwards, imgPassToRight2 30s 6s infinite; } #back3:checked ~ #photos { animation: toRight3 6s 0s forwards, imgPassToRight3 30s 6s infinite; } #back4:checked ~ #photos { animation: toRight4 6s 0s forwards, imgPassToRight4 30s 6s infinite; } #back5:checked ~ #photos { animation: toRight5 6s 0s forwards, imgPassToRight5 30s 6s infinite; } /* animation設定 */ @keyframes imgPassToLeft0 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @-webkit-keyframes imgPassToLeft0 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @keyframes imgPassToLeft1 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @-webkit-keyframes imgPassToLeft1 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @keyframes imgPassToLeft2 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @keyframes imgPassToLeft3 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @keyframes imgPassToLeft4 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @keyframes imgPassToLeft5 { 0% { left:-100%; } 16% { left:-100%; } 20% { left:-200%; } 36% { left:-200%; } 40% { left:-300%; } 56% { left:-300%; } 60% { left:-400%; } 76% { left:-400%; } 80% { left:-500%; } 96% { left:-500%; } 100% { left:-600%; } } @keyframes imgPassToRight1 { 0% { left: 0%; } 4% { left: -100%; } 20% { left:-100%; } 24% { left:-200%; } 40% { left:-200%; } 44% { left:-300%; } 60% { left:-300%; } 64% { left:-400%; } 80% { left:-400%; } 84% { left:-500%; } 100% { left:-500%; } } @keyframes imgPassToRight2 { 0% { left: -100%; } 4% { left: -200%; } 20% { left:-200%; } 24% { left:-300%; } 40% { left:-300%; } 44% { left:-400%; } 60% { left:-400%; } 64% { left:-500%; } 80% { left:-500%; } 83.999% { left:-600%; } 84% { left:-100%; } 100% { left:-100%; } } @keyframes imgPassToRight3 { 0% { left: -200%; } 4% { left: -300%; } 20% { left:-300%; } 24% { left:-400%; } 40% { left:-400%; } 44% { left:-500%; } 60% { left:-500%; } 63.999% { left:-600%; } 64% { left:-100%; } 80% { left:-100%; } 84% { left:-200%; } 100% { left:-200%; } } @keyframes imgPassToRight4 { 0% { left: -300%; } 4% { left: -400%; } 20% { left:-400%; } 24% { left:-500%; } 40% { left:-500%; } 43.999% { left:-600%; } 44% { left:-100%; } 60% { left:-100%; } 64% { left:-200%; } 80% { left:-200%; } 84% { left:-300%; } 100% { left:-300%; } } @keyframes imgPassToRight5 { 0% { left: -400%; } 4% { left: -500%; } 20% { left:-500%; } 23.999% { left:-600%; } 24% { left:-100%; } 40% { left:-100%; } 44% { left:-200%; } 60% { left:-200%; } 64% { left:-300%; } 80% { left:-300%; } 84% { left:-400%; } 100% { left:-400%; } } @keyframes toRight1 { 0% { left:-100%; } 19.999% { left:0%; } 20% { left: -500%; } 100% { left:-500%; display:none;} } @keyframes toRight2 { 0% { left:-200%; } 20% { left: -100%; } 100% { left:-100%; display:none;} } @keyframes toRight3 { 0% { left:-300%; } 20% { left: -200%; } 100% { left:-200%; display:none;} } @keyframes toRight4 { 0% { left:-400%; } 20% { left: -300%; } 100% { left: -300%; display:none;} } @keyframes toRight5 { 0% { left:-500%; } 20% { left: -400%; } 100% { left: -400%; display:none;} } </style>
CSSのポイント説明
・「スライダー/左右移動型(レスポンシブ)」との違いは、戻る(<)ボタンをクリックしたときに発生するanimationで
・左のスライドを右方向スラインドインで登場させるanimation(1)と、引き続きスライドショーを展開するanimation(2)の二つのanimationを再生するようにしている
・animation(1)は、6秒(スライド切換え時間)の登場終了でそのままの状態を維持し、animation(2)は、6秒後に再生が始まるように設定している
こんにちは。
こちらの記事を拝見して、
作成を試みているのですが、
#photos {
position:absolute;
}
こちら、absoluteではなく、display:flexを
使っての横並びでは、
animationを動かすことはできないのでしょうか?
(自分でflexに変えてみましたが、
animationの実行はされませんでした。)
また、
「animationをjavascriptで削除する方法がweb上で多数紹介されているので」
こちらが、いまいち調べ方がわからず、
不具合を修正することができておりません。
質問ばかり失礼します。
何卒宜しくお願い致します。
こんにちは。
position:absolute; にすることで、各スライドの水平方向の座標(位置)が定義できます。
この座標(数値)があるのでanimationさせることができます。
display:flexでは横並びにはできますが、animationさせることはできません。
「animationをjavascriptで削除する方法」で何をしたいのでしょうか?
ご回答ありがとうございます。
positionに関しては理解いたしました。
ありがとうございます。
animationをjsで削除することに関しては、
こちらの記事に書かれております
「css animation の制約で、進行中のanimationを続けてスタートすることができないということがあり、戻るボタンをクリックして前のスライドに戻り、再びクリックしたスライドに戻った時に戻るボタンをクリックしたケースでは動作しない。」
こちらの挙動を回避して、なるべく見る人が快適に慣ればと思ってjsを調べておりましたが、
知識・リサーチ力が足らず、見つけられなかったため、質問させていただきました。
お忙しいところ申し訳ございません。
ご確認頂けますと幸いです。
失礼しました。
自分で書いたことを失念していました。
このサイトでは、JSを使わないことを前提に書いていますので、私も詳しくは検討していません。ただ、JSでanimationを削除し、リスタートする方法については、
<a href="https://blog.ariafloat.com/article/cssanimationrestart/" rel="nofollow ugc">https://blog.ariafloat.com/article/cssanimationrestart/</a>
などが参考になると思います。
ご返答ありがとうございます!
参考にさせていただきます!
最後にもう一つだけ質問したいのですが、
imgPassToLeft0〜5までのKey flameに関して、
同じ数値ですが、
こちら番号を変えて別々にしているのは何故でしょうか?
素人目ではありますが、同じ数値であれば、同じ animation-nameで
統一できないものなのかなと考えてみたのですが…
質問ばかりで申し訳ございません。
flashやJSではfunctionとして、同じ記述文の使いまわしが可能ですが、
CSSでは、ひとつの要素に、ひとつのKey flame文が必要になります。
なるほど
そういうことなのですね。
jsとそういったところが違うとは知りませんでした。
一連のご質問にお答えくださりありがとうございました!
とても勉強になりました!
どういたしまして。
疑問を持ち、それを解決していけば、レベルがどんどん上がっていきます。
頑張ってください。
こんにちは、昨日はいろいろとありがとうございました。
1つ自分で検証したくご質問しなかったことなのですが、
#photo0,#photo6を省略した方法などは
無いものでしょうか?
自分でもいろいろkeyframe等をいじくって、
スムーズにいかないか試してみたのですが、
スムーズにいったとしても、
buttonが効かなくなったりと、他の不具合が出る結果となりました。
何かご意見等をお持ちでしたら、
ご教授いただければ幸いです。
#photo0,#photo6を使ったた方法にはどのような不具合がありますか?
こんにちは。
返信が遅くなってしまい、申し訳ございません。
機能的には問題ございません。
しかし、
<a href="http://www.mrchildren.jp/" rel="nofollow ugc">http://www.mrchildren.jp/</a>
上記サイトのように、
「『Mr.Children Dome Tour 2019 “Against All GRAVITY”』開催決定!」
といったslideと一緒に文字も移す場合、
同じ文字contentsがhtml上に2つある状態のため、
Googleに重複コンテンツと思われるのではと思ったため、
省略した方法を模索していた次第です。
「「『Mr.Children Dome Tour 2019 “Against All GRAVITY”』開催決定!」
といったslideと一緒に文字も移す場合、」
上記文章間違えておりました。
正しくはslideで画像と文字を一緒になったものをslideさせる際です。
私には良くわかりませんが、このスライダーを含むコンテンツが一つのコンテンツですから、スライダー内の文字列が重複していても、いわゆる重複コンテンツには当たらないような気がしますが、いかがでしょう。
いずれにしろ、#photosとして帯状のslide群を移動させる方式では難しいので、1枚1枚が移動するタイプに書き換えないといけませんね。yoshiさんがどのような方法でおやりになっているかわかりませんが、これをヒントにご検討ください。
なるほどです。
色々と無茶な質問して申し訳ございませんでした。
1枚1枚が移動する方法というのをヒントにまた模索してみたいと思います。
ありがとうございました!