JavaScriptを書かなくてもカルーセルを作れますか?
HTMLとCSSだけでカルーセルを作る方法を説明します。
カルーセルについて
WEBページでいろいろな情報を見せたい時に、カルーセルで表示することがよくあります。
カルーセルはjQueryやslickなどのライブラリを使用して簡単に作成することもできますが、HTMLとCSSだけでも作成できます。
この記事には、自動スクロールと操作ボタンの両方を持ったカルーセルはありません。
自動スクロールさせながら、ボタンで位置を操作するのは、JavaScriptを利用しないと難しいと思います。
自動スクロールするカルーセル
まずは、画像が自動スクロールを続ける以下のカルーセル作っていきます。
HTMLの内容
HTMLではカルーセル全体をdivタグにして、その中にimgタグを並べます。
末尾に最初の画像と同じ画像のimgタグを追加します。
<!-- カルーセルの外枠 -->
<div class="carousel">
<!-- 1枚目の画像 -->
<img src="https://dummyimage.com/320x120/ff0000/ffffff&text=1">
<!-- 2枚目の画像 -->
<img src="https://dummyimage.com/320x120/00ff00/ffffff&text=2">
<!-- 3枚目の画像 -->
<img src="https://dummyimage.com/320x120/0000ff/ffffff&text=3">
<!-- 4枚目の画像 -->
<img src="https://dummyimage.com/320x120/ff00ff/ffffff&text=4">
<!-- 1枚目と同じ画像 -->
<img src="https://dummyimage.com/320x120/ff0000/ffffff&text=1">
</div>
CSSの内容
CSSで、スクロールのアニメーションを記述します。
/* カルーセルの外枠 */
.carousel {
width: 320px;
height: 120px;
display: flex; /* 子要素を横に並べる */
overflow: hidden; /* はみ出た部分は表示しない */
margin: 0 auto; /* 水平方向中央寄せ */
}
/* カルーセル内の画像 */
.carousel img {
margin: 0;
padding: 0;
display: block; /* imgタグの改行のすき間を消すため */
}
/* スクロールアニメーションのキーフレーム */
@keyframes scroll {
/* 初期位置は1個目の画像が左端 */
0% { margin-left: 0; }
/* 1個分左の位置に進めて2個目の画像を左端にする */
20% { margin-left: -100%; }
/* 少しの間上と同じ位置 */
25% { margin-left: -100%; }
/* 2個分左の位置に進めて3個目の画像を左端にする */
45% { margin-left: -200%; }
/* 少しの間上と同じ位置 */
50% { margin-left: -200%; }
/* 以降は上と同様に繰り返し */
70% { margin-left: -300%; }
75% { margin-left: -300%; }
95% { margin-left: -400%; }
100% { margin-left: -400%; }
}
/* カルーセルの子要素にスクロールアニメーションを設定 */
.carousel > :first-child {
animation-name: scroll; /* キーフレーム名 */
animation-duration: 20s; /* 再生時間全体は20秒 */
animation-delay: 0s; /* 読込直後から遅延無しで開始 */
animation-iteration-count: infinite; /* 無限に繰り返す */
}
上の例ではimgタグを直接カルーセルの子要素にしていますが、間にdivタグを挟んで各スライドに文字などを追加することもできます。
操作ボタンのあるカルーセル
以下の操作ボタンを持つカルーセルを作成します。
前へ
、次へ
ボタン- 指定したスライドへ移動するボタン
See the Pen Casrousel-Buttons by mik20621 (@mik20621) on CodePen.
HTMLの内容
HTMLは以下のように記述します。
<div class="carousel">
<!-- スライドのリスト -->
<div class="contains">
<!-- スライドを選択するためのラジオボタンリスト。 -->
<!-- 数は増減しても構わないです。 最初は1番目を選択状態(checked)にします。-->
<!-- Slide各ラジオボタンに個別のidを定義して、nameはすべて同じ値にします。 -->
<input class="slide_select" type="radio" id="SlideA" name="slide_check" checked />
<input class="slide_select" type="radio" id="SlideB" name="slide_check" />
<input class="slide_select" type="radio" id="SlideC" name="slide_check" />
<input class="slide_select" type="radio" id="SlideD" name="slide_check" />
<!-- スライド -->
<!-- 上のラジオボックスと同じ数だけ記述します。-->
<div class="slide">
<!-- スライドの前へ、次へとスクロールさせるボタン -->
<div class="scroll_controler">
<!-- 前へボタン forで戻る先のラジオボタンのidを書きます。-->
<!-- 先頭要素なので、最後のスライドのidである"SlideD"を書いています。 -->
<label class="scroll_button scroll_prev" for="SlideD"></label>
<!-- 次へボタン 上と同様にforで進む先のラジオボタンのidを書きます。-->
<!-- 進み先は2番目の要素なので、2番目のスライドのid"SlideB"を書いています。 -->
<label class="scroll_button scroll_next" for="SlideB"></label>
</div>
<!-- スライドの内容(ここでは画像)を記述します。 -->
<!-- div要素に変えれば文字を加えることもできます。 -->
<img src="https://picsum.photos/320/180?random=1">
</div>
<!-- スライド(2番目)内容は1個めと同じ -->
<div class="slide">
<div class="controler_scroll">
<label class="scroll_button scroll_prev" for="SlideA"></label>
<label class="scroll_button scroll_next" for="SlideC"></label>
</div>
<img src="https://picsum.photos/320/180?random=2">
</div>
<!-- スライド(3番目)内容は1個めと同じ -->
<div class="slide">
<div class="controler_scroll">
<label class="scroll_button scroll_prev" for="SlideB"></label>
<label class="scroll_button scroll_next" for="SlideD"></label>
</div>
<img src="https://picsum.photos/320/180?random=3">
</div>
<!-- スライド(4番目)内容は1個めと同じ -->
<div class="slide">
<div class="controler_scroll">
<label class="scroll_button scroll_prev" for="SlideC"></label>
<label class="scroll_button scroll_next" for="SlideA"></label>
</div>
<img src="https://picsum.photos/320/180?random=4">
</div>
<!-- スライド移動用ボタン -->
<div class="move_controler">
<!-- 1個目のスライドのボタン -->
<!-- 一番上のラジオボタンの1個目のスライドのid”A”をforに定義します-->
<label class="button_move" for="SlideA"></label>
<label class="button_move" for="SlideB"></label>
<label class="button_move" for="SlideC"></label>
<label class="button_move" for="SlideD"></label>
</div>
</div>
</div>
少し長いコードですが、ポイントは以下の点になります。
スライド切替用のラジオボタンリストを作成する
表示したいスライドの数と同じ項目数のラジオボタンを作成します。
このラジオボタンの切り替えに合わせて表示するスライドを変えます。
<!-- スライドを選択するためのラジオボタンリスト。 -->
<!-- 数は増減しても構わないです。 最初は1番目を選択状態(checked)にします。-->
<!-- Slide各ラジオボタンに個別のidを定義して、nameはすべて同じ値にします。 -->
<input class="slide_select" type="radio" id="SlideA" name="slide_check" checked />
<input class="slide_select" type="radio" id="SlideB" name="slide_check" />
<input class="slide_select" type="radio" id="SlideC" name="slide_check" />
<input class="slide_select" type="radio" id="SlideD" name="slide_check" />
前へ
と次へ
ボタンの作成
各スライドのdiv要素内に、スライドを前後のものに切り替えるための前へ
と次へ
ボタンを記述します。
ボタンを押すと、前後のスライドに選択が切り替わるように、次のように記述します。
- ボタンは
label
タグで記述 - labelタグの
for
属性に、上で書いたラジオボタンの前後のスライドに該当する要素のid
を記述
これで、ボタンのクリックでラジオボタンの選択がid
に書いた項目に切り替わります。
<div class="slide">
<!-- スライドの前へ、次へとスクロールさせるボタン -->
<div class="scroll_controler">
<!-- 前へボタン forで戻る先のラジオボタンのidを書きます。-->
<!-- 先頭要素なので、最後のスライドのidである"SlideD"を書いています。 -->
<label class="scroll_button scroll_prev" for="SlideD"></label>
<!-- 次へボタン 上と同様にforで進む先のラジオボタンのidを書きます。-->
<!-- 進み先は2番目の要素なので、2番目のスライドのid"SlideB"を書いています。 -->
<label class="scroll_button scroll_next" for="SlideB"></label>
</div>
移動ボタンを作成
選択したスライドに直接移動するボタンを一番下に記述します。
こちらのボタンも上と同様に、label
タグでfor
属性に切り替え先のスライドに該当するラジオボタンのid
を記述します。
<!-- スライド移動用ボタン -->
<div class="move_controler">
<!-- 1個目のスライドのボタン -->
<!-- 一番上のラジオボタンの1個目のスライドのid”A”をforに定義します-->
<label class="button_move" for="SlideA"></label>
<label class="button_move" for="SlideB"></label>
<label class="button_move" for="SlideC"></label>
<label class="button_move" for="SlideD"></label>
</div>
</div>
</div>
CSSを記述する
CSSの内容は以下になります。
/* カルーセル全体 */
.carousel {
/* 水平方向中央寄せ */
display: flex;
justify-content: center;
}
/* カルーセル内容 */
.contains {
/* サイズは自由に変更してください。*/
/* 下の.slideも同じサイズにしてください。 */
width: 320px;
height: 180px;
overflow: hidden;
position: relative;
padding: 0;
list-style: none;
}
/* スライド切り換え用ラジオボタンは常に非表示 */
.slide_select {
display: none;
}
/* 各スライド */
.slide {
/* サイズは自由に変更してください。*/
/* 上の.containsも同じサイズにしてください。 */
width: 320px;
height: 180px;
position: absolute;
/* スライドの初期値は選択されていないので透明にしておく */
opacity: 0;
}
/* 前へ次へボタン */
.scroll_button {
position: absolute;
display: block;
height: 30px;
width: 30px;
/* 縦中央から20px上の位置 */
top: 50%;
margin-top: -20px;
/* 上辺と右辺のみ幅5pxの枠線 */
border-width: 5px 5px 0 0;
border-style: solid;
border-color: #fdfdfd;
cursor: pointer;
/* 普段はボタンはやや薄くする */
opacity: 0.5;
/* スライドよりも前面にする */
z-index: 3;
}
/* ホバー時にボタンを強調 */
.scroll_button:hover {
opacity: 1;
}
/* 前へボタン */
.scroll_prev {
left: 15px;
/* 上辺と右辺の枠線を回転して"<"にする */
transform: rotate(-135deg);
}
/* 次へボタン */
.scroll_next {
right: 15px;
/* 上辺と右辺の枠線を回転して">"にする */
transform: rotate(45deg);
}
/* スライド移動ボタンエリア */
.move_controler {
position: absolute;
bottom: 20px;
width: 100%;
text-align: center;
}
/* スライド移動の各ボタン */
.button_move {
display: inline-block;
height: 15px;
width: 15px;
margin: 0 2px;
border-radius: 100%;
cursor: pointer;
/* 普段はやや薄くする */
opacity: 0.5;
/* スライドより前面にする */
z-index: 2;
}
/* ホバー時はやや明るくする */
.button_move:hover {
opacity: 0.75;
}
/* スライド移動ボタンの色 */
.button_move {
background-color: #fdfdfd;
}
/* 1番目のスライド選択時 */
/* 1番目のスライドの透明度を0にして表示する */
.slide_select:nth-of-type(1):checked ~ .slide:nth-of-type(1) {
opacity: 1;
}
/* スライド移動ボタンの1個目を明るくする */
/* (今選択されていることが分かるように) */
.slide_select:nth-of-type(1):checked ~ .move_controler .button_move:nth-of-type(1) {
opacity: 1;
}
.slide_select:nth-of-type(2):checked ~ .slide:nth-of-type(2) {
opacity: 1;
}
/* 2番目のスライド選択時(1番目のスライドと同じことをする) */
.slide_select:nth-of-type(2):checked ~ .move_controler .button_move:nth-of-type(2) {
opacity: 1;
}
/* 3番目のスライド選択時 */
.slide_select:nth-of-type(3):checked ~ .slide:nth-of-type(3) {
opacity: 1;
}
.slide_select:nth-of-type(3):checked ~ .move_controler
.button_move:nth-of-type(3) {
opacity: 1;
}
/* 4番目のスライド選択時 */
.slide_select:nth-of-type(4):checked ~ .slide:nth-of-type(4) {
opacity: 1;
}
.slide_select:nth-of-type(4):checked
~ .move_controler
.button_move:nth-of-type(4) {
opacity: 1;
}