先日制作した案件で、タイムライン(過去→未来)があったんですね。
こういうのです。
デザインがイラレで来ていて、さてどうしましょうか、と。
もちろん画像でもOKなんですが、横長をタイムラインをスマホで見たら小さくて見えない。
かといって縦長の画像は作りたくない。※それなりに数があったので。
それじゃCSSだけで実装しましょ、とういうことになりました。
やってみよう
条件
- 広い画面では横型、狭くなったら縦型にする
- 項目数は変動する
- ポイントごとに目印をつける
もちろん、まず一直線を引いて、その上に絶対配置でポイントを打つのもアリだと思います。
今回は基本形を元にちょっといろいろしてみました。
けどあんまりうまくいかなかった。。。
ついでにCSSがいろいろ汚染しまくって悪い見本みたいになってます。
お目汚しですが、よかったらどうぞ。。。
基本形
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<div class="timeline"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">10年後</p> <p class="timeline-content">Webはまだ大丈夫。</p> </div> <div class="timeline-item"> <p class="timeline-label">20年後</p> <p class="timeline-content">スナフキンになりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> |
SASS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
.timeline{ padding: 3rem 5rem; background-color: #f0f0f0; &-item{ position: relative; border-left: 1px solid #000; padding: 0 0 30px 30px; &:before{ content: ''; display: block; width: 10px; height: 10px; position: absolute; left: 0; top: 0; border-radius: 100%; background-color: #000; transform: translateX(-50%) translateY(-50%); } &:last-of-type{ padding-bottom: 0; &:before{ width: 0; height: 0; border-style: solid; border-width: 10px 5px 0 5px; border-color: #000000 transparent transparent transparent; border-radius: 0; background-color: transparent; top: auto; bottom: 0; transform: translateX(-50%) translateY(0); } } } @media(min-width : 768px){ display: table; table-layout: fixed; width: 100%; &-item{ display: table-cell; vertical-align: top; padding: 0; border:{ top: 1px solid #000; bottom: 0; left: 0; } &:last-of-type{ padding-bottom: 0; text-align: right; &:before{ border-width: 5px 0 5px 10px; border-color: transparent transparent transparent #000000; top: 0; right: 0; bottom: auto; left: auto; transform: translateX(0) translateY(-50%); } p{ text-align: left; } } } &-label, &-content{ transform: translateX(-50%); text-align: left; display: block; max-width: 70%; } &-label{ text-align: center; position: absolute; top: 0; left: 0; transform: translateX(-50%) translateY(-120%); } &-content{ margin-top: 10px; } &-item:last-of-type &-label, &-item:last-of-type &-content{ transform: translateX(50%); text-align: left; display: inline-block; max-width: 70%; } &-item:last-of-type &-label{ left: auto; right: 0; transform: translateX(50%) translateY(-120%); } } } /* 現在地 */ .timeline-item.now:before{ background-color: #f00; } |
やってること
そんなに難しいことはしてません。
displayを切り替えて、ボーダー引く場所を変えているだけです。
狭い画面では縦型なのでdisplay: block;でいいですね。ボーダーは左に引きました。
横型の場合は、親要素をtableに、子要素をtable-cellにしてみました。(※flexでもうまくいくかもしれません。)
それから親要素にtablelayout: fixed;を指定して均等に割ります。
文字や時間の長さに長短がある場合は子要素のwidthをパーセントで指定してあげればOKです。
目印は子要素の擬似要素で。
基本的には左上に絶対配置して、自分の大きさ分だけ移動(transform: translateX(-50%) translateY(-50%);)します。
最後の子要素だけは矢印っぽくしたいので、三角にしました。これは縦横で向きを変えてあげてくださいね。
現在地は専用のクラスを振って文字色を変えました。
【DEMO】にのっけた他のやつのコードも一応載せときますね。
本当は背景を矢印っぽくするところまで行きたかったんですけど、パッと思いつかなかったので、とりあえず今回はここまで。
年末進行でお忙しいと思いますが、みなさんお体に気をつけて頑張っていきましょう!
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
<h2>基本形</h2> <div class="timeline"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">10年後</p> <p class="timeline-content">Webはまだ大丈夫。</p> </div> <div class="timeline-item"> <p class="timeline-label">20年後</p> <p class="timeline-content">スナフキンになりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> <h2>数が減っても大丈夫</h2> <div class="timeline"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">30年後</p> <p class="timeline-content">煙になりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> <h2>数が増えても大丈夫</h2> <div class="timeline"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">10年後</p> <p class="timeline-content">Webはまだ大丈夫。</p> </div> <div class="timeline-item"> <p class="timeline-label">20年後</p> <p class="timeline-content">スナフキンになりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">30年後</p> <p class="timeline-content">煙になりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> <h2>ボーダー有り</h2> <div class="timeline border-dashed"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">10年後</p> <p class="timeline-content">Webはまだ大丈夫。</p> </div> <div class="timeline-item"> <p class="timeline-label">20年後</p> <p class="timeline-content">スナフキンになりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> <h2>ストライプ背景</h2> <div class="timeline bg-stripe"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">10年後</p> <p class="timeline-content">Webはまだ大丈夫。</p> </div> <div class="timeline-item"> <p class="timeline-label">20年後</p> <p class="timeline-content">スナフキンになりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> <h2>ストライプ背景</h2> <div class="timeline-wrapper"> <div class="timeline bg-arrow"> <div class="timeline-item"> <p class="timeline-label">10年前</p> <p class="timeline-content">じつはまだ学生でした。</p> </div> <div class="timeline-item now"> <p class="timeline-label">現在</p> <p class="timeline-content">結構いい年です。</p> </div> <div class="timeline-item"> <p class="timeline-label">10年後</p> <p class="timeline-content">Webはまだ大丈夫。</p> </div> <div class="timeline-item"> <p class="timeline-label">20年後</p> <p class="timeline-content">スナフキンになりたい。</p> </div> <div class="timeline-item"> <p class="timeline-label">その後</p> <p class="timeline-content">仙人。</p> </div> </div> </div> |
SASS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
.timeline{ padding: 3rem 5rem; background-color: #f0f0f0; &-item{ position: relative; border-left: 1px solid #000; padding: 0 0 30px 30px; &:before{ content: ''; display: block; width: 10px; height: 10px; position: absolute; left: 0; top: 0; border-radius: 100%; background-color: #000; transform: translateX(-50%) translateY(-50%); } &:last-of-type{ padding-bottom: 0; &:before{ width: 0; height: 0; border-style: solid; border-width: 10px 5px 0 5px; border-color: #000000 transparent transparent transparent; border-radius: 0; background-color: transparent; top: auto; bottom: 0; transform: translateX(-50%) translateY(0); } } } @media(min-width : 768px){ display: table; table-layout: fixed; width: 100%; &-item{ display: table-cell; vertical-align: top; padding: 0; border:{ top: 1px solid #000; bottom: 0; left: 0; } &:last-of-type{ padding-bottom: 0; text-align: right; &:before{ border-width: 5px 0 5px 10px; border-color: transparent transparent transparent #000000; top: 0; right: 0; bottom: auto; left: auto; transform: translateX(0) translateY(-50%); } p{ text-align: left; } } } &-label, &-content{ transform: translateX(-50%); text-align: left; display: block; max-width: 70%; } &-label{ text-align: center; position: absolute; top: 0; left: 0; transform: translateX(-50%) translateY(-120%); } &-content{ margin-top: 10px; } &-item:last-of-type &-label, &-item:last-of-type &-content{ transform: translateX(50%); text-align: left; display: inline-block; max-width: 70%; } &-item:last-of-type &-label{ left: auto; right: 0; transform: translateX(50%) translateY(-120%); } } /* ボーダー有り */ &.border-dashed &-item{ border-top: 1px dashed #ccc; padding: 10px; &:last-of-type{ border: { top: none; bottom: 1px dashed #ccc; } } @media(min-width : 768px){ padding: 0; border:{ top: 1px solid #000; left: 1px dashed #ccc; } &:last-of-type{ border: { top: 1px solid #000; right: 1px dashed #ccc; bottom: 0; } } } } /* ストライプ背景 */ &.bg-stripe &-item{ &:nth-of-type(odd){ background-color: #e8e8e8; } &:nth-of-type(even){ background-color: #fff; } } @media(min-width : 768px){ &.bg-stripe &-label, &.bg-stripe &-content{ transform: translateX(0); text-align: left; display: block; max-width: 70%; } &.bg-stripe &-label{ transform: translateX(0) translateY(-120%); } &.bg-stripe &-content{ display: inline-block; } } /* PCの時は矢印っぽく */ &-wrapper{ padding: 3rem 5rem; background-color: #f0f0f0; } &.bg-arrow{ padding: 0; } &.bg-arrow &-item{ position: relative; border: { top: none; } } @media(min-width : 768px){ &.bg-arrow{ padding: 20px 0 0; overflow: hidden; } &.bg-arrow &-item{ &:before{ height: 100%; width: 100%; top: 0; left: 0; right: 0; bottom: 0; border:{ color: transparent; radius: 0; } box-shadow: 1px -1px 2px rgba(125, 125, 125, 0.8); transform: skew(-45deg); transform-origin:0 0; background: -moz-linear-gradient(45deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.3) 100%); /* FF3.6-15 */ background: -webkit-linear-gradient(45deg, rgba(0,0,0,0) 0%,rgba(0,0,0,0.3) 100%); /* Chrome10-25,Safari5.1-6 */ background: linear-gradient(45deg, rgba(0,0,0,0) 0%,rgba(0,0,0,0.3) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ } } &.bg-arrow &-label, &.bg-arrow &-content{ transform: translateX(0); text-align: left; display: block; max-width: 70%; } &.bg-arrow &-label{ transform: translateX(0) translateY(-120%); } &.bg-arrow &-content{ display: inline-block; } &.bg-arrow &-item:last-of-type{ padding-bottom: 0; text-align: right; &:before{ border: none; top: 0; left: 0; right: 0; bottom: 0; transform: translateX(0) translateY(0) skew(-45deg); } p{ text-align: left; display: block; } } } } /* 現在地 */ .timeline-item.now:before{ background-color: #f00; } |