1. シナリオ
左側に小さな丸(ドット)が並び、右側にリストのコンテンツが配置されるタイムラインリストを実装する必要があります。小さな丸の位置はリストの項目と対応している必要があり、最終的な表示は以下のようになります:
[caption id="attachment_1220" align="alignnone" width="313"]
timeline[/caption]
2. 実装案
いくつかの重要なディテールがあります:
-
小さな丸はリストの項目と位置を合わせる必要がある
-
最初と最後の項目のタイムライン(縦線)は、小さな丸を超えて伸びてはいけない
-
リストの項目間には間隔を設ける必要がある
最初の2つは自動適応への要求であり、最後の1つはレイアウト上の制限です。
従来の手法では、リストのコンテナに十分な長さの縦線を引かせ、リスト項目自体に小さな丸を持たせて、その丸を縦線に合わせるという方法をとります。しかし、この方法では縦線の長さを正確に制御できず(JSで計算しない限り)、2つ目の要件を満たせません。そこでアプローチを変え、各リスト項目に自身の高さと同じ長さの縦線を持たせ、それらを繋ぎ合わせて完全なタイムラインを形成するようにします。
P.S. 繋ぎ合わせた縦線の継ぎ目が見えてしまう心配はありません。ブラウザが正常に動作していれば、絶対にシームレスに繋がります(隣接するブロックレベル要素の間に説明のつかない隙間ができることはありません。したがって、それらの border-left は完璧に繋がるはずです)。
3. 具体的な実装
まず構造を決定します。リスト項目間の間隔を設ける制限があるため、リスト項目をもう1階層ラップする必要があります:
.listItem>.listItemContent>.listItemContent-date+.listItemContent-content
margin を使って間隔を作ると縦線の長さが合わず繋がらなくなるため、外側に listItem という階層を追加し、margin を padding に置き換えます。縦線と小さな丸は listItem が保持します:
/* リスト項目間の間隔は paddingTop で設定 */
.listItem {
position: relative;
padding-left: 40px;
padding-top: 4px;
}
/* リスト項目自体が持つ縦線 */
.listItem:before {
content: "";
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 100%;
border-right: 1px solid #f3f3f3;
left: 19px;
z-index: 1;
}
/* リスト項目自体が持つ小さな丸 */
.listItem:after {
content: "";
display: inline-block;
position: absolute;
width: 8px;
height: 8px;
background-color: #e0e0e0;
border-radius: 4px;
left: 16px;
top: 50%;
margin-top: -2px;
z-index: 1;
}
注意すべきは小さな丸の margin-top です。この -2px は目視で決めたものではなく、リスト項目の間隔と小さな丸の高さに関係しています:
// top 50%, marginTop -50% は、小さな丸を listItem に対して垂直方向に中央揃えにします
h = listItemContent.height
pt = listItem.paddingTop
ch = 小さな丸.height
y = (h + pt)/2 - ch/2
// 今回は、小さな丸を listItemContent に対して垂直方向に中央揃えにしたい
// pt によって生じる下方向へのズレ offsetY = pt/2 を取り除く必要があるため
top 50%, marginTop -ch/2 + offsetY
top 50%, marginTop -4 + 2
top 50%, marginTop -2
これが margin を padding に変更し、階層を追加したことによる厄介な点です。
次に、最初と最後の項目のタイムラインが小さな丸を超えないように制限を加えます:
.listItem-first:before {
height: 50%;
top: 50%;
}
.listItem-last:before {
height: 50%;
}
最後にハイライト効果を追加します:
/* ハイライト状態の小さな丸 */
.listItem.highlight:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 16px;
height: 16px;
background-color: #3d93fd;
border: 4px solid #88bdfe;
border-radius: 8px;
left: 12px;
-webkit-box-shadow: 0 0 0 3px #d8e9ff;
box-shadow: 0 0 0 3px #d8e9ff;
z-index: 2;
}
/* ハイライト状態のリスト項目 */
.listItem.highlight > .listItemContent {
background-color: #3d93fd;
color: #fff;
}
/* ハイライト状態のリスト項目の内容 */
.listItem.highlight .listItemContent-date{
color: #fff;
}
4. デモ
オンラインデモ:http://www.ayqy.net/temp/timeline/index.html
リスト項目をクリックするとハイライトされ、リスト項目の内容はHTMLと画像の自動適応をサポートしています。
終わりに
最近JSのアニメーション原理を勉強しています。月影先輩のシェアに感謝します。非常に深い知識です。
以前何度か読んでいたのですが、ずっと完全に理解できていませんでした。自分で実装してみて初めて、数式とイージング(easing)演算子の関係に気づきました。
強くお勧めします:アニメーションについて、あなたが知っておくべきこと
コメントはまだありません