利用 Material-UI 統一 UI framework —— 均一前端工程師宜陞技術分享

Why we do this: 統一「自由奔放」的 UI 框架

1 個網站套用 5 個 UI 框架

開發前端 APP 的前置作業,不外乎是根據設計師送來的設計圖,從 UI 框架中選擇適用的元件(component)。

但均一團隊從「選擇 UI 框架」這件事開始,就是道複雜的多選題。

在還是好傻好天真的 ES5 時代,均一的網頁大多是套用 Bootstrap,當我們開始 migrate 到 ES6 + React,由於適用於 React 的 UI 框架仍未發展成熟,為了有充足的元件庫可以使用,均一先後引入了 Material-UI(註一)及 React-Bootstrap。

除了前面提到的歷史因素,造成均一 UI 框架混亂的關鍵因素還有維護套件註定要面對的「套件升級」。

當工程師發現現有的 UI 框架無法提供所需的元件,通常會考慮以下幾種解法:

  1. 自己刻出需要的元件
  2. 升級套件,擴充現有套件的元件庫
  3. 引入一個符合需求的新套件

如果是功能陽春的元件,通常會選擇「自己的元件自己刻」,但如果元件的功能複雜又遇上專案死線在即,往往會考慮引入新套件以加速開發,至於「套件升級」則因為牽一髮動全身的特性,總是淪為最不得已的選擇。

隨著新的 UI 框架持續被引入,舊框架的維護被長時間擱置,當我們鐵了心要規範框架的使用時,早已在均一的 codebase 中引入 5 大包 UI 框架 —— 引入了 Bootstrap、Semantic-UI、Material-UI、React-Bootstrap、Ant-Design。

其中較常被使用的 Material-UI、React-Bootstrap 都還停留在最初被引入時的版本號 version 0.x.x。

而過去過於「自由奔放」的管理原則,也產生了以下的技術債:

  • coding style 混亂
  • UI 框架版本老舊
  • 同一個頁面套用兩種以上框架,導致 UI 凌亂

為了償還前面提到的種種技術債,我們開始訂定相關的還債計畫。

註一:Material-UI 是當前流行的 UI 框架之一,它用來提供網頁中的元件(如:Button、Input)。

How we do this 1: 對 UI 框架專一

限縮框架數量

要確保 UI 框架不再多元發展,最直接的方式就是限縮框架的數量,因此目標之一就是選定「一個」適合長期使用的框架,並持續維護、更新。

當選定的框架無法提供工程師所需的元件,仍可以選擇引入較輕量的套件加速開發,確保工程團隊能靈活的運用第三方套件——但是,禁止再引入一整包框架!

選擇 Material-UI

在選擇框架前,我們調查了當前熱門的 UI 框架,考量到 Material-UI 的元件庫及 styling 解決方案相對完備,瀏覽器支援度符合團隊需求,且均一也已經有不少頁面是以 Material-UI 進行開發。

因此,統一改成 Material-UI 的成本較小、易用性高,最後雀屏中選,成為均一主要的 UI 框架。

筆者在前一段提到均一使用的 Material-UI 還有個陳年的老問題:版本過舊,當我們開始研究 Material-UI 的發展近況時,才赫然發現 Material-UI 早已從 material-ui 轉移到 @material-ui/core

因此在採用 Material-UI 的第一個階段性任務就是:升級 Material-UI (from material-ui @0.19.0 to @material-ui/core @4.9.1),並在升級過程中改善 styling 相關技術。

How we do this 2: 選擇合適的 style API

升級 Material-UI 的過程,除了更新元件的語法,也花了不少心力思考怎麼善用 Material-UI 豐富的 styling 解決方案。最先遇到的問題就是如何取捨 style API(註二)。

使用 Material-UI 的 styled-components API 取代 styled-components library(註三)

在考慮引進 Material-UI 的 style API 之前,均一團隊慣用的解決方案是 styled-components library (以下簡稱 styled-components)。

使用舊版 Material-UI 時,因為 styled-components 的 CSS 權重不足,無法蓋過 Material-UI 元件的 inline style,所以我們仍是以 inline style 來實作 Material-UI 的元件客製化。

新版的 Material-UI,styled-components CSS 權重不足的問題已被解決,除此之外,Material-UI 也受到 styled-components 的啟發,進一步提供了 styled-components API (以下簡稱 styled API)。

由於 styled API 幾乎可以取代 styled-components,經過以下考量,均一團隊決定使用 styled API 取代 styled-components:

  • CSS 權重:使用 styled API 不需要額外設定 CSS 的權重
  • Theming:使用 styled API 可以直接取得 Material-UI 的 theme object,不需要混用 styled-components 的 theming 系統(註四)
  • Coding style:後面會提到我們也開放使用另一種 Material-UI 的 style API ——hook API。由於 styled API、hook API 的 CSS 皆是以 JSS 撰寫 (styled-components 的 CSS 則是用 String templates),選擇 styled API 能讓 CSS 的 coding style 更統一。

註二:style API 是 Material-UI 提供的 styling 解決方案之一,style API 可用來撰寫元件的 CSS。Material-UI 主要提供了 3 種 style API:hook API、styled components API、higher-order component API。 

註三:styled-components library 是一個 JavaScript 套件,它用來撰寫元件的 CSS。Material-UI 受到 styled-components library 啟發而發展出 styled-components API。 

註四:theme 可以用來更換網站的主題設計,如 styled-components library 與 Material-UI 皆提供所屬的 theme 系統(<ThemeProvider>)。可透過調整 theme 的設定,統一更換網站的主題(如:顏色、形狀、陰影)。

使用 classes API 客製化內層元件,並捨棄 global class

當遇上 Material-UI 元件含有內層元件時 (如:<Button> 其實內含了 MuiButton-rootMuiButtom-label 兩層元件),Material-UI 針對內層元件的客製化提供了兩種方法:classes API 和 global class。

考量到 styled API 可以直接鎖定 global class,不像使用 classes API 還需要自訂義 classes,我們一開始選擇使用 global class 來客製化內層元件:

// 鎖定 global class .MuiButton-label 來客製化 Button 的內層元件 label
const StyledButton = styled(Button)(
    ({ theme }) => ({
        backgroundColor: 'white',
        '& .MuiButton-label': { // 鎖定 global class
            padding: [[theme.spacing(3)]],
        },
    }),
);

天真地用了一陣子後,才發現鎖定 global class 其實有個潛在問題:global class 是會變動的。

當同一個元件樹中有巢狀的 theme 時,內層 theme 的 global class 會被加上 index,如:MuiTypography-root 會變為 MuiTypography-root-67

假如 styled API 鎖定了 MuiTypography-root ,可能會因為巢狀 theme 產生的 index 導致 CSS 選擇器失效。

而此問題的解法就是:classes API。由於 classes API 會產生獨立的 class ,不會因為巢狀 theme 導致失效,為了避免潛在問題,我們便捨棄了 global class,並統一使用 classes API:

// classes API:
const useButtonStyles = makeStyles(theme => ({
    root: {
        margin: 3,
    },
    myLabel: {
        padding: [[theme.spacing(3)]],
    },
}), { name: 'useButtonStyles' });

const StyledButton = ({ ...props }) => {
    const classes = useButtonStyles();
    return (<Button
        classes={{
            root: classes.root,
            label: classes.myLabel, // 改用 classes API 來客製化 Button 的內層元件 label
        }}
        {...props}
    />);
};

使用 hook API「拆分 style sheet」與「客製化多層的子元件」

隨著決定以 classes API 來實作內層元件客製化,團隊內也開始嘗試使用另一種 style API:hook API (makeStyles) 來操作 classes API。嘗試的過程中發現在某些情境下 hook API 能更有彈性的操作 style sheet。

例如在拆分 style sheet 的情境中,hook API 可以輕易的拆分 style sheet 並注入不同的元件:

const usePopupBtnStyles = makeStyles(theme => ({
    root: {  // 拆分出 root
        height: 70,
    },
    deleteContained: { // 拆分出 deleteContained
        color: theme.palette.primary.contrastText,
    },
}), { name: 'usePopupBtn' });

const PopupBtnDelete = ({ ...props }) => {
    const classes = usePopupBtnStyles();
    return (<Button
        classes={{
            root: classes.root, // 注入 root
            contained: classes.deleteContained, // 注入 deleteContained
        }}
        {...props}
    />);
};

const PopupBtnCancel = ({ ...props }) => {
    const classes = usePopupBtnStyles();
    return <Button classes={{ root: classes.root }} {...props} />; // 只注入 root
};

在另一種情境,當元件內有多層的子元件時,hook API 也能產生多份 style sheet 分別注入各個子元件:

// hook API
const useStepStyles = makeStyles(theme => ({ // 產生 4 份 style sheet
    labelContainer: {
        textAlign: 'center',
    },
    label: {
        fontSize: '24px',
    },
    stepLabelRoot: {
        background: theme.palette.primary.main,
    },
    stepRoot: {
        flex: 3,
    },
}), { name: 'StyledStepLabel' });

const StyledStepLabel = ({}) => {
    const classes = useStepStyles();
    return (<Step
        classes={{ root: classes.stepRoot }} // 其中 1 份,注入 Step 的 style
    >
        <StepLabel
            classes={{ // 其中 3 份,注入 StepLabel 的 styles
                root: classes.stepLabelRoot,
                labelContainer: classes.labelContainer,
                label: classes.label,
            }}
        >
            stepLabel
        </StepLabel>
    </Step>);
};

在 Material-UI 提供的 3 種 style API 之中,均一團隊主要仍使用 styled API,同時也持續嘗試 hook API 該如何和 styled API 配搭運用。

How we do this 3: 善用 theming,style 共用最大化

移除 styled-components 的 ThemeProvider

過去我們一直沒有明確規範 theming 的用法及用途,在各個專案中也會混用 Material-UI 及 styled-components 的 ThemeProvider

延續前面提到的,均一團隊將逐步淘汰 styled-components,所以在正式啟用 theming 前做的第一件事就是移除 styled-components 的 ThemeProvider 並統一使用 Material-UI 的 ThemeProvider

善用 Material-UI 的 ThemeProvider

在統整各 package 的 theming 時,我們嘗試用以下原則進行重構:

  • 適用均一全站的 theme 統一放在 commonMuiTheme
  • 適用各個 package 的 theme 會寫在各自的 customTheme
  • 不適合套用整個 package 的元件客製化,則使用 style API
  • 同一個元件樹建議只有一個 ThemeProvider,避免巢狀 theme

重構的第一步,我們便根據設計師開出來的元件規範,寫出適用全站的 commonMuiTheme

// commonMuiTheme.js
const commonMuiTheme = {
    palette: {
        text: {
            primary: 'rgba(0, 0, 0, 0.6)',
        },
    },
};

第二步,則是在各 package 的 entry point 撰寫 customTheme,並透過 Material-UI 提供的 createMuiTheme 來 merge commonMuiThemecustomTheme

// entry point: index.js
const customTheme = {
    palette: {
        primary: courseMenuPalette.primary,
    },
};

/* 
 * createMuiTheme 能讓 customTheme 覆寫
 * commonMuiTheme 中相同的 key
 */
const muiTheme = createMuiTheme(commonMuiTheme, customTheme);

const show = () => (
		<ThemeProvider theme={muiTheme}>
        <Grouping/>
		</ThemeProvider>
);

最後,如果元件的客製化不適合放在 commonMuiThemecustomTheme,則會使用 hook 和 styled API 來實作。

How we fix problems: multiple ThemeProvider cause class name conflict

除了 migration to Material-UI,均一團隊極力想完成的另一件大事就是 migration to React。

為了同時兼顧專案開發與均一團隊的技術提升,我們會在開發項目中安排 React migration,常見的作法是將頁面中的局部功能替換成 React,以逐步達成整個頁面的 migration 。

這個作法的結果,以均一的課程主題頁為例,課程主題頁只有「content」及「切換出版社 Button」是以 React + Material-UI 實作,在整個頁面中,「content」及「切換出版社 Button」是兩棵不同的元件樹,即兩棵樹有各自的 ThemeProvider

這種單一頁面多個 ThemeProvider 的情形,極有可能會發生 class name conflict,均一團隊在升級 Material-UI 的過程中就遇上了各種類型的 conflict。

以下範例可重現同一頁面中有兩個平行的 ThemeProvider 會產生的問題。範例中的 Theme1 照理來說要為紅色,但因為 class name conflict 導致顯示為綠色:

const Theme1 = createMuiTheme({
  palette: {
    primary: {
      main: red[400]
    }
  }
});
const Theme2 = createMuiTheme({
  palette: {
    primary: {
      main: green[600]
    }
  }
});
const ThemeConflict = ({}) => (
    <div>
      <ThemeProvider theme={Theme1}>
          <Icon color="primary">add_circle</Icon> {// 預期為「紅色」,實際看到為「綠色」}
      </ThemeProvider>
      <ThemeProvider theme={Theme2}>
          <Icon color="primary">add_circle</Icon> {// 預期為「綠色」,實際看到為「綠色」}
      </ThemeProvider>
    </div>
);

造成 conflict 的原因是,兩個平行的 ThemeProvider 各自產生了同名的 global class MuiIcon-colorPrimary —— 不像巢狀 theme 還會為內層 theme 的 class 加上 index,由於 Theme2MuiIcon-colorPrimary 較晚被引入,導致 Theme2 的 class (綠色) 覆蓋掉 Theme1 的 class (紅色)。

<!-- output HTML -->
<div>
		<span class="material-icons MuiIcon-root MuiIcon-colorPrimary" aria-hidden="true">add_circle</span>
		<span class="material-icons MuiIcon-root MuiIcon-colorPrimary" aria-hidden="true">add_circle</span>
</div>
// output CSS
.MuiIcon-colorPrimary {
    color: #ef5350; // red[400]
}

.MuiIcon-colorPrimary {
    color: #43a047; // green[600]
}

當同一頁面中的 ThemeProvider 數量越來越多時就越有可能發生 conflict,甚至隨著環境 (local or production)不同還會遇到不同類型的 conflict。

幸好 Material-UI 都有提供自訂「class 生成規則」的方法,我們也在踩雷試錯的過程中找到了各種 conflict 的解法 —— conflict 都可以透過 Material-UI 提供的 createGenerateClassName 及 style API 的 name 解決。

What’s next?

工程團隊費時兩個月終於完成了 Material-UI 升級,儘管仍有許多未竟之事(如:將其他 UI 框架替換成 Material-UI),但對均一的前端開發環境來說已是一大福音,光是可使用的元件大幅增加,就為開發帶來極大的便利。

為了確保統一 UI 框架之路能繼續走下去,工程團隊仍持續努力在 migration to React 或進行重構時,從其他框架轉移到 Material-UI。

同時,我們也正在規劃和設計團隊協作進行 Atomic Design(註五),並基於 Material-UI 規劃共用的元件庫。

如果對均一前端的未來發展感興趣,可以持續關注我們,一起體會均一前端技術的成長與突破。

註五:Atomic Design 是一種設計方法論,此方法論將元件區分為五個層級 (由小到大為:原子、分子、組織、模板、頁面) 以促進元件的一致性與可擴展性。


均一招募中!

如果你對前端軟體開發充滿熱忱,而且跟宜陞一樣期待用科技來影響教育,我們正在尋找軟體工程師,馬上到招募頁面查看職位詳情!


作者|江宜陞(均一平台教育基金會前端工程師)
編輯|陳又慈(均一平台教育基金會實習生)

分享這篇文章:

相關文章

未來十年,均一的前進關鍵

核心基礎:多元協作,推進未來教育

均一平台教育基金會與六大利害關係人的持續協作是未來十年的關鍵,我們期望基金會成為一個能與數百個政府單位、企業與非營利組織共舞的協作共創型組織,就如同台積電創辦人張忠謀先生所說,他喜歡黃仁勳談到的,「台積電已與 400 名夥伴共舞,而英特爾卻只是一個人跳舞。」

目前,均一平台教育基金會已與一些單位有較深入的合作,包括教育部(含國教署、國教院等相關單位)、台北市教育局、新北市教育局、苗栗縣教育處、屏東縣教育處、宜蘭縣教育處。同時,在企業方面,均一與台積電、Google 等公司建立了合作關係,並與為台灣而教教育基金會(Teach For Taiwan)、誠致教育基金會等非營利組織形成深度的協作,共同推動「教育創新合作社」。

在上百個有互動的單位中,以上十個單位是我們擁有密切互動的合作夥伴。期待在未來的十年裡,均一平台能與超過百個單位達到這樣的協作深度,擴大我們的影響力。

在教育更加融入學用接軌的未來,我們希望成為更多企業在 ESG 和社會責任上的最佳夥伴。聯合國 SDGs 將會在下一個十年 2030 年屆滿,相信均一平台在知識深化、教師轉型兩個方面將取得很大的進展。

管理學大師彼得 · 杜拉克(Peter Drucker)認為,有效的社會運作需要政府、企業和非營利組織三個部門有效協作,而教育議題尤為如此。因此我們將持續透過每年的年度論壇、活動及感恩茶會等方式,與六大利害關係人對話,建立共識。期望最終能在更多人的認同下,對下一輪的課綱產生正面影響。

未來十年,均一的教育發展期待

協助教師升級,讓個人化學習成為學習主流

很多人認為均一教育平台對於教育未來的想像,是孩子在電腦前不斷地學習知識。然而,個人化教育的真正意義在於回歸孩子的本質,關注獨特性與差異性。人類必須透過其他人的啟發,並進行互動交流,因此教師的角色變得更加重要。

過去的教育目標過度著重於知識的灌輸,尤其是那些可以在考試中得到驗證的知識。然而,完整的教育目標應該包括以下方面:

  • 知識(認知能力):不僅僅是記憶和理解,還應包括應用、分析、評估和創造。
  • 品格(非認知能力):例如恆毅力、好奇心、感恩、自制、熱情、樂觀和社交智慧。
  • 技能(實踐能力):這是產學銜接最重要的一環,需要學生能夠實際應用所學。
  • 反思(後設認知能力):這是終身學習的關鍵,透過反思發現盲點,並邁向更高層次。

因此,均一平台教育基金會除了持續強化均一教育平台,讓知識學習更貼合個人的速度和程度外,過去幾年還致力於發展「非認知能力發展平台」(與麥肯錫、TFT 和 KIST 合作)、「PBL 教案平台 – ShareClass」(與成功大學和 KIST 合作)以及「DreamMoreMentor 媒合平台」(與DreamMore 團隊合作)。希望提供具體幫助和支援給教師,使老師們能夠從單純的教學任務中解放,保留更多時間來引導學生。

當教育 AI 和教師能夠協同進化時,培養出來的中小學生將不再只能面對國中會考和高中學測,而是真正具備多元知識、扎實品格,以及實踐能力和反思能力的下一代人才。這正是社會和企業對未來人才最期待的樣貌。

未來十年,均一的 AI 應用

作者 | 呂冠緯 (均一平台教育基金會負責人)

AI 解放知識教育,並輔助品格教育與專案學習

作為一個接受過醫學系基本「證據導向」訓練的教育工作者,我相信 ChatGPT 問世後,教育可以應用的工具層面,未來十年的變化將會遠大於過去一百年的進展。

打造不斷進化的蘇格拉底家教與英語口說老師

ChatGPT 於 2022 年底嶄露頭角,首先推出了 3.5 版本,2023 年 3 月則升級至 4.0 版本。4.0 版本問世時,OpenAI 官網上分享的第一個應用案例就是「蘇格拉底家教」,這是 OpenAI 和可汗學院 2022 年 8 月開始合作的成果。

以下是他們給 ChatGPT 4.0 的指令:「你是一位採用蘇格拉底式風格回答的導師,從不直接給學生答案,而是透過正確的問題幫助他們培養獨立思考能力。你應該根據學生的興趣和知識調整問題,將其分解為較簡單的部分,直到適合學生的程度為止。」

想必大家對於在這種前提下,學生如何與 ChatGPT 互動感到相當好奇!以下是我所摘要的一些有趣片段:

當學生提出一個二次一元方程式的問題,期望獲得直接的答案時,GPT-4 並不直接回答,而是給予引導。學生生氣地說:「請告訴我答案!」通常情況下,懶散的家教可能會直接給出答案,畢竟與學生發生衝突也很麻煩。即便是想細心引導,聽到學生表現得較「兇」,內心也難免會不耐煩。

然而,GPT-4 的回答很高水準:「我了解你可能希望直接得到答案,但我的目的是幫助你批判性思考並引導你通過解決問題的過程。讓我們專注於任務。這兩個方程式中的任何變量的系數是否有共同因子?」這句話涵蓋了三個層面:表達共情、溝通目的,最後回到教學。

學生回答卻答錯時,GPT-4 會這樣回答:「回答不完全正確,但你越來越接近了。」「不完全正確」這五個字讓我非常驚訝,因為若回答不正確,那可能會挫折了孩子剛剛願意嘗試回答的心,但若回「OK」卻又沒有指出孩子的問題。「不完全正確」後再補一句「但你越來越接近了」,讓我感到這個蘇格拉底家教具有同理心、有引導能力,且如果看詳細版解答,你會發現他真的能夠提供教學輔助。

另一個顯著的突破是 GPT 帶來的語言學習家教,由於語音文字轉換技術早已成熟,與 GPT 結合後,進行語音對話變得非常容易,可以到 YouTube 尋找參考影片。均一平台團隊在 2023 年初也推出了 Jutor Beta 版,讓重視雙語的台灣學生可以進行從初級到優級、CEFR A1-C2 的對話,並根據文法和流暢度給予學生回饋。

這些進展非常迅速,GPT 從 3.5 版本升級到 4.0 版本,就像一個高中生在先修微積分考試中,由 PR 值 0 進步到 40,或者一個參加美國律師考試的考生,由 PR 值 10 進步到 90,這樣的進步幾乎每幾個月就會發生。

最近,可汗學院推出了以蘇格拉底家教為模型的 Khanmigo,這是學生和老師的教育夥伴,以定期捐款 20 美元作為條件。20 美元相當於每月 600 元新台幣,就能夠擁有一位蘇格拉底家教,相較台灣家教一個小時可能就要 600 元,現在 600 元讓你能每月請一個蘇格拉底線上家教,而且每天 24 小時一週七天都可以問!

因此,均一除了英語口說家教,同時也在預備開發一個能隨時協助學習者解答問題、教學者設計教案的 AI 助教,相信下個十年,這樣的技術會變得非常成熟。我們才有機會真正降低師生比,讓每個孩子都有機會獲得更即時的回應,「每一個孩子不論出身,都能勇敢開口說英語、勇敢問問題,成為終身學習者。」

從使用均一,到成為均一捐款者:奧林匹亞選手的社會回饋

均一相信每個孩子都有自己的長處,而促進自主學習,一直都是是我們努力的目標。先前,我們收到一則捐款者的問卷回饋,他是建中學生劉徹,利用自學資源拿到麻省理工學位。他表示自己從小學二、三年級,便開始利用均一教育平台的影片學習高中生物、化學和物理。

均一讓他養成在線上資源中不斷自修的能力,國內大學的 MOOCs、國外知名的可汗學院、edX、Coursera 等學習平台都有他的足跡。他更是利用 edX 成功拿到了麻省理工學院的微碩士學位,成為 MIT 校友,並於 Coursera 平台上獲得美國線上碩士入學許可。

2021 年,他保送進入建中,卻依然持續自學,並於 2022 年錄取物理奧林匹亞選訓營、和資訊奧林匹亞選訓營,最終選擇資訊類別,代表台灣參加印尼資訊奧林匹亞競賽。去年,他亦獲得了 YTP 少年圖靈大賽的第一名,並且將獎金全數捐獻給了均一。

「我一直很想像您一樣,幫助別人,我將我個人的獎金一萬元,全數捐給均一教育平台。」從使用者到成為捐款者,去年劉徹獲得了 YTP 少年圖靈大賽的第一名,並且將獎金全數捐獻給了均一。

資訊奧林匹亞選手 劉徹:「我一直很想像您一樣,幫助別人,我將我個人的獎金一萬元,全數捐給均一教育平台。」

均一讓她重燃希望:從灰心到自學成功,賦能者璨霙的故事

小學時期的璨霙並不信任學校,也不相信教育,但現在,她是透過教育改變世界的賦能者。

出生在南投郊區,璨霙在求學的起點便面臨頻繁更換導師、被老師不公平對待的挑戰。不穩定的環境,讓他們成為學校中惡名昭彰的班級,班上同學似乎都習慣了周遭大人對自己的失望。在動盪之中,璨霙失去對學校的信任,同一時間家庭也無法提供足夠的安全感,那是一段最黑暗的時期。

這樣的狀態一直持續到五年級時,新導師給了她前所未有的關心,並向她介紹了「均一教育平台」。那是璨霙第一次體會到有人關心的感覺,也是第一次覺得,自己好像可以再相信老師、相信教育一次。

「我可能會在現有體制下,被學校的決策犧牲掉,但我不會被教學影片放棄。」在認識均一之後,即便在班上聽不懂,璨霙也能透過數位學習,重複觀看直到學會。因為遇到均一,讓她得以靠著自學,考上台北的大學。

現在的璨霙就讀於教育科技學系,她相信透過平台的建置以及載具的提供,就能以科技帶動教育平等。「我就是活生生的例子,我也期待以後的每一代孩子,都可以相信教育能夠改變他們。」

「海水與沙本來都是柔軟的東西,但是它們混在一起的時候卻變得如此硬實,就像內心質地各自柔軟的人,聚在一起就變得無所畏懼。我非常感謝每一位願意持續耕耘教育議題的人。因為有你們,我們才能用最溫柔的方式,回應這塊土地上每個真實存在並且美好的生命。」璨霙在訪談最後這樣說。

未來,璨霙希望能成為一位賦能工作者,幫助與自己兒時相同處境,甚至更挑戰的孩子們。她也期待能有更多人一起投入、支持這樣的教育議題,成為彼此互助前進的燈塔,透過教育翻轉更多生命。

璨霙的照片

均一教育平台創辦人方新舟董事長:不求己利、願意給年輕人舞台的風範

作者 | 呂冠緯 (均一平台教育基金會負責人)

教育的「門外漢」,一手帶起台灣年輕教育團隊

2022 年 10 月,均一教育平台迎來了它的十週年紀念;2023 年 1 月,均一平台教育基金會也滿五歲。產品歷史比目前負責的組織更悠久,這要歸功於創辦人方新舟董事長(簡稱方大哥),他創立了均一教育平台並有意識地進行傳承,在五年前將均一團隊從原本的誠致教育基金會獨立出來。

究竟是怎樣的「教育創業家」能創造如此成就?方大哥更願意自稱為「教育門外漢」,因為他的背景是科技業,在矽谷起家,回台創業後成為誠致科技董事長,最終公司與雷凌合併並出售給聯發科。然而,他在教育界具有深遠影響力,皆因創建了台灣最大的線上教育平台——均一教育平台,並創立台灣最大公辦民營學校體系 KIST (KIPP Inspired School in Taiwan),同時也是影響劉安婷創辦 Teach For Taiwan 的重要推手。

方大哥帶領的均一教育平台至今仍深刻影響著許多孩子的學習與成長。他與翻轉教育重要推動者嚴長壽董事長經常攜手支持許多具有推動力的一線教育工作者,為台灣教育改革注入更靈活且扎實的由下而上的力量。

方大哥行事低調,很多人容易誤認我為均一教育平台的創辦人。實際上,方大哥不僅創立了均一教育平台、培養了一群年輕團隊,還將許多經驗傳授給我,且總是樂於讓舞台留給年輕人。

正因為方大哥是我生命中除家人以外最重要的恩人,我想從個人視角分享我最敬佩方大哥的一點:「願意給年輕人機會」。

方大哥的信任,是我不曾從其他長輩身上感受到的

2011 年底,我在網路上錄製了一系列教學小短片,吸引了方大哥的注意。當時,我還是一名大醫院的實習醫生,方大哥邀請我與他合作。雖然起初我婉拒了邀請,但在接下來的一年裡,方大哥經常寫信給我,堅定地分享他的教育願景,使我逐漸被他的熱情所感染,並在服役期間,開始考慮與方大哥跨世代、跨專業的合作機會。

2013 年初,我在海軍服役期間,經過深入的信仰反思與探索,決定加入誠致的大家庭。在電子郵件中,我寫道:「方大哥:在跟父母親審慎地討論過以後,我們的共識是我會加入誠致的大家庭。 簡單地來說,my answer is “yes”。我會盡力完成我能做到的事情。」方大哥很快回信說:「冠緯,謝謝您和您爸媽做了一個影響台灣未來教育的決定。有機會我一定要去拜訪您爸媽向他們致敬!」

那年大年初二,方大哥和太太來到我家拜訪,與我父母親交流。我父親直接問道,方大哥到底希望我做什麼?方大哥毫不猶豫地回答,他希望我能成為誠致未來的執行長。當時,25 歲的我聽到這番話感到非常驚訝。原來,在方大哥眼中,我不僅是個擅長錄製影片的專案教師,而是具有發展潛力的年輕人。這種信任是我不曾從其他長輩身上感受到的。

方大哥與冠緯合照:方大哥在短短的四年半時間內,就願意放手讓均一團隊獨立運作

有一種愛是放手,相信英雄出少年

時間快轉到 2013 年的 9 月,我才剛加入誠致兩個月,方大哥確診罹患了肺腺癌。在入刀房前的幾小時前,他打了個電話給我:「冠緯,我想跟你說,謝謝你加入誠致,投入在均一教育平台的工作,我希望你答應我一件事好嗎?」即便還不知道要答應的是什麼,我直覺式的回答:「我答應了,方大哥請說。」

「如果,這一次開刀,我沒有辦法回來,請你持續均一教育平台的工作,至少十年,好嗎?我相信你。」

我在電話另一端愣住了好幾秒,不知道是什麼讓方大哥有這樣的膽識和信任,說出這樣的話。雖然我感受到巨大的責任,但同時也感受到強烈的使命感。

「方大哥,收到,我會全力以赴。」

幸運的是,方大哥很快完成手術並逐步康復,讓我有機會跟隨他學習,共同奮鬥。我發現他與一般保守型領導者不同,敢於授權,並用「以色列式辯證」激勵我們勇敢地與他討論。他相信真理越辯越明,很少以長輩身份壓制年輕夥伴,也因此我和其他年輕夥伴的膽識逐漸被培養起來。

一年後,方大哥將我提拔為執行長,兩年後邀請我加入董事會,又過了一年,他邀請我承擔整個均一教育平台的營運責任,獨立成立新的基金會「均一平台教育基金會」,擔任負責人。

從 2013 年 7 月加入誠致,到 2018 年 1 月團隊正式分拆成立新單位,僅歷時四年半。我很難想像有哪位前輩敢這麼做,因為在每個過程中,我都還有很多地方沒有準備好。但是方大哥緊抓三不原則:不難的事不做、不具規模化的事不做、不能擴大影響力的事不做。在均一教育平台之後,他創立了第二個重要專案:實驗學校 KIST 體系。他清楚兩者在同一組織內難以共存,因此鼓勵均一獨立,並提供第一年的營運資金。這種無私的價值觀深深影響了我。

方大哥把經營組織視為一個大膽的教育實驗,不等孩子或晚輩準備好了才放手,而是只要他們有面對失敗的意願,並且跌倒後能夠再次站起來,就應該及時放手讓他們去嘗試。

受到方大哥的影響,均一團隊非常樂意給年輕夥伴提供挑戰:我們曾經讓一位高一的自學生突破實習生年齡限制,讓三位大三的夥伴擔任深度兼職工程師,還讓一位即將畢業的台大學生擔任 Google 合作專案經理。

事實上,許多企業家也跟隨著方大哥的腳步,以傳承精神回饋下一代。董事會中的梁立省、何麗梅、李吉仁老師、簡立峰和白崇亮等企業家都樂於扮演這樣的角色。此外,還有其他眾多長期支持和贊助均一教育的企業和基金會夥伴。

我堅信,只要更多社會成功人士願意身體力行,為年輕人創造機會,我們的社會將穩健地向前邁進,對立將大幅減少,世代之間的合作將更加密切

方大哥與團隊合照:均一團隊尚未從誠致教育基金會獨立時,團隊與方大哥的溫馨合照

生命的改變從教室開始

在孩子長大成人之前,有將近一半的時間在學校度過,許多孩子的成長與改變也在這裡發生。有些孩子從討厭數學到數學成績名列前茅、有些孩子從討厭學習到願意學習,卻也有些孩子無法前進,不論是學習動機低落、教育資源受限,都是可能的原因之一。

也因為看見了這些孩子的困境,我們希望透過科技的力量,提供孩子們優質且免費的學習資源,落實教育平權,打造一座沒有牆的教室。

我發現,原來教學就該是看見孩子真正需要被幫忙的地方,而不是看教學指引而已。

大同國小.林政琦老師

教室裡的改變

均一在一次次與學校、課輔班的合作中,看到許多成長與改變的故事。

我們看到有孩子從一開始放棄數學、不敢發問,到後來能主動舉手發問,甚至能教其他同學;也看到有老師體悟到成績不是一切,重要的是孩子們的學習態度以及如何面對挑戰與困難。

可能有一些東西並不是,成績單上面看得到的,有的時候我們好像,太在乎這個學生的表現是集中在成績這一塊。

文英國中.李延慶老師

孩子有無限多的可能正在教室中發生,邀請你與我們一起,創造更多免費優質的教育資源,讓更多孩子的未來有好的改變。

你也能一起參與改變

均一是一個非營利組織,為了專注於我們的願景使命,我們不承接政府預算、不發展有對價關係的盈利,仰賴與我們有相同願景使命的大眾捐款支持,期待集合眾人之力,實現真實的共創與共好。

邀請你一起參與 >> 公益支持

不分城鄉,教室裡的學習弱勢

不論在都市或是偏鄉,教室裡都存在著學習弱勢。每個孩子的學習步調、吸收知識速度都不同,如果孩子們沒辦法在教室裡學到適合自己步調與發展需求的內容,都有可能處於學習弱勢。我們希望透過平台上免費有趣的學習影片與習題、科技化的平台輔助功能,讓這些孩子能夠按照自己的步調學習,培養自信找回成就感,發揮原生天賦。

我們藉由課輔班合作計畫與學習扶助計畫,讓更多學習速度不同的孩子,得到差異化的教學,弭平學習落差,並在過程中持續鼓勵、陪伴孩子與教師

課輔班合作計畫

透過與課輔班合作,均一提供平板筆電載具、專業師資培訓與觀課陪伴,協助課輔班老師能以遊戲化的數學學習模式,讓弱勢孩子重拾學習興趣、鞏固基本學力。合作期間,也看到許多老師陪伴孩子的動人故事,我們記錄這些過程與故事,也邀請有興趣的你,點擊下列文章更了解計畫成果,也認識課輔班老師的故事!

有位平常學習上較落後的孩子,跟我分享,是磨數營讓她愛上數學。甚至跟我說 : 努力沒有做不到的事!

屏東躍愛課輔班 林綺漩 老師

學習扶助計畫

在 106 學年度,均一與苗栗縣和屏東縣分別合作進行「結合均一的課中補救」試辦計畫。藉由一般課堂的時間,抽離需要額外學習扶助的孩子到「學習扶助班級」,搭配均一平台的使用,有效診斷學生的學習斷點,提供個人化學習。

經過三年的顯著成效與現場教師的正面迴響,109 學年度起,均一在苗栗、屏東推動學習扶助「深化」模式,除了繼續數學課中學習扶助外,期盼藉由更深度投入的專案教師、更具規模的教師社群、更系統性的增能與支持,為學習扶助的師生帶來更有效的教與學。

學習扶助計畫進行的這幾年,我們不只看見許多孩子學習的進步,更看見許多老師教書育人的理念,邀請你點進下方文章,認識其中一位專案教師的故事。

苗栗文英國中李老師照片

帶孩子走出教室裡的無力感 —— 苗栗延慶老師分享

在眾多均一平台上的老師當中,今天想特別與大家分享延慶老師的故事。延慶老師是「均一課中學習扶助深化專案」的老師,他觀察到,傳統一體適用的教學當中,班級內存在的學習落差影響了孩子的學習信心;透過「課中學習扶助」,老師們能用不同的教學方式,幫助孩子建立學習成就感,以及對未來的信心。

了解更多 »

你也能一起參與改變

均一是一個非營利組織,為了專注於我們的願景使命,我們不承接政府預算、不發展有對價關係的盈利,仰賴與我們有相同願景使命的大眾捐款支持,期待集合眾人之力,實現真實的共創與共好。

邀請你一起參與 >> 公益支持

是老師,也是教育創新家

在均一有一群老師,不只出現在第一線教學現場,分享如何利用平台提供孩子們差異化教學,給學校或課輔班的老師,更設計出多元跨領域的課程,激發孩子們的學習動機。

我們在台灣擴大推廣 Code.org 的 Hour of Code 一小時玩程式,團隊夥伴製作中文化插電與不插電的程式課程、結合創意的教學設計,讓 Code.org 這套全球廣受好評的程式課程,在台灣的使用濃度達到世界排名第九、亞洲排名第二,讓臺灣的程式教育能夠與國際接軌。課程資源與師資培育,都逐步與國際接軌。

「模組化的課程設計,不論對教師教學、學生學習都有很大的幫助;因為課程規劃得很完整,老師能很清楚第一步要如何開始、接下來又該怎麼做,以及背後的教學目標,搭配程式闖關遊戲,小朋友會更有動機去嘗試、思考,甚至他們做完後、還會想再做一次,主動地去複習所學!」

太平國小 陳宜均老師

為了讓孩子透過程式學習運算思維,均一也設計了一系列 Scratch 課程,採取專案導向學習 (Project-Based Learning),以深入淺出的講義或影片引導,經由不同領域主題,’當孩子面對給予的任務,將學習如何解構問題、摘要重點、發現規律,循序漸進地練習程式的思考。

數電快閃教室

數電快閃教室計畫,是團隊夥伴到教學現場透過「數學 X 電腦科學」的跨領域課程,將好玩、互動性高的電腦科學融入數學的課程內容,讓孩子覺得原來數學可以這麼有趣,學到的知識也可以加以應用。均一也透過此課程和現場老師分享跨領域教學,探索更多的學習可能

後續雖遇上五月份的疫情,團隊發揮創意推出「線上快閃教室」,以線上的形式,快閃 18 所國小的線上教室,帶來「自學力就是你的超能力」主題分享,總計有 329 位學生參與,我們希望藉由這個活動,讓孩子在疫情期間能夠找到自己學習的目標和節奏。

當我們 Code 在一起說故事

「當我們 Code 在一起說故事」專案計畫,也就是平台上「電腦科學起步走|一起說故事」課程,是源自 Google 開發的 CS First,均一除了將其中文化翻譯,並且配合 108 課綱將課程內容和教學模組在地化。課程內容以程式作為跨域學習的槓桿,融合電腦科學、語文、音樂、藝術,鼓勵孩子用想像力編寫動人的故事,並且練習程式的思考。

此課程也獲選「 第三屆未來教育.臺灣100 – 全臺年度百大創新教學專案」的獎項殊榮。

每個孩子都希望能創造屬於自己的故事,細緻的課程架構,並附有專人引導的自學影片,孩子可以根據自己的學習和創作速度前進,人人都有成就感!

KIST: 拯民國小.宋亭緻老師

你也能一起參與改變

均一是一個非營利組織,為了專注於我們的願景使命,我們不承接政府預算、不發展有對價關係的盈利,仰賴與我們有相同願景使命的大眾捐款支持,期待集合眾人之力,實現真實的共創與共好。

 邀請你一起參與 >> 公益支持

教室裡的風景

每個人的生命當中,都有那麼幾位令人印象深刻的老師。有的老師幽默風趣、有的嚴厲而堅毅,有的老師像是再生父母,讓我們從學習與探索中,發揮生命更大的價值。

在 2021 年 的停課期間,有一種老師大量增加了,他們是守護孩子學習不中斷的「抗疫老師」,在短短幾天內,設法與孩子取得聯繫、使用各種數位工具,並給予遠距支持。

事實上,在在台灣的每一個角落,一直都能看見這些義無反顧為孩子付出的身影。以下是均一在推動教育改變的路上,遇到的幾位老師,希望透過簡短的文字、影片,與你一起分享,均一在教育現場的看見。

均一教師的身影

安溪國中——靜怡老師

靜怡老師任教於新北市安溪國中數學科,七年前開始使用均一教育平台,並將均一應用在「適性分組班」與自己的班級教學當中。

「讓孩子不會只是之前的挫折一直累積到最後,讓他可以在這裡找到讓他產生信心的地方。」/ 靜怡老師

點我看靜怡老師的完整分享 >>

 

安溪國中靜怡老師

 

高雄岡山教會課輔班——子婕老師  

子婕老師雖罹患罕病,仍完成中央大學數學、資工雙主修,更因為從小便與媽媽在教會服務弱勢孩童。研究所時對數位教學產生興趣、畢業後即投入弱勢教育。2020 年導入均一教學後,子婕老師與課輔團隊投入其中,幾乎天天討論到深夜。雖然孩子的學習成就並沒有一飛沖天,但她認為,孩子的正面心態、學習品格才是第一順位。

「我希望這些孩子記得,小時候有這麼一群人拼 死拼活努力去愛他們,他們是值得被愛的。」/ 子婕老師

點我認識「弱勢課輔班計畫」>>

均一如何支持教師

均一經由支持教師,更規模化地影響孩子。

在子婕老師參與的弱勢課輔班計畫中,均一在兩年內培訓了 110 位教師,其中有 87% 的老師過去未曾使用數位平台輔助教學,在經過師資培訓後,提升了 20% 老師的教學信心,大多數老師更能夠獨立於課堂中教學,陪伴孩子探索數位學習平台,找到適合的學習內容。

除了弱勢課輔班計畫之外,均一長期與苗栗、屏東學習扶助班級合作,培養學習扶助科技教師。疫情期間,更曾累積上千名老師同時在線參與研習培訓,支持全台教師、家長陪伴孩子停課不停學。疫情之後,超過半數的現場教師仍持續採取科技搭配教學,數位學習將是教師、學生、家長不可或缺的關鍵能力。我們期待持續投入培訓資源與教學法開發,支持現場教師,進而支持更多孩子。

你也能一起參與改變

均一是一個非營利組織,為了專注於我們的願景使命,我們不承接政府預算、不發展有對價關係的盈利,仰賴與我們有相同願景使命的大眾捐款支持,期待集合眾人之力,實現真實的共創與共好。

邀請你一起參與 >> 公益支持