上面的圖是題目,而我們要做出幾乎一樣的樣子
我做好的此題CSS Challeage解答
上一集由於篇幅太長,拆分兩集來寫,今天我們就來做他中間最重要的 .statistic
跟底下 .days
兩個區塊。
先讓大家回憶一下昨天Body部分的架構長這樣:
<div class="body">
<div class="params"></div>
<div class="statistic"></div>
<div class="days"></div>
</div>
我們最後做好 params 的時候長這樣:
那我們就繼續後面 .statistic
跟 .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。
剛做好的時候長這樣
看題目可以看的出來,上下各有一條細細的灰色線,正中間也有一條,所以這邊很明顯應該是要使用 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
,這樣基本畫布就完成了。
剛做好的時候長這樣:
接著就是放 data
的時候了。data
的 svg
我是直接從題目裡偷來的啦,重點是我們知道怎麼操作他就好。
當然你要自己寫也可以,其實語法很簡單 <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
則是線條的粗細。
接著來設定資料
.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%
讓他們可以置中對齊。
看起來已經很完美了,但我們還缺底下的一個小箭頭。
.tooltip {
...
&:after {
content: '';
position: absolute;
display: block;
width: 6px;
height: 6px;
left: 50%;
bottom: -3px;
margin-left: -3px;
transform: rotate(45deg);
}
}
這種小箭頭在很多地方都用運用到,常見的作法是使用 :after
偽類來做一個小方塊,再把小方塊旋轉45度讓他變成菱形,並調整位置只露出下半截的三角形,來達成看起來是小箭頭的樣子。
這樣就差不多了,我們只剩下讓他平常的時候隱藏,滑鼠指上的時候再呈現的互動效果。
.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% 能被看到。
如此一來就全部都完成囉~
希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。
那今天就先到這裡,明天我們再繼續來玩下一題。