iT邦幫忙

2024 iThome 鐵人賽

DAY 7
1
Modern Web

Dive into CSS Challenge:從問題到解決方案的實踐之旅系列 第 7

CSS Challenge Day #5:Weekly Report 介面(下)

  • 分享至 

  • xImage
  •  

題目

CSS Challenge Day5
https://ithelp.ithome.com.tw/upload/images/20240919/20169403yCIPW72Hfq.png

上面的圖是題目,而我們要做出幾乎一樣的樣子
我做好的此題CSS Challeage解答

前情提要

上一集由於篇幅太長,拆分兩集來寫,今天我們就來做他中間最重要的 .statistic 跟底下 .days 兩個區塊。

先讓大家回憶一下昨天Body部分的架構長這樣:

<div class="body">
	<div class="params"></div>
    <div class="statistic"></div>
    <div class="days"></div>
</div>

我們最後做好 params 的時候長這樣:
https://ithelp.ithome.com.tw/upload/images/20240919/20169403PzRtVPtJBl.png

那我們就繼續後面 .statistic.days 的部分。

開始解題

卡片區塊

Body部分

2. days 的部分

因為等等 .statistic 的部分還要去做滑鼠的互動,會花比較多時間,所以我們先把比較簡單的 .days 做起來。

<ul class="days">
	<li class="day">Mon</li>
	<li class="day">Tue</li>
	<li class="day">Wed</li>
	<li class="day">Thu</li>
	<li class="day">Fri</li>
	<li class="day">Sat</li>
	<li class="day">Sun</li>
</ul>

這邊我考慮了他裡面的每個東西都是一樣的樣式,所以我把 .days 從原本的 div 結構,改成了 ul li 的架構。並在裡面把文字都貼上去。

也是因為考慮到這裡的距離非常靠近卡片邊緣,所以我們上一集在做 .params 的時候,我沒有把 .params 距離卡片邊緣的 padding 做在 .body 身上,而是選擇做在 .params 身上,為的就是不要對 .days 造成影響。

.days {
	display: grid;
	grid-template-columns: repeat(7, minmax(0, 1fr));
			
	.day {
		text-transform: uppercase;
		text-align: center;
		font-size: 10px;
		color: #999;
		line-height: 3;
	}
}

這裡我依然使用我愛用的 grid 來完成,因為這邊的欄位數量是固定的,我們可以直接把欄位設定成7個欄位,可以用 grid-template-columns: repeat(7, minmax(0, 1fr)) 來達到這個效果,接著只要設定每個欄位內,文字的樣式即可。

h1, p, span, ul, li {
	padding: 0;
	margin: 0;
}
ul {
	list-style: none;
}

這邊另一個重點是 ul li 本身也都有自己原先的 padding margin 之類的屬性,一樣要記得去做 CSS Reset。

剛做好的時候長這樣
https://ithelp.ithome.com.tw/upload/images/20240919/20169403IMMUADS4li.png

3. Statistic 的部分

看題目可以看的出來,上下各有一條細細的灰色線,正中間也有一條,所以這邊很明顯應該是要使用 absolute 的方式來把中間那條線完成。

<div class="statistic">
    <div class="line"></div>
</div>

基本架構長這樣,我預計在 .statistic 內設定好高度,並在上下使用 border 來完成上下灰線的部分,然後再把 .line 使用 absolute 的方式放到 .statistic 的正中間。

.statistic {
	position: relative;
	width: 260px;
	height: 80px;
	margin: 0 auto;
	border: 1px solid #efefef;
	border-left: none;
	border-right: none;
			
	.line {
		background-color: #efefef;
		width: 100%;
		height: 1px;
		position: absolute;
		z-index: 0;
		top: 50%;
		left: 0;
	}
}

所以這邊先設定好 .statistic 的高度跟寬度,也加上了 relative 讓他成為一個畫布。
設定好 border 之後再把左右的 border 改成 none ,這樣基本畫布就完成了。
剛做好的時候長這樣:
https://ithelp.ithome.com.tw/upload/images/20240919/20169403CwFIY89E0g.png

接著就是放 data 的時候了。
datasvg 我是直接從題目裡偷來的啦,重點是我們知道怎麼操作他就好。
當然你要自己寫也可以,其實語法很簡單 <polyline points="9,46"> 這邊 points 內的就是點點的座標 (x,y) 要幾個節點就做幾個,中間用空白分隔,這樣你就有轉折線條了。
顏色的部分跟上一集 .params 的偽類一樣,我們都是在 .red 這邊才賦予他顏色。

<div class="statistic">
	<div class="line"></div>
	<div class="data red">
		<svg>
			<polyline points="9,46 50,12 90,23 130,11 171,38 211,48 251,19"></polyline>   
		</svg>
		<div class="points">
			<div class="point-1"></div>
			<div class="point-2"></div>
			<div class="point-3"></div>
			<div class="point-4"></div>
			<div class="point-5"></div>
			<div class="point-6"></div>
			<div class="point-7"></div>
		</div>
	</div>
</div>

基本架構是這樣,我讓 .statistic 裡面包一個 .data ,他裡面先放一個 svg,這個 svg 本身是只有線條,並沒有我們題目上看到的圓點。
所以我們要再在下面放一個 div 叫做 .points,在他裡面放所有的圓點點。

svg {
	position: absolute;
	zindex: 2;
	left: 0;
	top: 0;
	right: 0;
	bottom: 0;
}
polyline {
	fill: none;
	stroke-width: 2;
}

先來處理 svg,剛剛已經說了這是一個畫布,我們需要將他做定位,因此這裡一樣使用 absolute 來定位他,並且讓他上下左右都設定 0,這樣就可以對齊的剛剛好了。
這裡記得要比我們剛剛放在中間那條叫 .line 的線高一層,所以我有設定 zindex: 2,把圖表放在線條的上面。

polyline 內的屬性的話,fill 是只有沒有底色,這邊我們不要底色,所以必須把他拿掉,如果放了底色會長下圖這樣,那就不是我們要的了。stroke-width 則是線條的粗細。
https://ithelp.ithome.com.tw/upload/images/20240919/201694033do6toKgh6.png

接著來設定資料

.data {
    [class^="point-"] {
		position: absolute;
		width: 6px;
		height: 6px;
		border-radius: 50%;
		z-index:4;
		cursor: pointer;
	}
}

[class^="point-"] 這個選擇器是選這個範圍內所有名字前面是 point- 的元件,這是圖表中每個節點上面的圓點點。由於之後會設定他們每一顆的位置,所以在這邊統一給他們 absolute 及其他的視覺樣式,也先給他滑鼠游標的設定,因為之後滑鼠指上的時候要有 tooltip 出現。

接著來設定資料,這邊我用紅色的來示範,但做完之後都記得要把藍色的也跟著做一次唷~

.data {
    &.red {
        polyline {stroke: $red}
        [class^="point-"] {background-color: $red;}
        .tooltip, .tooltip:after {background-color: $red;}
        .point-1 {left: 7px; top: 42px}
        .point-2 {left: 47px; top: 9px}
        .point-3 {left: 87px; top: 20px}
        .point-4 {left: 127px; top: 9px}
        .point-5 {left: 167px; top: 35px}
        .point-6 {left: 207px; top: 45px}
        .point-7 {left: 247px; top: 17px}
    }
}

首先把 .red polyline 內的線條顏色設定成我們變數的紅色。
再來 [class^="point-"] 把他們的底色設定為我們剛剛變數的紅色。
接著就是一個個去對 .point-1 ~ .point-7 在畫面上的位置,我是用右鍵檢查去一個個對,然後再去CSS裡面修改他們每一個的位置,花了不少時間...

之後就可以來作他們滑鼠指上的 tooltip 了。

<div class="data red">
	<svg>
         ...
	</svg>
	<div class="points">
		<div class="point-1">
			<div class="tooltip">458</div>
		</div>
		<div class="point-2">
			<div class="tooltip">812</div>
		</div>
		<div class="point-3">
			<div class="tooltip">746</div>
		</div>
		<div class="point-4">
			<div class="tooltip">877</div>
		</div>
		<div class="point-5">
			<div class="tooltip">517</div>
		</div>
		<div class="point-6">
			<div class="tooltip">434</div>
		</div>
		<div class="point-7">
			<div class="tooltip">458</div>
		</div>
	</div>
</div>

這邊就是把他們的數字,依照題目上的那樣將數字鍵入。
然後去調整 tooltip 的位置跟樣式。

.tooltip {
	font-size: 11px;
	border-radius: 3px;
	padding: 5px 3px;
	position: absolute;
	bottom: 15px;
	left: 50%;
	transform: translate(-50%, 5px);
}

這邊的 .tooltip 是從 .point-1 ~ .point-7 長出來的,所以他們對齊位置的起始點是 .point-1 ~ .point-7,因此我們在這邊的對齊就可以用通用一致的方式來製作,使用 transform: translate(-50%, 5px)left: 50% 讓他們可以置中對齊。
https://ithelp.ithome.com.tw/upload/images/20240919/20169403TxPr5rgbDB.png

看起來已經很完美了,但我們還缺底下的一個小箭頭。

.tooltip {
    ...
	&:after {
		content: '';
		position: absolute;
		display: block;
		width: 6px;
		height: 6px;
		left: 50%;
		bottom: -3px;
		margin-left: -3px;
		transform: rotate(45deg);
	}
}

這種小箭頭在很多地方都用運用到,常見的作法是使用 :after 偽類來做一個小方塊,再把小方塊旋轉45度讓他變成菱形,並調整位置只露出下半截的三角形,來達成看起來是小箭頭的樣子。
這樣就差不多了,我們只剩下讓他平常的時候隱藏,滑鼠指上的時候再呈現的互動效果。
https://ithelp.ithome.com.tw/upload/images/20240919/2016940362G0ZCxjXt.png

互動效果

.tooltip {
	opacity: 0;
	transition: all ease-in-out .4s;
}

為了要有互動效果,我們先到 .tooltip 這邊,在他本人身上加上 transition: all ease-in-out .4s ,讓他裡面所有屬性都能夠吃到漸變,也不要忘記加上 opacity: 0; 讓他先隱藏起來。

[class^="point-"] {
	...
	&:hover .tooltip {
		opacity: 1;			
	}
}

接著去 point- 的選擇器中,設定滑鼠指上的時候,他裡面的 .tooltip 透明度要呈現 100% 能被看到。
如此一來就全部都完成囉~


Wrap up and go home

希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。

那今天就先到這裡,明天我們再繼續來玩下一題。


上一篇
CSS Challenge Day #5:Weekly Report 介面(上)
下一篇
CSS Challenge Day #6:Profile卡片介面(上)
系列文
Dive into CSS Challenge:從問題到解決方案的實踐之旅14
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言