CSS3スライドショー

このサイトのサンプルを自分で理解しやすいように成形した健忘ページ。

Javascriptを使わないスライドショー

パネル系骨格

radioボタンにidを指定してlabelと関連付けることで、labelをクリックするとradioボタンのチェックを遠隔操作で移動させることができるようになる。すなわちchecked属性を移動できる。ここでのnameはなくてもいい。

リンク先をコピーしてそのまま画像だけ変えるとこうなる。

Wrapper(100%;overflow;)→slideshow(100%;relative;)→【arrow+slideContents(500%;relative;)→各section(20%;)】みたいな骨格。

各sectionをfloatで横並びにし、親にclearfix。親にoverflow:hiddenはよくない。この時点で最初の画像だけ表示された初期状態が完成する。

ここに矢印を絶対配置に付ける。

<!--html-->
<div id="wrapper">
  <input type="radio" name="slideshow" id="switch1" checked />
  <input type="radio" name="slideshow" id="switch2" />
  <input type="radio" name="slideshow" id="switch3" />
  <input type="radio" name="slideshow" id="switch4" />
  <input type="radio" name="slideshow" id="switch5" />
  <div id="slideshow">
    <div class="slideContents">
      <section id="slide1">
        <img src="./img/t1_b.jpg" />
      </section>
      <section id="slide2">
        <img src="./img/t2_b.jpg" />
      </section>
      <section id="slide3">
        <img src="./img/t3_b.jpg" />
      </section>
      <section id="slide4">
        <img src="./img/t4_b.jpg" />
      </section>
      <section id="slide5">
        <img src="./img/t3_b.jpg" />
      </section>
    </div>
    <p class="arrow prev">
      <i class="ico"></i>
      <label for="switch1"></label>
      <label for="switch2"></label>
      <label for="switch3"></label>
      <label for="switch4"></label>
      <label for="switch5"></label>
    </p>
    <p class="arrow next">
      <i class="ico"></i>
      <label for="switch1"></label>
      <label for="switch2"></label>
      <label for="switch3"></label>
      <label for="switch4"></label>
      <label for="switch5"></label>
    </p>
  </div>
</div>

user-select:noneでマウスを押しながらドラッグで画像やテキストを選択できないようにする。なくてもわからないプロパティ。

slideContentsを起点に絶対配置する(すべての画像を重ねる。そしたら見えないように右側に100%移動させておく。overflow:hiddenがあるのでこの時点で画像表示はされない。

sectionに囲われたエリアをアニメーションで移動させたいのでtransitionを指定しておく。

imgの左右にスペースを開けたいので、paddingを左右に50pxとり、幅はbox-sizingでpadding加えた幅を100%に指定しはみ出ないようにする。画像の最大幅もここで指定。

スライドの構造は、チェクされているinputと兄弟のslideshowの対応するsectionを中央にtransformで移動させる。z-indexを1にして最前面に。positionを入れないとz-indexを指定できない。

次が少し難易度が高い。

1にチェックが入っていたら、4と5は左側へ移動させ、2と3はそのまま右側に。(4、5)、1、(2、3)みたいな感じになってる。()は重なってる意味。

んで、3と4のtransition-duration、移動にかかる時間を0sにして、右から左への移動or左から右への移動の残像が残らないようにする。

右ボタンを押すと、(5、1)、2、(3、4)で4が右に移動、左ボタンを押すと、(3、4)、5、(1、2)で3が左に移動するからである。

矢印は親がすべてwidth:100%なのでその範囲内で絶対配置。z-indexは1で最前面に。

icoの中にmarginとborderで矢印を作成し、cursorをpointerに、すべてのlabelに対してpointer-eventsをnoneにしておき、チェックされたinputの次、又は前のlabelだけを有効にする。

/*css*/
#wrapper {
  overflow: hidden;
  width: 100%;
  padding: 0;
}
 
input[type="radio"] {
  display: none;
}
 
#slideshow {
  position: relative;
  width: 100%;
}
 
.slideContents {
  position: relative;
  background: lightSeaGreen;
  text-align: center;
  -webkit-user-select: none;
  user-select: none;
}
 
.slideContents,
.slideContents section {
  width: 100%;
  height: auto;
}
 
.slideContents section {
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transform: translateX(100%);
  transform: translateX(100%);
  -webkit-transition: opacity .6s, -webkit-transform .6s;
  transition: opacity .6s, transform .6s;
  opacity:0;
}
 
.slideContents section img {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  max-width: 100%;
  height: auto;
  padding: 0 50px;
  vertical-align: middle;
}
 
/* :::::: slideshow mechanism :::::: */
 
#switch1:checked ~ #slideshow .slideContents #slide1,
#switch2:checked ~ #slideshow .slideContents #slide2,
#switch3:checked ~ #slideshow .slideContents #slide3,
#switch4:checked ~ #slideshow .slideContents #slide4,
#switch5:checked ~ #slideshow .slideContents #slide5 {
  z-index: 1;
  position: relative;
  -webkit-transform: translateX(0);
  transform: translateX(0);
  opacity: 1;
}
 
 
#switch1:checked ~ #slideshow .slideContents #slide5,
#switch1:checked ~ #slideshow .slideContents #slide4,
#switch2:checked ~ #slideshow .slideContents #slide1,
#switch2:checked ~ #slideshow .slideContents #slide5,
#switch3:checked ~ #slideshow .slideContents #slide2,
#switch3:checked ~ #slideshow .slideContents #slide1,
#switch4:checked ~ #slideshow .slideContents #slide3,
#switch4:checked ~ #slideshow .slideContents #slide2,
#switch5:checked ~ #slideshow .slideContents #slide4,
#switch5:checked ~ #slideshow .slideContents #slide3 {
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
}
 
#switch1:checked ~ #slideshow .slideContents #slide3,
#switch2:checked ~ #slideshow .slideContents #slide4,
#switch3:checked ~ #slideshow .slideContents #slide5,
#switch4:checked ~ #slideshow .slideContents #slide1,
#switch5:checked ~ #slideshow .slideContents #slide2,
#switch1:checked ~ #slideshow .slideContents #slide4,
#switch2:checked ~ #slideshow .slideContents #slide5,
#switch3:checked ~ #slideshow .slideContents #slide1,
#switch4:checked ~ #slideshow .slideContents #slide2,
#switch5:checked ~ #slideshow .slideContents #slide3 {
  transition-duration: 0s;
}
 
/* :::::: arrows :::::: */
 
.arrow,
.arrow label,
.arrow .ico {
  position: absolute;
}
 
.arrow {
  top: 0;
  margin: 0;
  transition: background .3s;
}
.prev { left: 0; }
.next { right: 0; }
 
.arrow:hover {
  background: rgba(255,255,255,.2);
}
 
.arrow,
.arrow label {
  cursor: pointer;
  width: 50px;
  height: 100%;
}
 
.arrow label {
  top: 0;
  left: 0;
  z-index: 1;
}
 
.arrow .ico {
  top: 50%;
  width: 12px;
  height: 12px;
  margin-top: -6px;
  border-top: 3px solid #fff;
  border-right: 3px solid #fff;
  opacity: 0;
  transition: right .6s, left .6s, opacity .6s;
}
 
.arrow:hover .ico {
  opacity: .6;
  transition-duration: .3s;
}
 
.prev .ico {
  left: 60%;
  -webkit-transform: rotate(-135deg);
  transform: rotate(-135deg);
}
 
.next .ico {
  right: 60%;
  -webkit-transform: rotate(45deg);
  transform: rotate(45deg);
}
.prev:hover .ico { left: 30%; }
.next:hover .ico { right: 30%; }
 
/* :::::: arrows mechanism :::::: */
 
.arrow label {
  pointer-events: none;
}
 
#switch1:checked ~ #slideshow .prev label[for="switch5"],
#switch2:checked ~ #slideshow .prev label[for="switch1"],
#switch3:checked ~ #slideshow .prev label[for="switch2"],
#switch4:checked ~ #slideshow .prev label[for="switch3"],
#switch5:checked ~ #slideshow .prev label[for="switch4"],
 
#switch1:checked ~ #slideshow .next label[for="switch2"],
#switch2:checked ~ #slideshow .next label[for="switch3"],
#switch3:checked ~ #slideshow .next label[for="switch4"],
#switch4:checked ~ #slideshow .next label[for="switch5"],
#switch5:checked ~ #slideshow .next label[for="switch1"] {
  pointer-events: auto;
}

スライドを3画像にする

スライドを3画像にしたとすると、下記のような感じになるが、transition-durationがすべて0sになってしまうので、滑らかに移動という訳にはいかない。5枚が一番いいのかもね。

/*css*/

/* :::::: slideshow mechanism :::::: */
 
#switch1a:checked ~ #slideshow1 .slideContents #slide1,
#switch2a:checked ~ #slideshow1 .slideContents #slide2,
#switch3a:checked ~ #slideshow1 .slideContents #slide3 {
  z-index: 1;
  position: relative;
  -webkit-transform: translateX(0);
  transform: translateX(0);
  opacity: 1;
}

#switch1a:checked ~ #slideshow1 .slideContents #slide3,
#switch2a:checked ~ #slideshow1 .slideContents #slide1,
#switch3a:checked ~ #slideshow1 .slideContents #slide2 {
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
}
 
#switch1a:checked ~ #slideshow1 .slideContents #slide3,
#switch2a:checked ~ #slideshow1 .slideContents #slide1,
#switch3a:checked ~ #slideshow1 .slideContents #slide2,
#switch1a:checked ~ #slideshow1 .slideContents #slide2,
#switch2a:checked ~ #slideshow1 .slideContents #slide3,
#switch3a:checked ~ #slideshow1 .slideContents #slide1 {
  transition-duration: 0s;
}
 
/* :::::: arrows mechanism :::::: */
 
#switch1a:checked ~ #slideshow1 .prev label[for="switch3a"],
#switch2a:checked ~ #slideshow1 .prev label[for="switch1a"],
#switch3a:checked ~ #slideshow1 .prev label[for="switch2a"],
 
#switch1a:checked ~ #slideshow1 .next label[for="switch2a"],
#switch2a:checked ~ #slideshow1 .next label[for="switch3a"],
#switch3a:checked ~ #slideshow1 .next label[for="switch1a"] {
  pointer-events: auto;
}

Chromeでの画像読み込みちらつき

Chromeで最初に開いた時に画像のチラツキがpaddingの部分にでることがある。これを防止するためには、paddingを指定しないで配置すると良い。

コメントor補足情報orご指摘あればをお願いします。

(件名or本文内でキーワード検索できます)



  • << 前のページ
  • 次のページ >>
ページトップへ