Open Rplus opened 7 years ago
Sync to Codepen post: http://codepen.io/Rplus/post/introduction-for-pok-dex-in-css-grid
montage -tile 12x -background none -geometry 100x100+0+0 $(ls -1 *.png | sort -n) sprite.png
輸出 12 欄的 image sprite 每格 100px,間距 0
更正第五點 5. CSS counter
可以略過 DOM 結構
但需要將 counter-reset
往上層拉
看這篇時,發現他也有遇到同樣的問題~ ref: Using CSS to detect and counting Prime Numbers https://github.com/xieranmaya/blog/issues/12
0. 前言
這是上週六(12/25) 網友線下聚會(?) 時,我所負責撰寫的 UI 部份 這次玩得挺開心的, 不論是大家拼命調整開發環境、或是對細節精雕細磨都超有趣的 XD 不過更棒的是, 最後大家在分享時都非常熱心地介紹自己使用的技巧,也都樂於提出建議~ 希望下次還可以繼續一起約出來玩~
至於我負責的畫面可以先看看實作完的 demo: Pokédex in CSS grid http://codepen.io/Rplus/pen/MbddMe?editors=1100 [[[pen slug-hash='MbddMe' height='300' embed-version='2']]]
ps: 這篇效果應用了些許新的 CSS 規格,不保證所有瀏覽器皆正常顯示 建議直接使用 Canary Chrome 瀏覽 或如果你的 Chrome 看不到 grid 的話,可以依 Google 開發者的這篇文章 去開啟 flags
1.
Grid
system說實話, 要完成這樣的格狀排版並不是太困難的任務 不管是
float
,inline-block
,flexbox
或是直接table
都可以達成! 而這次我想再繼續練習grid
的排版方式,所以就選用 grid 囉~grid 相關設定大多都直接寫在
.wall
裡,SCSS 原始碼 也就兩三行在定義而已,看起來挺簡單的不是嗎~ 是的,grid 設定起來就是非常輕巧,初學者並不需要太害怕它 XD 只是要稍微多去認識、並找機會實作嘗試 (我也是在嘗試而已~)
grid-template-columns: repeat(auto-fill, minmax(15vmin, 1fr))
其中這段的定義就是讓 grid 的欄寬自動填滿,寬度最小 15vmin,最大 1fr (fr 是指自動的欄寬) 所以實際跑出來就會變成每欄等寬,最小 15vmin。因為
100 / 15 = 6.66…
,所以一個版面較短的那側大概都會塞到 6 格 (塞太多格會太小) 而又因使用 vmin 的緣故,所以打螢幕打橫還是可以維持差不多的格數 大家有興趣可以自己用 devtool 隨便拖拉改變螢幕尺寸試玩看看這邊也有加一個唯一的
@media
query 來控制更窄畫面的情況 畫面太小時,就改用較硬性的單位em
來控制可讀性了而
@supports not (display: grid)
這區塊則是目前 grid 較常見的 fallback 使用方式 這處就定義若不支援就改用其它種排版方式處理2. Pokemon 的圖片
這張合併圖是用 Pokemon-GO-App-Assets-and-Images 裡的素材, 再用 ImageMagick 接起來的 (花好多時間在弄素材 = =)
原本圖片是可以直接設定在
.pm
的背景圖上 不過這樣弄剪影效果會影響到不必要的其它元素 所以獨立到 pseudo-element 上來設定背景圖 => 原始碼圖片就是應用很常見的 CSS image sprite,藉由載入一張大圖來減少 request 數量 這裡有另外的優化是讓它透過 image CDN 來緩存 ( 不然圖床 imgur 有時會 ban codepen 的 request… )
而因為 grid size 會變來變去的關係 所以這邊的 image sprite 的
background-position
也要調整為百分比形式才能好好地完成 RWD 的定位 而百分比定位跟原本的計算方式有些不同,不熟的可以參考這篇文章: How to Use Responsive Background Image Sprites – CSS Tutorial 簡單地說,就是100% * $index / #{$grid-count - 1}
,格數減一就對了~至於背景圖位置
background-position: var(--bgp)
則是用了 CSS variables, 這是因為背景圖是設定在 pseudo-element 上, 而 HTML inline style 沒法塞到 pseudo-element 身上 所以這邊應用了 CSS variables 的 scope 特性,讓該變數僅在該 grid 生效 便可達成正確的 sprite 定位 :pps: 其實 image sprite 不是太難,就是手刻起來會有點繁瑣,不知不覺就變這麼多字…
3. Pokemon 的剪影
=> 原始碼
剪影效果的 code 其實超短 不過 filter 的想像力沒那麼熟時,還是得慢慢去試效果
contrast
調到 0 基本上就是把顏色都打掉變成灰灰的,opacity
是為了調淡一些、並帶上一些背景色調 而一直記不起每個屬性效果的mix-blend-mode
則是在 devtool 裡上上下下切換直接看效果比較快 XDD剪影這一段的效果其實一開始也沒把握實作出來 不過胡搞瞎搞後的成果還挺趣味的~ 哈哈
4. Pokemon 狀態
其實就三種 已捕獲(caugth)、見過(seen)、未知(unknown) 這三種的數量其實是有一個大約比例的 大約是 7:2:1
這邊的處理方式是使用 HTML preprocessor: pug 寫個 mixin 來處理 其實就是 JS function 而已 只是 Codepen 現在把 jade 換成了 pug2,所以有支援比較新的 es6 syntax~
=> 原始碼
基本上就是先做一個陣列,內容是以比例分配好狀態出現的次數 再隨機挑一個 0 ~ 99 的餘數 所以可能會有些不準,不過大致的隨機效果可以做到了~ 這邊隨機數好像應該用
~~(Math.random() * states.length)
會比較正確一些 XDD而 CSS 部份就只是使用一些
:not()
選擇器去控制哪些東西不要出現5. CSS counter
其實頂端的計數我一開始是用
data-attr
寫死在 .subtitle 上的 後來實作完隨機狀態後,才回來想這塊要怎麼修正 XD這部份的作法若用 client 端的 script (javascript) 來處理的話 應該也是一塊小蛋糕而已 不過前面寫這麼多都沒用到 JS,實在不太想在這邊破功吶 XDD
所以我改用 CSS counter 來自動計數~ 在 code 裡可以看到這部份的設定:
=> 原始碼
=> 原始碼
將
counter-increment
設定在各個需要計數的位置 最後再讓 pseudo-element 吃下這個 counter 就能顯示正確的計數囉~可以發現這邊用的是多重 counter 有的甚至同時觸發 3 個,這在計算不同狀態時非常好用
只是這邊有個比較需要留意的部份是 counter 要印出來會看 DOM 的順序 所以本來
.header
是寫在.wall
之前的 為了這效果,才把 header 搬進 wall 裡頭 這部份也剛好 header 的定位是 fixed on top,所以 DOM 擺哪對排版比較不會有副作用 所以有些時候技術的選用也要看天時地利配不配合而因為 counter 就是這麼吃 DOM 結構 所以原本寫在
.pm
上的 pokemon 狀態硬是拉升到.tile
上去設定 使用上有較多限制,需要特別留心~主要的效果基本上就介紹到這邊 相信用到的其實都不是很難的屬性 只是需要平時多接觸、多查找、多練習就能慢慢累積一些能牢記的知識 在需要用上時,就能笑笑地回:
『江湖一點訣』