スタイルではなく、インタラクションに関するJavaScriptの依存関係
効果的なカルーセルは、次の点でJavaScriptに依存しないカルーセルです。
•応答性
•任意の数の要素のコンテンツ
•任意の数の要素の表示
挑戦する
要素を横に並べたカルーセル(行)に表示する方法は多数ありますが、これらの方法のいくつかは他の方法よりも優れています。
フロートを使用
disneystore.comのカルーセルは、このスタイルの2つの主な制限を示しています。
•コンテナは、行内のすべての要素を表示する(クロールを回避する)ために、子要素(外枠)の幅の合計以上の幅を持つ必要があります。
•ブロックのサイズ(この幅の計算の基礎として使用されるフレーム)はカルーセルの表示領域ではなく、その子の数に関連付けられているため、要素の幅をパーセントで指定することはできません。
問題をよりよく理解するには、次の例を見てください。
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> ul { border: 5px solid deeppink; overflow: hidden; /* */ } li { border: 1px solid #fff; background: #3CB371; width: 100px; height: 100px; float: left; }
上記のリストには5つの要素が含まれています。すべてがfloat要素を使用して装飾されています。 リスト自体は、overflow:hiddenを使用して作成されるため(ブロックの書式設定コンテキストを作成するため)、リストは折り畳まれずにフロートを揃えます。
ここでの問題は、以下に示すように、コンテナの幅がこれらすべての要素を一列に収めるのに十分でない場合、要素がスライドすることです。
ul { overflow: hidden; /* */ width: 450px; } li { float: left; }
したがって、このソリューションでは、コンテナの正確な幅を設定する必要があります。これにより、このコンテナが応答しなくなります(JavaScriptが不要)。
使用位置:絶対
on.aol.comのようなカルーセルでは、すべての要素がストリームから削除されるため、各要素は、前の兄弟の直後に表示される個別のオフセット値に依存します。
別の例を見てみましょう:
ul { height: 100px; /* */ } li { position: absolute; }
すべてのフレームには絶対配置があるため、ストリームから削除され、同じx / y座標に配置されます。 最後のフレームはスタックの一番上を示しています。
その結果、作成者は3つのことを行う必要があります。
•height要素を使用してコンテナを描画し、後続の要素(フレーム外)の上方への移動を防ぎます。
•各フレームを左シフト(左)で配置して、要素を行に表示します。
•position:相対要素を使用してコンテナを描画し、子要素を含むブロックに変換します。
同じフレームワークが次のように作成されます。
ul { height: 100px; /* */ position: relative; /* , AP */ } li { position: absolute; } li:nth-child(2) { left: 100px; /* + / */ } li:nth-child(3) { left: 200px; /* + / */ } li:nth-child(4) { left: 300px; /* + / */ } li:nth-child(5) { left: 400px; /* + / */ }
これがaol.comのカルーセルの作成方法であり、すべてのオフセットはピクセル単位で示されます。 しかし、興味深いのは、コンテナの幅がフロートを使用した例と同じ方法で設定されることです。 コンテナは、すべての子の合計幅と同じ幅になるように設計されています-position:absoluteを使用している場合でも、作成者はコンテナブロックの特性を改善するよりシンプルなアプローチを使用できます。
フロート構造とは異なり、コンテナの幅はネストされたフレームの配置に影響しません。 つまり、パーセンテージを使用して、要素を全幅(100%)で表示したり、コンテナの一部(要素が含まれるブロック)として表示したりできます。 たとえば、比率が50%の各フレームの設計では、次のように2つの要素が連続して表示されます。
ul { height: 100px; /* */ position: relative; /* , AP */ width: 30%; } li { position: absolute; width: 50%; } li:nth-child(2) { left: 50%; /* + / */ } li:nth-child(3) { left: 100%; /* + / */ } li:nth-child(4) { left: 150%; /* + / */ } li:nth-child(5) { left: 200%; /* + / */ } ul { height: 100px; /* */ position: relative; /* , AP */ width: 30%; } li { position: absolute; width: 50%; } li:nth-child(2) { left: 50%; /* + / */ } li:nth-child(3) { left: 100%; /* + / */ } li:nth-child(4) { left: 150%; /* + / */ } li:nth-child(5) { left: 200%; /* + / */ }
上記のコンテナの幅(幅)は30%に設定され、他のすべての値(左オフセットとフレームの幅)もパーセンテージで示されます。
ul { height: 100px; /* */ position: relative; /* , AP */ width: 50%; } li { position: absolute; width: 25%; } li:nth-child(2) { left: 25%; /* + / */ } li:nth-child(3) { left: 50%; /* + / */ } li:nth-child(4) { left: 75%; /* + / */ } li:nth-child(5) { left: 100%; /* + / */ }
この場合、コンテナの幅は50%で、各フレームの幅は25%です。これにより、コンテナ内に4つのフレームを連続して表示できます。
このソリューションはフロートを使用するよりも確実に優れていますが、ここでの欠点は、ストリームからすべての要素を削除するには、後続のソース要素がすべてのフレームを超えて表示されないように高さを示すコンテナが必要になることです。
解決策
大まかに言えば、このソリューションでは、要素を含むブロックがカルーセルの可視領域に対応し、ストリームから何も落ちないことを確認する必要があります。ここでは、コンテンツがカルーセルの高さを設定します。
インラインブロックを使用します
基本から始めましょう:
<ul> <li>1</li><!-- --><li>2</li><!-- --><li>3</li><!-- --><li>4</li><!-- --><li>5</li> </ul>
li { display: inline-block; }
フロートを使用した構造のように、このようなシンプルなデザインとレイアウトでは、十分なスペースがない場合、ネストされたフレームはスリップします。
ul { width: 450px; } li { display: inline-block; }
魔法の薬
white-space:nowrap:を使用して、フレームのクロールを回避できます。
ul { width: 450px; white-space: nowrap; } li { display: inline-block; }
これで、コンテナの高さの正確な値を設定したり、ネストしたフレームをオフセットで配置したり、正確な値で幅を調整したりする必要のないソリューションが得られました。 ボーナスとして、このソリューションはRTLに適しています。
<ul class="example example-10" dir="rtl"> <li>1</li><!-- --><li>2</li><!-- --><li>3</li><!-- --><li>4</li><!-- --><li>5</li> </ul>
カルーセルの実装
マージンオフセット
最初の要素で左マージンを使用すると、すべてのフィールドを一度に(左または右)シフトできます。
ul { width: 100px; white-space: nowrap; } li { display: inline-block; width: 100%; } li:first-child { margin-left: -100%; /* IE */ }
overflow:hiddenでコンテナを作成すると、コンテナの外側にある要素が非表示になります。
ul { width: 100px; white-space: nowrap; overflow: hidden; } li { display: inline-block; width: 100%; } li:first-child { margin-left: -100%; }
覚えておくべき唯一のことは、このスタイルが継承される場合、nowrapの説明をリセットすることです。
移動、位置などによるオフセット
最初の子ではなくコンテナを移動するには、追加のラッパーを使用する必要があります(すべてのスタイルがリストからこのアドインに転送されることに注意してください)。
<div> <ul> <li>1</li><!-- --><li>2</li><!-- --><li>3</li><!-- --><li>4</li><!-- --><li>5</li> </ul> </div> div { white-space: nowrap; width: 50%; overflow: hidden; border: 5px solid deeppink; }
ul { border: none; *position: relative; /* oldIE */ *left: -100%; /* oldIE */ transform: translateX(-100%); } /* IE8 */ @media screen\0 { .example-13 { position: relative; left: -100%; } } li { white-space: normal; /* */ display: inline-block; width: 50%; }
のぞき要素を備えたカルーセル
このソリューションは次のように簡単に実行できます。
div { padding-right: 12%; /* , */ } img { width: 100%; /* , */ vertical-align: bottom; }
カルーセルの高さを指定するのは画像であり、JavaScriptを使用せずにすべてのフィールドが応答し、正しく配置されることに注意してください。
ピュアCSSメリーゴーラウンドカルーセル
数学の知識を必要としないロジック!
<div class="carousel"> <input role="presentation" name="carousel" type="radio" value="1" checked /> <input role="presentation" name="carousel" type="radio" value="2" /> <input role="presentation" name="carousel" type="radio" value="3" /> <input role="presentation" name="carousel" type="radio" value="4" /> <input role="presentation" name="carousel" type="radio" value="5" /> <ul class="carousel-list"> <li><img src="..." alt="Mask #1"></li><!-- --><li><img src="..." alt="Mask #2"></li><!-- --><li><img src="..." alt="Mask #3"></li><!-- --><li><img src="..." alt="Mask #4"></li><!-- --><li><img src="..." alt="Mask #4"></li> </ul> </div> <div class="carousel"> <input role="presentation" name="carousel" type="radio" value="1" checked /> <input role="presentation" name="carousel" type="radio" value="2" /> <input role="presentation" name="carousel" type="radio" value="3" /> <input role="presentation" name="carousel" type="radio" value="4" /> <input role="presentation" name="carousel" type="radio" value="5" /> <ul class="carousel-list"> <li><img src="..." alt="Mask #1"></li><!-- --><li><img src="..." alt="Mask #2"></li><!-- --><li><img src="..." alt="Mask #3"></li><!-- --><li><img src="..." alt="Mask #4"></li><!-- --><li><img src="..." alt="Mask #4"></li> </ul> </div>
.carousel { width: 200px; padding: 5px; overflow: hidden; border: 1px solid #ccc; border-radius: 3px; text-align: center; /* - */ } .carousel-list { white-space: nowrap; padding: 0; margin: 0; transition: transform .3s; } .carousel-list li { white-space: normal; /* */ display: inline-block; width: 100%; } .carousel-list img { width: 100%; /* */ vertical-align: bottom; /* */ } /** * - */ input:nth-child(1):checked ~ ul { transform: translateX(0); } input:nth-child(2):checked ~ ul { transform: translateX(-100%); } input:nth-child(3):checked ~ ul { transform: translateX(-200%); } input:nth-child(4):checked ~ ul { transform: translateX(-300%); } input:nth-child(5):checked ~ ul { transform: translateX(-400%); } /** * */ .carousel-list li { opacity: .1; transition: all .4s; transform: scale(.1); } input:nth-child(1):checked ~ ul li:nth-child(1), input:nth-child(2):checked ~ ul li:nth-child(2), input:nth-child(3):checked ~ ul li:nth-child(3), input:nth-child(4):checked ~ ul li:nth-child(4), input:nth-child(5):checked ~ ul li:nth-child(5) { opacity: 1; transform: scale(1); }
以下の幅の値を編集して、このソリューションの応答性を確認できます。
.carousel{width:200px}
より複雑なカルーセル
一度に1つのカルーセル要素を移動して、ギャップで区切られた2つの要素を表示する方法。
.carousel { display: inline-block; width: 200px; padding-right: 190px; /* 10px */ overflow: hidden; border: 1px solid #ccc; border-radius: 3px; text-align: center; /* - */ } .carousel-list { white-space: nowrap; padding: 0; margin: 0; border: none; transition: transform .3s; } .carousel-list li { white-space: normal; /* */ display: inline-block; width: 100%; box-sizing: border-box; padding-right: 10px; /* */ } .carousel-list img { width: 100%; /* */ vertical-align: bottom; } .carousel input { margin-left: -3px; } .carousel input:nth-child(1):checked ~ ul { transform: translateX(0); } .carousel input:nth-child(2):checked ~ ul { transform: translateX(-100%); } .carousel input:nth-child(3):checked ~ ul { transform: translateX(-200%); } .carousel input:nth-child(4):checked ~ ul { transform: translateX(-300%); } .carousel input:nth-child(5):checked ~ ul { transform: translateX(-400%); } .carousel input:nth-child(6):checked ~ ul { transform: translateX(-500%); } .carousel input:nth-child(7):checked ~ ul { transform: translateX(-600%); }
Habré読者向けの便利なPaystoソリューション: