Timeline 時間線的功能很常出現在履歷表,或是各種跟年分有關的介紹。原本參考 W3schools How To 的 Timeline 範例圖片【1】,想說應該能簡單的切出預期的圖形,沒想到竟然卡住了,由於時間關係,當下反應是「或許整個砍掉重練還比較快?!」,於是先放棄原來的切版,直接學習 How To 的作法...
首先,我們要加入 HTML 檔案,架構是這樣的:「最外層用一個 Class 名稱為 timeline 的 div,包住所有的元素,Class 為container left
或是container right
,left 代表放在時間線左邊的訊息方框,而 right 則是指放在時間線右邊的訊息。container
裡面有一個content
,用來放置內容,而這個內容則是由一個標題和一段文字所組成。
HTML:
<div class="timeline">
<div class="container left">
<div class="content">
<h2>2022</h2>
<p>Lorem ipsum dolor sit amet, quo ei simul congue exerci, ad nec admodum perfecto mnesarchum, vim ea mazim fierent detracto. Ea quis iuvaret expetendis his, te elit voluptua dignissim per, habeo iusto primis ea eam.</p>
</div>
</div>
<div class="container right">
<div class="content">
<h2>2021</h2>
<p>Lorem ipsum dolor sit amet, quo ei simul congue exerci, ad nec admodum perfecto mnesarchum, vim ea mazim fierent detracto. Ea quis iuvaret expetendis his, te elit voluptua dignissim per, habeo iusto primis ea eam.</p>
</div>
</div>
顯示結果:
在複製時,left 和 right 要交錯排放。也就是說要用 left、right、left、right …這種寫法,這樣之後在排版交錯時,才不會出現問題。
在全部 CSS(星號)中加入box-sizing: border-box;
,這樣寫可以更好的控制元件的大小,此時可以加入這行語法。
box-sizing: border-box;
代表依照 border 框線為基準起始點,使得內部間距過大時,不會因此讓圖形跑版。也就是能更精確控制元素。可參考用法【2】。
CSS:
* {
box-sizing: border-box;
}
body {
background-color: #474e5d;
font-family: Helvetica, sans-serif;
}
而在 body 部分,設定一個背景色#474e5d
,以及字體樣式修改成Helvetica、sans-serif
。
顯示結果:
首先,要讓所有的元素置中,直接控制最外層名稱為timeline
的 Class,設定最大寬度為1200px
,設定最大寬度用意在於版面閱讀舒適性,timeline 也是父層,為了讓內部元素對齊父層,將position
設定為 relative
。最後,使用一個margin: 0 auto;
可以讓 timeline 整個置中畫面正中間。
CSS:
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
}
顯示結果:
接著,要製作一個白色的中心線,線寬為 6px。這裡使用 after 偽元素來製作,要注意的是,使用 before、after 的偽元素【3】,裡面需要加入 content 的屬性,這樣偽元素才能使用(若沒有要加文字時,可直接加入空字串””)。
然後,為了要將產生的白線置中,先把position
設定為absolute
,這樣會讓白線能夠自由移動,position
不用relative
原因則是要讓元素不占空間,不會影響其他元素排版。當我們有了position
後即可使用上下左右來做排版,這裡將上、下設為 0,靠左 50% 的地方對齊,這樣寫就能讓白線靠近中間,最後,因為白線本身有寬度,所以,使用margin-left: -3px;
作微調,margin-left:
後面的數值為總寬度的一半-(width /2)px
,會這樣寫的原因是,寬度會從最左邊當起始點,為了要讓基準點落在正中心,就要把寬度除 2。
CSS:
.timeline::after {
content: '';
position: absolute;
width: 6px;
background-color: white;
top: 0;
bottom: 0;
left: 50%;
margin-left: -3px;
}
position 的預設對齊基準為 body。
顯示結果:
這裡的訊息方框指的是可放置內容的元素,這個訊息框的 Class 名稱為container,
這裡設定 container 的 padding,可讓內容文字有上下、左右產生間距。因為要保留文字的版面位置,所以使用 position 為relative
,背景色用 inherit 繼承父層,重要的是寬度
,寬度設定50%
,將全部的訊息框都移至白線左邊。
CSS:
.container {
padding: 10px 40px;
position: relative;
background-color: inherit;
width: 50%;
}
顯示結果:
圓點圖形用途是放在白線上的裝飾,它的製作方法很簡單,只要用繪製一個圓形後,將 border 寬度加粗即可。比較特別的是,這個圓形要在 container 的偽元素::after
(也可以用::before
)來完成。before 和 after 的用法可以參考這篇。
position
設定為absolute
,讓圓點能夠移動,剩下其餘的參數用來產生圖形, 這裡可以注意z-index: 1;
的用法,這樣寫可以讓圖形擺放到最前面的位置,z-index:
放的數字越大,圖形堆疊時就會越靠近最上層。
CSS:
.container::after {
content: "";
position: absolute;
width: 25px;
height: 25px;
right: -17px;
background-color: white;
border: 4px solid #ff9f55;
top: 15px;
border-radius: 50%;
z-index: 1;
}
顯示結果:
bfore 和 after 可以分別放在元素的前和後,但如果使用了
position: absolute;
,是否 bfore 和 after 之間就沒有區別了呢?這部分有請大神幫忙解答。
這裡要決定訊息框是要在白線的左邊(left)或是(right), 由於我們在 timeline 已經設定 position 為 relative,left 和 right 可直接使用,left 為 0, right 為 50%。
CSS:
.left {
left: 0;
}
.right {
left: 50%;
}
顯示結果:
這裡對 left 和 right 的偽元素上各添加一個三角形的圖示,關於三角形的作法,可以參考這篇。
CSS:
.left::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
right: 30px;
border: medium solid white;
border-width: 10px 0 10px 10px;
border-color: transparent transparent transparent white;
}
.right::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
left: 30px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
顯示結果:
由於圓點圖形是寫在container
的偽元素中,又因為 container 的位置移到右側,而相關的圓點也跟著移動,這時我們要修正它。
CSS:
.right::after {
left: -16px;
}
顯示結果:
加入訊息框的背景顏色,這裡使用 Class 名稱為content
的 div,設定背景顏色為白色,另外加上內距 padding 和圓角 border-radius 用於修飾訊息框。
CSS:
.content {
padding: 20px 30px;
background-color: white;
position: relative;
border-radius: 6px;
}
顯示結果:
做到這裡已經將桌機的版型切好了,在下一個小節,我們要加入行動裝置上的版面。原則上就是將訊息框全部放在白線的右側,就不使用類似桌機的交錯排版方法。
這裡未使用 Mobile First Design 的概念,先貼出 Media Query 的寫法。
@media screen and (max-width: 600px) {
.timeline::after {
left: 31px;
}
.container {
width: 100%;
padding-left: 70px;
padding-right: 25px;
}
.container::before {
left: 60px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
.left::after,
.right::after {
left: 15px;
}
.right {
left: 0%;
}
}
顯示結果:
到這裡,我們已將完成 RWD 的寫法,稍微解釋寫法:在 @media 中使用max-width: 600px
,指的是小於 600px 以下的裝置適用,也就是在手機裝置,排版才會改變。container
是訊息框,在這裡寬度用100%
讓它滿版,因為只有單欄,所以就這樣設定,container::before
為三角形箭頭方向向右,.left::after,.right::after
的left: 15px;
設定為 15 px,是為了要和圓點圖形保持距離。最後,將.right
的 left 設定為 0%,這樣寫就可以和.left
位置垂對齊。
加入簡單的動畫效果,讓訊息框可以由下而上顯示。
這裡還沒有將 animation 更進階用法實作出來,之後寫到 Scroll 時,再修改 timeline 的 animation ,目前先使用常見的 fade up 功能,使用@keyframes
和animation
來製作。另外translateY(50%)
指的是這個 Class 高度的一半,也就是指.container
高度的一半,結束時會移動到translateY(0)
的位置。代表.container
會往上移 Fade Up。
CSS:(@keyframes
)
@keyframes fade {
from {
opacity: 0;
transform: translateY(50%);
}
to {
opacity: 1;
transform: translateY(0);
}
}
fade 為 @keyframes 的名稱,from
裡面放的是起始位置,一開始先設定opacity
為0
,將其隱藏,直到to
結束時,讓opacity
為1
,訊息框即可顯示。另外,位置要由下往上浮出,其程式碼如下。
CSS:(animation
)
.container {
padding: 10px 40px;
position: relative;
background-color: inherit;
width: 50%;
animation: 1s linear 1s fade; /* + Add */
}
顯示結果:
在排版時,關於三角形的位置有點搞不定,花了很多時間思考,但是沒有一個頭緒,於是決定好好的研究一下 Timeline 是如何被實現的,結果實作方法比我想還簡單許多,一定是我在做版面規劃的時候,偽元素放的 div 位置不正確導致移動元素很困難。另外,position 概念需要再加強,感覺好像有遺漏什麼特性沒有釐清,會在寫一篇再探討 position。不過那篇會放在另一個系列裡就是了。
此外,還有就是 border 產生三角形的用法會是一個迷惑地帶,建議可以先釐清概念,或是將所有方向的三角形全部都先寫好,之後再直接套用,就不用每次都在想參數,節省開放的時間。