半熟前端

軟體工程師 / 台灣人 / 在前端的路上一邊探索其他領域的可能性

分類:前端

前端

深入理解 Svelte(2)— 分析 Svelte 生成程式碼

前言 從 Svelte 的核心理念 可以得知,Svelte 希望從編譯過程中盡可能地獲取必要資訊,減少在動態的 overhead。上一篇文章中說明了 Svelte 從編譯到生成程式碼是如何運作的,今天要來觀察一下 Svelte 生成的程式碼是怎麼運作的。 先觀察一個簡單的 Svelte 元件: Svelte 元件語法跟一般 HTML 相同,除了會加上類似樣板語法之外(if, await)基本上可以完全相容 HTML,但是生成的元件又是 JavaScript…

(繼續閱讀...)#svelte
前端

2021 年值得學習 Svelte 的四個理由

1. 關注度持續上升 根據 State of JS 的調查,Svelte 在 2019 年納入問卷選項,當時的滿意度就有 88%(React 89%, Vue 87%),今年變成 89% 變成滿意度第一名的前端框架。 另外原本使用率在 2019 年為 8% 排名為第六,在 2020 年變為 15% 晉升為第四名。代表越來越多人在關注這個前端框架了。 2. 入門門檻低,容易上手 Svelte 的語法幾乎與 HTML 完全相容,另外像是 {#if} {#each…

(繼續閱讀...)#svelte
前端

深入理解 Svelte(1)— Svelte 編譯過程

深入理解 Svelte(1)— Svelte 編譯過程 在閱讀本篇文章之前,預期讀者已有 Svelte 或其他前端框架使用經驗,並且對實作原理有興趣。 如果還沒有看過「 Svelte 如何編譯(0)— 什麼是抽象語法樹? 」,建議先閱讀後再來閱讀本篇 今天這篇文章想要回答幾個問題: 為什麼 Svelte 可以將程式碼編譯為 JavaScript 為什麼在 Svelte 中可以使用類似模板引擎的語法({#if} {#await…

(繼續閱讀...)#svelte
前端

深入理解 Svelte(0)— 什麼是抽象語法樹?

前言 這一系列的文章以探討 Svelte 原理實作為主,希望能讓讀者對於 Svelte 的編譯機制與程式碼生成有更深入的理解。由於 Svelte 編譯過程涉及程式碼解析,因此這一篇文章主要會先討論抽象語法樹是什麼,並進一步說明抽象語法樹扮演的角色與重要性。 什麼是抽象語法樹(AST)? 我們先以維基百科的說明作為開頭: 在電腦科學中,抽象語法樹(abstract syntax tree 或者縮寫為 AST),或者語法樹(syntax tree…

(繼續閱讀...)#svelte
前端

Hotwire 與 Turbolinks

前言 DHH (Ruby on Rails 的作者)發了一則推特,在講他的新作 Hotwire 。DHH 是個 SPA 黑粉(從推文上可以略知一二),因此他極力避免在開發上加入太多 JavaScript。這則推文在推特上引起熱烈討論,在這邊稍微做個整理。 關於 Hotwire 的介紹在這邊直接引用官方上面的說明: Hotwire is an alternative approach to building modern web applications without using much…

(繼續閱讀...)#前端
前端

linaria - 不需要 runtime 的 CSS-in-JS 解決方案

前言 現在 css-in-JS 應該是常見的開發解決方案,就前端開發而言,這種開發手法逐漸變成主流有幾個原因: 比起 BEM OOCSS 等命名手法,css-in-JS 大多由開發工具上下手,根本性地解決 CSS 命名衝突的問題 以往工程師在撰寫樣式時,會希望 css 裡頭有程式化、模組化的功能。(例如迴圈、巢狀 CSS、函數等),所以大多使用 SASS 做開發。 在講求互動與體驗的前端開發,會希望 JavaScript 與 CSS…

(繼續閱讀...)#linaria
前端

資料視覺化 — 台灣性侵害統計簿

這次想實作這個主題是因為看到新聞加上資料也相對齊全的關係,想說剛好也可以推廣 Svelte 本身,就一邊構想一邊把他實作出來了。成品在 這裡 資料視覺化一直是我想好好研究的領域之一,不只是單純做出炫砲的圖表而已,我希望可以從中鍛鍊好說故事的技巧,而資料視覺化剛好是個很好拿來當作練功的材料之一。 之前也有陸陸續續做一些專案,只是感覺都有點太趕,沒有好好去雕細節。想說從這次之後要好好把常用的元件整理起來。 2017 年寫的 勞工大代誌 2017 年寫的 Year In Review 202…

(繼續閱讀...)#資料視覺化
前端

對於 SSR 的思考與使用場景

幫助 SEO 與搜尋引擎爬取頁面 生成 Open Graph 內容 / 管理 <head> 優化使用者體驗 與傳統模板引擎的不同之處 前端框架是如何作到 SSR 的? 常見誤區:動態載入(dynamic import)與 ajax 有沒有 SSR,真的差很多嗎? 其他方案與思考 早期在前端尚未發展成熟,且互動上也沒有那麼要求時,通常頁面的渲染會以後端程式語言提供的樣板引擎(著名的像是 ejs pug erb thymeleaf 等),先在伺服器端渲染 HTML…

(繼續閱讀...)#SSR
前端

Vue ref 語法糖與 Svelte

前言 在 10/28 時尤雨溪提出了一個 RFC ,是關於 ref 宣告的語法中,可以用 JavaScript 的 label statement 來進一步做簡化。 這個語法跟 Svelte 如出一徹,在這邊紀錄一下自己的想法。 先來看看範例當中的程式碼: 在 Vue 3 當中透過 Composition API ,可以透過 ref 將變數變成具有 reactive 的效果。宣告方式像這樣:(程式碼為文件範例) 經過 ref 宣告之後會有 reactive…

(繼續閱讀...)#svelte
前端

Svelte Summit 2020 筆記與心得

前言 The Zen of Svelte Prototyping with Svelte How does Svelte's crossfade function work Svelte Animation Unlocking The Power of Svelte action Demystifying Svelte Transitions Futuristic Web Development 後記 前言 Svelte…

(繼續閱讀...)#svelte
前端

iOS mousedown 事件觸發問題

iOS 在某些版本下 mousedown 處理器不會正確運作,不過在其他裝置上(像 Android 等等), mousedown 仍然是可以正確運作的。 解決方法是在手機上不要用 mousedown 處理器,用 touchStart 來處理,但不知道觸發順序是否會受到影響?原本在 click 事件當中,是 blur 會先觸發(如果有)再觸發 click 事件,為了躲掉這個點才用 mousedown 取代。 在 codepen 上進行簡單的實驗: 可以發現觸發順序會是 touchstart…

(繼續閱讀...)#前端
前端

將數字加上 comma 的正規表達式說明

前言 Positive lookahead 與 Negative Lookahead \b 與 \B 的意思 \b \B 如何正確解析正規表達式 開始解析表達式 方法 1:利用 zero-length 的特性匹配 方法 2:匹配應該加入 comma 的數字 其他考量與方式 效能與其他想法 其他方式 後記 相關資源 在一般顯示貨幣的時候通常會有一個需求,就是將原數字轉成人類比較好看懂的格式,例如: 1234567 → 1,234,567 10000 → 10,00…

(繼續閱讀...)#正規表達式
前端

關於 Cookie 與 CORS 的再思考

前言 2019 年我在 Medium 上發布過一篇關於 Cookie 與 CORS 的文章( 和 Cookie 與 CORS 打交道 ),受到不錯迴響,文章甚至還被抄到對岸。希望大家記得原作者在這裡就好。當時的文章在探討 CORS 是什麼,以及在前端、後端上要如何正確實作 CORS,是網頁開發中時常碰到的問題。 又過了一年多,Chrome 發布了 Cookie 政策改變(將 SameSite 預設改為 lax) ,我開始重新思考這件事,並且寫下了感想在 Chrome Cookie…

(繼續閱讀...)#cookie
前端

React 17 更新重點 - useEffect 的 clean up 函數時機改變

(本截圖取自 React 官方部落格) React 17 已經到了 RC 階段了, 官方的部落格聲明 這次的發布沒有重大更新或是任何新功能,不過在文章中還是可以找到一些有趣的東西,在這邊一併介紹給大家。 本篇文章不會一一解說每個更新,而是紀錄文章中比較值得關注的地方。 event delegation 的節點改變 在 React 當中,如果使用事件監聽器 <button onClick={}> 的話,React 會將全部的事件監聽器都放在 document…

(繼續閱讀...)
前端

前端應該學習 CS 嗎?

這個議題吵好久了,在這裡簡單紀錄一下自己的想法。 在很久以前只有 HTML 與 CSS 的年代,頂多再加上 jQuery,只要架出靜態網頁丟到 FTP 就可以被稱作是高手。 隨著瀏覽器可以做到的事情越來越多,前端能夠涵蓋的範圍也越來越廣了,光是前端這個名詞,可能就可以有多個分支: UI:對於使用者體驗的重視,其中包含了 API 狀態處理、資料處理、使用者體驗、a11y、適當的 animation 互動。 多媒體:對聲音、影像、直播比例偏重的服務,除了要對 UI…

(繼續閱讀...)
前端

科技始終來自於人性(Svelte Society: Frequently Asked Questions 筆記)

我在研究新的函式庫時,同時也會研究這個人(當然不是全部,不然一個 npm install 大概就要花一輩子去看了)。因為技術的創造者是人、函式庫的創造者是人、框架的創造者是人,大家都是有血有肉、有感情的人。 技術始終是用來服務人類的,所以理解作者背後的動機甚至是故事,對於了解框架本身也有幫助。 這位 Svelte 作者 Rich Harris,原本是 rollup 的作者,還有之前一個比較沒有名氣 Ractive.js,都是由他撰寫的。從他的 Repo…

(繼續閱讀...)
前端

從無到有寫一個 JSON 解析器(2)

在 part1 當中我們提到了如何撰寫一個 JSON 解析器,並實作解析字串的功能,接下來我們把其他函數補上。(事實上只要知道基本原理,剩下的函數實作都是照本宣科而已) Number number 實作上也不難,容易忽略的地方在於小數點、負數、浮點數的部分,還有指數表達(1e6)。(話說剛剛才發現 E 也可以) 第一個部分,我們先看看它是不是負數 第二部分,跑 while…

(繼續閱讀...)
前端

從無到有寫一個 JSON 解析器(1)

遞迴下降可以說是直覺且強大的解析方法。 今天會從解析 JSON 開始,講解如何從頭建立一個 JSON 解析器。由於 JSON 的架構簡單,很適合當作練習。雖然解析語法這件事情的確和前端或是平時的開發沒有什麼太大的關聯,不過如果有天要設計一個 DSL,或是有特殊需求可能要建立一個客製化的語言時,這些技巧就可以派上用場。 為什麼要學遞迴下降? 有了 JSON.parse 為什麼還要學遞迴下降?透過簡單的分析語法,除了正常解析 JSON…

(繼續閱讀...)
前端

如何用一行 CSS 做到 smooth scroll

正當我開開心心用 svelte 實作了 smooth-scroll 之後,我發現其實可以用一行 CSS 達到: 除了瀏覽器支援可能要擔心一下,完全省掉開發者引入 library 或是自己實作的麻煩。 完美達成 smooth-scroll ,不需要再透過改寫 hashchange 跟 state change 的行為。改天再寫一篇文章談談要怎麼不用 CSS 做到 smooth-scroll 好了。

(繼續閱讀...)
前端

Svelte 筆記(2):編譯器比你聰明多惹

今天跑去看 Svelte 原始碼,摸熟架構的同時順便看看有沒有什麼簡單的 issue 可以拿來練手。然後看到了 這個 — emits warning 。 雖然我覺得以這個 issue 的描述來看,沒有 href 的 a tag 應該是不合法的才對(至少不符合 a11y),後來我去查了一下,在 StackOverflow 上有提到目前的規範有些不統一的地方。 但基本上 href 可以是空的,只是在這種情況下就不要用 a 而是考慮用 button 之類的標籤取代,這樣對 screen…

(繼續閱讀...)#svelte
前端

Svelte 搭配 apollo-boost 時遇到的 rollup 錯誤

原本想用 svelte 搭配 graphQL 玩玩看是什麼感覺的,apollo 本身提供的 Observable Query 非常容易搭配 Reactive 的場景。 我在 svelte 裡頭引入 ApolloClient 沒想到都裝好了發現 rollup 編譯沒辦法過: 查了一下 issue ,發現其他地方也有類似問題。目前懶得繼續找解法,因為有其他想法想先完成,所以只好回到舒適圈繼續用 React 了。先筆記一下之後再慢慢瞧。

(繼續閱讀...)#svelte
前端

Svelte 筆記(1)- 沒有銀彈

在前面的章節有提到,Svelte 讓我愛不釋手。Svelte 的核心概念在於「透過靜態分析+編譯減少 runtime 做的事」,來減少 Virtual DOM 做 diff 的時間和一大包的 runtime。 但是 Svelte 走的路也註定會遇到一些問題,最主要的就是 Svelte 沒辦法在 runtime 當中幫你做太多事情。 像是這個 issue (Render slot fallback content when there's no content) ,svelte 在 slot…

(繼續閱讀...)#svelte
前端

Svelte — 是什麼讓我遇見這樣的你

前言 第一次看到 Svelte 時,心中想著「恩...又是一個新的前端框架了嗎?」,抱持著這樣的心情沒有在意太多。直到後來看到越來越多部落格文章介紹以及很多網站都在用之後,開始引起了我的好奇心。 看了官方網站的教學跟文件,才發現這跟一般的「前端框架」做法不太一樣,是從語法層面下手,搭配 compiler 來寫出簡潔又高效的程式碼。 這句話吸引了我: Svelte compiles your code to tiny, framework-less vanilla JS — your app…

(繼續閱讀...)#svelte
前端

Chrome Cookie 政策調整與反思

隨著使用者對隱私權的重視,各個服務也都逐漸開始調整自家的隱私權與安全,像是 Mac 改版到 Catalina 之後會很煩人地問你是否要同意 xxx 存取某某資源。 雖然安全性上的確是變得更嚴謹了,不過也因為如此有時候會出現一些慘案。像是 WACOM 手繪版 沒辦法順利使用之類的。 而 Google 也在 2019 的 Google I/O 大會上宣佈了 安全政策調整 ,其中對目前網頁開發影響最大的應該就是 Chrome 官方會逐漸移除第三方 Cookie 的支援。 其中從 Chrome 8…

(繼續閱讀...)
前端

深入前端開發

鐵人賽連結 - 深入前端開發 深入前端開發 - Gitbook 之前就希望能夠把一些關於前端開發的東西紀錄下來,不過一直沒有著手去做,趁著鐵人賽期間一口氣全部整理完。 這個系列分成了幾大部分,未來有機會會再繼續寫下去。 JavaScript 基礎 淺談 JavaScript 與 ECMAScript JavaScript 常見操作簡介 == 與 ===、浮點數運算 再談 Event Loop 重新思考 jQuery JavaScript 與記憶體回收 立即執行函數(IIFE…

(繼續閱讀...)
前端

migrate react-transition-group

react-transition-group 從 v1 升級到 v4 比較重要的有幾點: 升級後 CSSTransitionGroup 元件被移除了 leave 變成 exit transitionName 變成 classNames transitionEnterTimeout 之類的變成 timeout 物件 transition{Appear, Enter, Leave} 變成 appear, enter, exit…

(繼續閱讀...)#react
前端

從 class component 到 hooks

這篇文章並不會一一介紹各個 react-hooks 的 API,而是試著從設計的角度出發,來探討設計背後的原因。主要會分成幾個段落: Function Component 與 Class Component 的差異 如何在元件中複用類似的邏輯 淺談 high-order component、render props、mixin Function Component 與 Class Component React Function Component 與 React class component…

(繼續閱讀...)#react
前端

透過 overflow-anchor 實作 pin to bottom 元件

前言 這篇文章是看完 Implementing a pin-to-bottom scrolling element with only CSS 後,並且介紹使用 JavaScript 的做法整理而成。 現在網頁越上越常出現每次加入新的內容時,就將 scroll 的位置調整到最底下。像是 Twitch 的留言區: 或是 Youtube 的留言區: 在中文上好像還沒有類似的名詞來敘述這樣的行為,先叫做 pin to bottom 好了。 JavaScript…

(繼續閱讀...)
前端

更安全的請求標頭 - Fetch Metadata Request Headers

有一天在開發頁面的時候,為了要檢查請求 Header 的欄位是否正確,打開開發工具一看,發現了請求多出了幾個可疑的 header: 有注意到可疑的地方嗎?仔細一看發現,怎麼有三個以 Sec-Fetch-* 開頭的標頭。 這引起了我的注意,我並沒有設定這些標頭,也沒有套用其他函式,為什麼會自己幫我加上這些標頭,猜測應該是瀏覽器在作祟。 查了一下 google 發現,原來這是一個新的草案,叫做 Fetch Metadata Request Headers 。目前只有 chrome…

(繼續閱讀...)
前端

requestIdleCallback - 善用空閑時間

許多網頁當中都有各式各樣的 script 需要執行,當然也會有優先程度,像是比較重要的:渲染 UI,註冊相關的互動事件,呼叫 API 拿取資料等等是高優先的任務,而像是比較不重要的任務有:Analytic 的腳本、lazy loading、初始化比較不重要的事件。 怎樣才算 Idle? 怎樣才能知道瀏覽器處於 Idle 的狀態?這是一個相當複雜的問題,瀏覽器幫我們排程了一連串的任務,解析 HTML, CSS, Javascript、渲染 UI、API calls、抓取圖片並且解析、GPU…

(繼續閱讀...)
前端

新的取消請求方式 - AbortController

在前端當中,我們主要可以透過兩種方式來發送請求: XHR 跟 Fetch 。XHR 是從,嗯...,很久以前就有的 API。不過因為設定上很麻煩,所以時常被包裝成更高階的 API 使用,像是 jQuery 的 getJSON 、 axios 、RxJS 的 AjaxObservable 等等。 而近幾年隨著 Promise 逐漸流行的 Fetch API 可以大幅改進這些問題。除了回傳值為 Promise,方便操作之外,API…

(繼續閱讀...)
前端

和 CORS 與 cookie 打交道

前言 CORS 與 cookie 在前端是個蠻重要的問題,不過大多數在開發的時候,因為前後端的 domain 時常是相同的,所以很少去 care 這些問題。或者只要要求後端將 Access-Control-Allow-Origin: * 開好開滿就對了,很少去理解背後運作的機制。 針對這個問題, MDN 上其實有個非常詳盡的解說,所以這篇文章主要在於整理重點以及在實際操作上時常發生的問題。 同源政策(same-origin policy) 為了防止 javascript…

(繼續閱讀...)#CORS#cookie
前端

如何 Code Review

前言 身為前端工程師,通常在整個團隊裡面會是最常發送 pull request 的人。為了讓自己的 PR 更容易被測試,以及讓 reviewer 更容易的 review,總結了一些注意事項。 pull request 的描述 這個 pull request 的目的。例如:修正 layout、新增 feature、某個畫面的 style 等等 記住每個公司的成員都可以看見 pull request ,所以確保 pull request…

(繼續閱讀...)
前端

透過 vuex 與 webpack dynamic import 動態載入 module

在最近的專案中用到 vue 來開發,而如果要管理比較複雜的資料流貨狀態,通常都是用 vuex 來當作 Single Truth of Source 的 store。在 vue 裡頭建立 store 時,都是把所有的 module 寫完後,再統一放到 vue 的 root 當中。 這在一般的中小型專案中沒有什麼問題,不過一旦專案的架構變得越來越大,很容易讓 store 的資料結構變得越來越大且越來越複雜。而且 module 裡頭的 action, mutations…

(繼續閱讀...)#webpack#vuex#vue
前端

如何設計 user friendly 的 table

認清一件事實,table 是拿來看,不是被當作絢麗的視覺使用的 最近在後台頻繁有使用表格的需求,如何設計對使用者良好的 table 是一項挑戰,尤其在資料筆數多、欄位多的情況下,使用者很容易就會被額外的元素吸引。 而在現代 div 排版盛行的影響下,使用 table 很容易就被當成二流的前端工程師。 其實對於呈現資料上,table 仍然是個相當有效的排版方式,且他們具有的特色可以幫助我們排版更加輕鬆。 HTML 中的 table 在 HTML 當中 table 由幾個標籤組成: thead…

(繼續閱讀...)#table#CSS
前端

React16 重點整理

react 終於正式發佈 v16 了,其實 官方部落格 的介紹已經相當完整(而且賞心悅目)。本篇文章作為筆記與統整,精簡了部分的細節。 1. componentDidPatch(error, info) react16 最亮眼的部分,加入 ErrorBoundary 的功能,確保在 lifecycle 時的錯誤不會影響到整個 component。之前如果在 render 時發生錯誤,會導致整個 component 不見。 只有在 Error 在 lifecycle method…

(繼續閱讀...)#react
前端

前端面試心得

前言 終於有時間整理最近的面試歷程了。先總結一些看到的事情: 通常公司面試只考 Javascript 的熟悉度,多數關於演算法或是解釋原型鍊等等,很少考 DOM 或是 Event 的操作。 幾乎不考 CSS,就算有也只是簡單判斷 class、ID 優先度這種基本題目而已。 沒有面試考 HTML,例如 semantic tag、accessilbility、input type 使用等等。 React、Redux、ES6 語法幾乎成為前端必備技能,Angular…

(繼續閱讀...)#面試
前端

淺談 ramda 中的幾個 API

前言 ramda 是個相當好用的函式庫,如果聽過 lodash 或是 underscore 的話,可以將 ramda 想成 functional programming 的 lodash,他們的 API 有許多相似性,差別在於 ramda 本身有 FP 的功能,任何的 API 只要你沒有傳入參數,ramda 就會自動幫你做 curry,這提供了相當大的彈性。 比如說在 lodash 當中,API 常見的使用方式為: 而在 ramda…

(繼續閱讀...)#ramda#javascript
前端

IT 鐵人幫完賽心得

連結 今天是鐵人賽的最後一天,感覺自己最後結尾的部分收得不是很好,也有很多部分都因為時間上的關係沒有很完整地 介紹完。 挑戰 30 天連續發文的確是一件非常不容易的事情,自己也更了解到如果還有類似的機會,一定要事先做好準備才行,才不會突發狀況發生時,急就章地寫完文章結尾。 同時,這次挑戰的主題是以前從來沒有碰過的 webGL 及 3D 圖學。原本以為前 10 天的學習能夠掌握基本的知識,不過實際上要了解 webGL shader 的應用跟撰寫、活用 three.js API…

(繼續閱讀...)#webGL#IT 鐵人幫
前端

高度相同的排版解決方案

在前端的頁面中,我們經常會碰到需要相同高度的排版。最直覺的方法就是將容器裡的所有元素設為 float 或是 inline-block。 float 及 inline-block 如果是使用 float 排版,不但要先撐開父元素容器(clearfix),還要針對子元素設定 margin。 所以一旦內容太多,或是高度不足就會跑版。 而且,這樣的排版最大的缺陷就是, 必須設定高度 。 那,如果不設置高度呢? 就算設定了 min-height 也一樣,當內容超出高度時,就必定會面臨 overflow…

(繼續閱讀...)#flex
前端

css variable + sass variable = 😍

之前寫過了一篇關於自己對 css variable 的想法,原本對這個屬性沒有抱持著太大的期待,自己用習慣了 SASS 變數也覺得這個 css variable 反而像個彆腳的 system,不過如果你也是這樣想的人,可以參考這篇文章 Why should you care Css variables css 的變數已經出來有一段期間了,瀏覽器的支援程度還不算太糟。或許各位都曾經想過,這些變數的功能在 SASS 上幾乎都做得到,而且搭配 SASS 的 function 以及 SASS…

(繼續閱讀...)#css
前端

令人期待的 PostCSS

從 SASS 到 PostCSS 大約在一年前,PostCSS 開始竄紅在前端生態圈裡,不外乎就是所謂的 preprocessor 的特性、高度客製化自己的 plugin、搶先使用 cssnext 的功能,還能夠搭配各種建構工具(gulp, webpack),用起來非常輕鬆寫意。 變數 雖然剛開始看到 PostCSS 的時候還挺興奮的,但隨即思考了一下:「真的有必要馬上把 SASS 取代掉嗎?」。 PostCSS 的優點在於你能夠選擇你想要的 plugin…

(繼續閱讀...)#postcss#sass
前端

快速變化下的前端思考

重新思考語義化這件事 會有這個想法,是看到 instant article 的 html 架構,他們規範 instant article 的架構必須符合他們的規範,而且結構的表達也很清楚。我在裡頭看到了好多我以前沒有注意過的 html tag。像是 address figure caption summary 。 好奇之下查了一下 文件 等等。發現其實有很多語義化的標籤都已經支持目前主流的瀏覽器,spec 也寫得很清楚,但是目前主站多還是以 div + class…

(繼續閱讀...)