iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0

https://i.imgur.com/yAcbok4.jpg

組件實作 : DemoDemo2

一、前言

Timeline 時間線的功能很常出現在履歷表,或是各種跟年分有關的介紹。原本參考 W3schools How To 的 Timeline 範例圖片【1】,想說應該能簡單的切出預期的圖形,沒想到竟然卡住了,由於時間關係,當下反應是「或許整個砍掉重練還比較快?!」,於是先放棄原來的切版,直接學習 How To 的作法...

尚未完成的 timeline 切板放在 Demo2 裡面,可與 Demo 互相對應。


二、直接實作 Timeline 組件

首先,我們要加入 HTML 檔案,架構是這樣的:「最外層用一個 Class 名稱為 timeline 的 div,包住所有的元素,Class 為container left或是container right,left 代表放在時間線左邊的訊息方框,而 right 則是指放在時間線右邊的訊息。container裡面有一個content,用來放置內容,而這個內容則是由一個標題和一段文字所組成。

2.1 建立 Timeline 主架構

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>

顯示結果:

https://i.imgur.com/a3w1u4H.jpg

在複製時,left 和 right 要交錯排放。也就是說要用 left、right、left、right …這種寫法,這樣之後在排版交錯時,才不會出現問題。

2.2 CSS 起手式

在全部 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

顯示結果:

https://i.imgur.com/cdPuM9l.jpg

2.3 timeline 相關語法

首先,要讓所有的元素置中,直接控制最外層名稱為timeline的 Class,設定最大寬度為1200px,設定最大寬度用意在於版面閱讀舒適性,timeline 也是父層,為了讓內部元素對齊父層,將position設定為 relative。最後,使用一個margin: 0 auto;可以讓 timeline 整個置中畫面正中間。

CSS:

.timeline {
  position: relative;
  max-width: 1200px;
  margin: 0 auto;
}

顯示結果:

https://i.imgur.com/JWgoJ1e.jpg

接著,要製作一個白色的中心線,線寬為 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。

顯示結果:

https://i.imgur.com/Kd6KB3y.jpg

2.4 訊息框排版

這裡的訊息方框指的是可放置內容的元素,這個訊息框的 Class 名稱為container, 這裡設定 container 的 padding,可讓內容文字有上下、左右產生間距。因為要保留文字的版面位置,所以使用 position 為relative,背景色用 inherit 繼承父層,重要的是寬度,寬度設定50%,將全部的訊息框都移至白線左邊。

CSS:

.container {
	padding: 10px 40px;
	position: relative;
	background-color: inherit;
	width: 50%;
}

顯示結果:

https://i.imgur.com/mddoads.jpg

2.5 使用偽元素添加裝飾圓點圖形

圓點圖形用途是放在白線上的裝飾,它的製作方法很簡單,只要用繪製一個圓形後,將 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;
}

顯示結果:

https://i.imgur.com/F8urE0F.jpg

bfore 和 after 可以分別放在元素的前和後,但如果使用了position: absolute;,是否 bfore 和 after 之間就沒有區別了呢?這部分有請大神幫忙解答。

2.6 訊息框排版

這裡要決定訊息框是要在白線的左邊(left)或是(right), 由於我們在 timeline 已經設定 position 為 relative,left 和 right 可直接使用,left 為 0, right 為 50%。

CSS:

.left {
	left: 0;
}

.right {
	left: 50%;
}

顯示結果:

https://i.imgur.com/zEZ2iOy.jpg

2.7 三角形箭頭寫法

這裡對 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;
}

顯示結果:

https://i.imgur.com/4RF1Btv.jpg

2.8 修正問題

由於圓點圖形是寫在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;
}

顯示結果:

https://i.imgur.com/NN2j3ng.jpg

做到這裡已經將桌機的版型切好了,在下一個小節,我們要加入行動裝置上的版面。原則上就是將訊息框全部放在白線的右側,就不使用類似桌機的交錯排版方法。

2.9 加入 RWD 響應設計功能

這裡未使用 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%;
	}
}

顯示結果:

https://i.imgur.com/gw0aqBa.jpg

到這裡,我們已將完成 RWD 的寫法,稍微解釋寫法:在 @media 中使用max-width: 600px,指的是小於 600px 以下的裝置適用,也就是在手機裝置,排版才會改變。container是訊息框,在這裡寬度用100%讓它滿版,因為只有單欄,所以就這樣設定,container::before為三角形箭頭方向向右,.left::after,.right::afterleft: 15px;設定為 15 px,是為了要和圓點圖形保持距離。最後,將.right的 left 設定為 0%,這樣寫就可以和.left位置垂對齊。


三、 額外修改

3.1 訊息框的動畫效果

加入簡單的動畫效果,讓訊息框可以由下而上顯示。

這裡還沒有將 animation 更進階用法實作出來,之後寫到 Scroll 時,再修改 timeline 的 animation ,目前先使用常見的 fade up 功能,使用@keyframesanimation來製作。另外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裡面放的是起始位置,一開始先設定opacity0,將其隱藏,直到to結束時,讓opacity1,訊息框即可顯示。另外,位置要由下往上浮出,其程式碼如下。

CSS:(animation

.container {
	padding: 10px 40px;
	position: relative;
	background-color: inherit;
	width: 50%;
	animation: 1s linear 1s fade; /* + Add */
}

顯示結果:

https://i.imgur.com/Ly5Kira.gif


四、推薦資源

  1. 15+ HTML & CSS Timelines [Examples for Inspiration]
  2. 35 Clean CSS Timeline Design To Clearly Explain The Events
  3. 30 Best CSS Timelines In 2022 | Techknow Prime
  4. 30 Best Html And CSS Timelines Plugins 2022
  5. 16+ Free Html CSS Timelines Plugins 2022
  6. CSS Timelines Examples 2022
  7. 11 TIMELINE UI DESIGN EXAMPLES

五、結論

在排版時,關於三角形的位置有點搞不定,花了很多時間思考,但是沒有一個頭緒,於是決定好好的研究一下 Timeline 是如何被實現的,結果實作方法比我想還簡單許多,一定是我在做版面規劃的時候,偽元素放的 div 位置不正確導致移動元素很困難。另外,position 概念需要再加強,感覺好像有遺漏什麼特性沒有釐清,會在寫一篇再探討 position。不過那篇會放在另一個系列裡就是了。

此外,還有就是 border 產生三角形的用法會是一個迷惑地帶,建議可以先釐清概念,或是將所有方向的三角形全部都先寫好,之後再直接套用,就不用每次都在想參數,節省開放的時間。


六、參考資料

  1. How TO - Timeline
  2. Box Sizing
  3. ::before & ::after 無中生有的僞元素選取器 - 傑克這真是太神奇啦
  4. Use CSS border to make trapezoids, triangles, dialog boxes

上一篇
Day 10:Form 驗證功能實作
下一篇
Day 12:Modal 組件實作
系列文
從零開始手刻網站,30 天打造我的前端武器庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言