題目是一個看起來像是 Weather Widget 的介面,配上下雨的動畫,並且在初次 loading 時,月亮會有升起的動畫。
上面的圖是題目,而我們要做出幾乎一樣的樣子,題目中還有附上出題官方的CodePen,也有附上給我們解題用的template,當我們真的不會的時候,還是可以參考他們的寫法,所以沒有想像中困難。
我做好的此題CSS Challeage解答
那麼我們就開始吧。
這個題目要求我們製作一個天氣 Widget 的畫面
那這裡我一樣會拆解成幾篇來寫,避免版面太長(我會寫的太累)
首先我們先來寫基本架構,明天再來做動畫。
因為我並不想要放好幾個一樣的 div
在裡面,所以在這裡我跟題目一樣使用了 slim 版本的 HTML 預處理器來寫。
Slim 是一個輕量化的模板語言,它使用縮排來結構化 HTML,簡化了標籤的書寫,不需要閉合標籤,並減少了重複的代碼。這樣可以讓 HTML 更加簡潔易讀,常用於像 Ruby on Rails 這樣的框架中。
例如,傳統 HTML 的寫法:
<div class="container">
<h1>Hello World</h1>
</div>
在 Slim 中可以這樣寫:
.container
h1 Hello World
這種語法可以大幅減少 HTML 的冗餘,使模板更易維護。
.frame
.view
.label
.temperature 12°
.info
.left Wind: E 7 km/h <br/> Humidity: 87%
.right
span TUE
span 21° / 9°
span WED
span 23° / 10°
.view
:圖片區域.label
:下方文字資訊區域
.temperature
:溫度:文字區域內的左方,氣溫的部分。.info
:小資訊:文字區域右方區塊的小字。
left
:小資訊的左半邊:風速、濕度。right
:小資訊的右半邊:顯示不同星期的最高及最低氣溫。$primary: #3D476A;
$labelH: 90px;
$viewH: 400px - $labelH;
這邊是我先為了目前會用到的區塊設定的變數。
primary
:下方資訊區塊的文字顏色,這時候一樣拿出我們第一天的小工具來吸色。這裡我是吸12那邊稍粗一點的字體顏色。
labelH
:拿第一天教的小工具出來量下方資訊區塊的高度。viewH
:由於是滿版的,我們已經知道 .frame
本人的高度之後,就直接拿來剪掉下方天氣資訊的高,就可以得知圖片區域多高了。
.frame {
...
background: #192238;
color: $primary;
}
變數設定好之後,把 frame
的底色跟文字顏色加上去。
.view {
width: 100%;
height: $viewH;
overflow: hidden;
}
這邊是明天我們要做的上方圖片區塊的基本值,先放上去,讓它有一個高度,好方便我們先做底下的天氣資訊。
.label {
height: $labelH;
background-color: #fff;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
& > * + * {
margin-left: 15px;
}
}
首先,來設定 .label
區塊。
每個標籤內的內容會被排列成一條水平的行,並透過 display: flex
控制對齊。
align-items: center
讓所有元素在垂直方向上置中,而 justify-content: space-between
讓內容均分左右,分別對齊兩端。
padding: 0 20px
則是設定內容左右的內邊距。
另外,& > * + *
則是我很喜歡使用的小技巧,這讓 .label
內第一層的每個元素彼此之間會有 15px
的間距,用來避免內容貼在一起。
.temperature {
font-size: 45px;
font-weight: 300;
line-height: 2;
flex: none;
}
font-size: 45px
:將字體大小設為 45px
,確保溫度的數字很大,易於閱讀。font-weight: 300
:字重設置為 300,表示字體較細,不會過於粗重。line-height: 2
:行高設定為 2,讓內容之間有更多的垂直間距,增加可讀性。flex: none
:因為這邊我們需要讓右邊的區塊吃到所有剩餘的寬,這樣才能關閉 flex 子元素的彈性行為,保持該元素不會自動調整大小或位置。 .info {
font-weight: 300;
display: flex;
align-items: center;
line-height: 1.5;
font-size: 15px;
flex: 1;
這邊外面再包一層主要是設定區塊內的文字樣式,並且實現靈活的 flex
布局。
display: flex
:因為這個區塊內的文字,又再分成了左右兩塊,這邊我們就使用 flex
屬性來排列內容,確保子元素能得到靈活的布局。flex: 1
:讓這個區塊在彈性容器內占滿剩餘空間。 .info{
...
.left {flex: 1;}
}
小資訊區塊內左方的文字,這邊其實是一行字,我們單純的使用<br/>
來讓它們換行就已經足夠,加上剛剛已經設定好的 line-height
,這邊並不需要太多的操心。
加上由於已經設定好的字體的大小顏色等等,這邊只需要設定這個區塊的 flex
,確保它能夠在彈性容器內占滿剩餘的空間即可。
.info {
...
.right {
flex: 1;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
text-align: right;
column-gap: 10px;
justify-content: space-between;
span:nth-child(odd) {
text-transform: uppercase;
}
span:nth-child(even) {
font-weight: 400;
}
}
}
這邊是小資訊的右方區塊。
這邊我使用我愛用的 grid
來進行編排,讓我說明一下:
flex: 1
:讓 .right
區塊在父容器中填滿剩餘的空間。grid-template-columns: repeat(2, minmax(0, 1fr))
:將區塊分成左右兩個等寬的欄位,有超出的 column
都會依照這個規則繼續往下往右排列。text-align: right
:將文本對齊到右側。column-gap: 10px
:欄位之間的間距設定為 10px。span:nth-child(odd)
和 span:nth-child(even)
:為奇數和偶數的 <span>
元素設定不同樣式,奇數大寫,偶數設置較細字重。這邊奇數的就是星期幾的部分,而偶數則是右邊的最高/最低溫的區域。那做完之後大概就長這樣
由於之前我都一次寫太多,搞的自己很累,我決定之後儘量分小段寫,這樣比較不會太辛苦,那就先這樣,明天我們再來繼續做上方圖片的部分。
希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。
那今天就先到這裡,明天我們再繼續來玩下一集。