Rplus
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee
  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- title: 變數握手,CSS、JS 樂無窮 by Rplus -- JSDC 2017 description: Use CSS and JS Variables together to make web more wonderful --- <h1 class="workspace"> <div class="left">CSS</div> <div class="right">JS</div> <div class="var">Variables</div> </h1> <style> .present .workspace { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-image: linear-gradient(100deg, #e7e7d0 50%, #18182f 0); text-align: center; font-size: 15vmin; font-weight: 900; line-height: 1; color: #fff; } .present .workspace .left, .present .workspace .right { position: absolute; top: 15%; bottom: 0; width: 50%; flex-grow: 1; height: 100%; overflow: hidden; mix-blend-mode: difference; } .present .workspace .var { position: absolute; top: 40%; left: 50%; transform: translateX(-50%); mix-blend-mode: difference; } .present .workspace .left { left: 0; } .present .workspace .right { right: 0; } </style> <br> <br> <div class="intro"> <a href="https://fb.me/rplus.tw"> <img src="https://avatars.githubusercontent.com/rplus" width="120"> </a> <a href="https://twitter.com/RplusTW">@RplusTW</a> </div> Note: Hi 大家好, 我是 R+, 今天這一場的主題是「變數握手,CSS、JS 樂無窮」 雖然 JSDC 本來跟我說,可以講一場 CSS 的主題來打 JS 的臉 我其實也是滿想的, 但是有些經驗的前端工程師應該都能理解:前端技術三支柱,並不能偏廢 純 CSS 雖然很 geek、很生猛;但還是有它的極限在,CSS 它仍然還是該以 style 為主軸 雖然有些 CSS 的 selector 可以做到一些互動的效果 但網頁的互動邏輯基本上還是以 JS 作為核心 所以今天來分享一些 CSS variables 跟 JS 互動的使用經驗 我講的也不一定都對~ 有什麼疑問的話 非常歡迎大家一起研究討論 你可以在 FB 或 Twitter 上找到我, 但技術問題能公開問就公開問 盡量不要用私訊,這樣我要是解釋地不好也沒法得到其他人的修正 若你比較害羞 也可以到 Gitter 上 cue 我,連結會附在最後面 啊 因為 Gitter 挺冷清的,不用太擔心會有很多人看到 XD --- # <a href="https://translate.google.com/?#en/zh-TW/variables">variables</a> `/v'ɛriəbəlz/` <br><br><br> Note: JS 大家都很常用 var, let, const 這邊就不再多加介紹, 今天的主題會著重於 CSS variables,我會先介紹一下 CSS variables 的基礎知識 --- ## CSS Custom Properties for Cascading Variables <br> * CSS Custom Properties * CSS Variables <br> <br> > spec: https://www.w3.org/TR/css-variables-1/ --- ## CSS Custom Properties for Cascading Variables > This module introduces <span><!-- .element: class="fragment highlight-green" -->cascading</span> variables as a new primitive value type that is accepted by <span><!-- .element: class="fragment highlight-green" -->all CSS properties</span>, and custom properties for defining them. <br> Note: 變數不稀奇,像 SASS 之類的工具也都有,但 cascading 則是 CSS variables 更加靈活的關鍵點 "all CSS properties"! 泛用 在 2015 就是候選推薦標準了 Candidate Recommendation spec,滿穩定了,大家可以安心用,不用怕 API 大改 --- ## Syntax ```css .boo { --color-red: #c00; color: var(--color-red, #f00); } ``` <pre><!-- .element: class="fragment" data-fragment-index="1" --><code class="scss hljs"> .heart { --color-red: #f00; --color-blue: #00f; --color-♥: var(--color-red, #900); color: var(--color-♥); } </code></pre> <br> <br> Note: 兩個 dash 後接 custom property 引用時使用 var 包起來,後面可以放 fallback 的屬性值 前面的 property 跟後面的 value 都非常寬容, 一般只要正常的文字都沒問題,當然特殊符號還是有可能炸掉的 但 emoji 是 ok 的~ 對特殊語法有興趣的也可以去讀讀 w3c spec,這 spec 算是字數挺少的 spec 了 XD --- #### 常見使用情境 <ul> <li>顏色</li> <li>尺寸</li> <li>文字</li> <li><!-- .element: class="fragment" data-fragment-index="1" -->media query</li> </ul> Note: 對,基本上就是你會去問 UI 設計師的東西 大多像是定義用的,可以想像成 spec 給的值 這些定義類的用法跟 SASS 裡的變數比較類似 就是定義後讓其它元件可以直接跟變數連動 省得異動時每個地方都要去改 這些不少文章都會優先以這類顏色、大小的明顯變化來示範 CSS variables 的威力 但如果跟 media query 混在一起後 就會有比較有趣的變化 來看一下 --- ```css :root { --base-font-size: 14px; } .h2 { font-size: var(--base-font-size); } @media (min-width: 600px) { :root { --base-font-size: 16px; } } ``` note: 像這一例中,我們分別在全域與 media query 裡使用 CSS variables 可以讓不同視窗寬度下有不同的基礎字級 你可能會說,這個就直接在 media query 裡改 `.h2` 的字級就可以了呀 OK,那兩個呢? --- ```css :root { --base-font-size: 14px; } .h1 { font-size: calc(var(--base-font-size) * 1.5); } .h2 { font-size: var(--base-font-size); } @media (min-width: 600px) { :root { --base-font-size: 16px; } } ``` Note: 若設計師希望在不同寬度下有不同的字級,但相對大小仍維持相同的比例 可以觀察到: 在愈多元件相依於同一個值的時候,CSS variables 就愈能體現它的便利性 只是這邊也需要留意: 除非有管理上的需求,盡量在複數元件都相依的才使用,而不是全部都直接改用 而與 media query 搭配的這種例子中 也是更明確地展示了 CSS variables 中 cascading 繼承的重要性 --- ## cascade with `font-size` ```scss .ooo { width: 5em; height: 5em; font-size: 20px; &.big { font-size: 50px; } .o { width: 1em; height: 1em; transform: translateX(2.5em); } } ``` note: 這邊先將時光往前移一點, 在還沒有 CSS Variables 的時候 我們如何利用繼承特性, 我們比較常見的類似用法是使用 `font-size` 控制元件的尺寸 然後再使用 `em` 就可以便利地調整相對尺寸大小 例子中在不同 class 下了不同的 `font-size` 即可一起控制整體元件的尺寸 控制子元件尺寸也可以用 `%` 處理, 但若需要處理 `transform` 的時候,使用 `%` 就會遇到一些問題 不過這樣的繼承只限於很少的屬性,`color`、`font-size`… 所以 CSS variables 出來救大家了~ --- ## [瀏覽器支援](http://caniuse.com/#feat=css-variables) * Global: 78.11% * Taiwan: 84.6% <sub><small>(5% IE 11)</small></sub> --- ## 瀏覽器支援 * Firefox v31 <small><sub>( 2014 / 06 )</sub></small> * Chrome v49 <small><sub>( 2016 / 05 )</sub></small> * Safari v9.1 <small><sub>( 2016 / 05 )</sub></small> * iOS v9.3 <small><sub>( 2016 / 05 )</sub></small> * Android WebView <small><sub>gg</sub></small> * IE <small><sub>gg</sub></small> * Edge v15 <small><sub>( 2017 / 04 )</sub></small>、v16<small><sub>( 2017 / 10 )</sub></small> note: Edge v15 is buggy 問一下,你負責的專案需要支援 IE 11 的可以舉個手嗎? 想在工作上使用 CSS Variables 的朋友們,趕快問問附近剛沒舉手的還缺不缺同事 XD 開玩笑~ --- ### Fallback with CSS: ```css @supports ((--a: 1)) { :root { --color-red: #f00; } } ``` note: feature detection IE 11 gg again, QQ --- ### Fallback with JS: ```js if (window.CSS && window.CSS.supports && window.CSS.supports('--a', 0)) { _html.classList.remove('no-css-variables'); } ``` Note: 類似 Modernizr 處理 class 的方式 CSS variables 基礎介紹到這 --- ## 變數握手 <br> <br> <br> <br> <br> <br> <!-- .slide: data-background="https://i.imgur.com/dWHMtr7.png"--> note: 進主題:握手 當然,這邊講的不是自己握手,而是要跟別人互動的握手 --- ## 變數握手 <br> <br> <br> <br> <br> <br> <!-- .slide: data-background="https://i.imgur.com/88e1JJG.jpg"--> note: cc0 image source: https://pixabay.com/en/paw-hand-friendship-dog-human-548634/ --- ## 1. set ```js // inline-style element.style.setProperty('--a', 2); ``` <br> <br> <br> <br> note: 一般比較常用的是 set 值 在 JS 判斷一些環境後,給定特別設定值 再由 CSS variables 在 CSS 裡處理好 UI 的邏輯 React v15.6 才有支援在 style 屬性裡, React 舊版要自己手刻 & 用原生寫法手動更新 這寫法其實也挺噁心的就是 https://github.com/facebook/react/pull/9302/files#diff-61273f1ad4383d5a3a802ac95031ade4R220 Vue https://github.com/vuejs/vue/commit/4b8eb75c7a5544a1f65ebd679fd89639208d5976 --- ## 2. get ```js // inline-style element.style.getPropertyValue('--a'); // any case window.getComputedStyle(element).getPropertyValue('--a'); ``` <br> <br> <br> <br> note: get 的情境會比較少一點 我自己也是滿少用的,只有一次在處理 CSS image sprite 有用到 是也滿好玩的 有些 CSS variables 是預寫好在外部 CSS 檔案裡,這種情況就要用第二種方式才能拿到值 --- * CSS variables 擅長: (X)與 JS 溝通 (O)在 CSS 裡處理相依 <!-- .element: class="fragment" data-fragment-index="2" --> <br> <br> ----- <!-- .element: class="fragment" data-fragment-index="2" --> <br> 要不如… 直接用 JS 設定 inline style? note: 恩… 看到這裡,應該會覺得以前直接設定 inline style 在 DOM 上更直覺一些 XD 但像前面提到的, CSS variables 有個很關鍵的點就在於 `cascade`、繼承的特性 我們可以統一在親代層設定一次,而不是每一層都設定一次 除了減少 DOM 異動次數以外,更重要的是讓相依的值可以真的是相依, 而非依 JS 邏輯處理並依序設定後,才"看似"相依 實際來看一些例子 --- [Demo 1: parallax layers @ CodePen](https://codepen.io/Rplus/pen/GOZjKM) <a href="https://codepen.io/Rplus/pen/GOZjKM"> <video autoplay muted controls playsinline loop src="https://giant.gfycat.com/UniformLimpIzuthrush.webm"></video> </a> note: 視差效果很夯,但相對不難的實作原理,相信很多人都玩過、或套用過 而這效果其實也很適合用 CSS variables 處理 今年的 COSCUP 網站首頁也有使用到視差效果 + CSS variables,有興趣可以去參考看看:) --- ```css .l { transform: translate(-50%, -50%) translate( calc((var(--dx) - .5) * var(--df) * 200%), calc((var(--dy) - .5) * var(--df) * 200%) ); } .box { --dx: 1; --dy: .7; --df: 0; } /* default */ ``` ```js const setDxDy = (evt) => { let dx = evt.layerX / boxWidth; let dy = evt.layerY / boxHeight; box.style.setProperty('--dx', dx); box.style.setProperty('--dy', dy); }; ``` note: 從這例子可以看到,我們只需要設定 dx 跟 dy 就好了 其它定位通通會經由設定好的 CSS Variables 處理好相依 那開發者的工作就會變成:去找出相依的規則來 這部份若用以前的寫法 就會是去設定每個 layer 的 `transform`,變成要觸發很多次 DOM 異動 數量一多,勢必會影響網頁效能 當然,也不是說用 CSS Variables 就通通一定效能一級棒 數量多的 CSS repaint 也是很容易有效能差而出現 jank 的情況 --- ## CSS condition ```scss // [--x, --y] = [0, 0] // [--x, --y] = [1, 1] transform: translate( calc(0% - 100% * var(--x)), calc(0% - 100% * var(--y)) ); ``` <a href="https://codepen.io/Rplus/pen/BmKZyL"> 變形:<br> <img src="https://i.imgur.com/xK3QsjC.png" width=250> </a> note: 有 CSS variables 後,CSS 也能做到簡單的判斷 那通常會稱作 CSS condition 透過 step function 的概念來切換不同的數值 --- ## CSS Variables 真的是 Variables 嗎? ```js // JS i = i + 1; ``` ```css /* expected syntax for real CSS variables */ .l + .l { --df: calc(.2 + var(--df)); } ``` <br> <br> note: 順便用這例子提一下為什麼正式名稱不是 CSS Variables 並沒有像 JS 變數的特性 XDD 不能用自己再賦值給自己 如果真的需要類似的功能,需要另外一組來更新數值 它真的比較適合稱作 Custom Properties --- [Demo 2: re-order @ CodePen](https://codepen.io/Rplus/pen/VraKrr) <a href="https://codepen.io/Rplus/pen/VraKrr"> <video autoplay muted controls playsinline loop src="https://giant.gfycat.com/ParallelFragrantIceblueredtopzebra.webm"></video> </a> note: 公司實際使用:大多仍然是色票、系統 UI 尺寸 特殊情境:九宮格調整順序 比較常見的解法應該是搭配有 virtual DOM framework,直接操作 data array 的順序 那 framework 會自己去異動 DOM 的順序 但其實也可以使用 CSS variables 來處理 在移動過程中,我們其實不太需要操作真正的資料的順序 --- ### CSS `order` solution ![](https://i.imgur.com/dtEYdIX.png) source: https://www.w3.org/TR/css-flexbox-1/#propdef-order note: 先講一下這個處理方案的主要依據是 CSS 的 `order` 屬性, `order` 目前可以使用在 flexbox & grid system 裡,專門負責 item 的排版順序 painting order 只能吃整數值,初始值為 `0`,可以餵進 keyframes 裡 <3 --- ![](https://i.imgur.com/4p8vdbu.png) ![](https://i.imgur.com/o3oiInD.png) note: 想法是讓 初始順序 變成 目標順序, 並再加**修正量**以便排在**目標位置** 這邊的修正量是直接取半格,也就是 `5` 實際使用上跟取 `1` 沒什麼不同,只是在四則運算的算式有些些不同而已 而正確的目標位置還另外需要移動方向來判斷 往前移動的話,order 應該要比該位置的更小、往後的話應該要更大 那這移動原理基本上就是這樣的設計 --- ```js // init tiles.forEach((tile, index) => { well.style.setProperty(`--order-${index}`, index * BASE_NUMBER); tile.style.order = `var(--order-${index})`; }); // in key events targetIndex = (targetIndex + operator + 9) % 9; let dir = originIndex > targetIndex ? -1 : 1; well.style.setProperty( `--order-${originIndex}`, (targetIndex + .5 * dir) * BASE_NUMBER ); ``` note: 在第一步驟先初始化所有的 order,並讓各方塊都吃到這個 order CSS variables 在收到 key event 時,計算一下該 **移動到哪一格** 去、還有 **移動方向** 那最終要輸出的就是: 目標 order 再加上方向的修正量 (這邊就看前面修正量是怎麼定的 --- <h3 class="ref">Reference:</h3> * [CSS Custom Properties for Cascading Variables Module Level 1](https://www.w3.org/TR/css-variables-1/) * [CSS Variables: Why Should You Care?](https://developers.google.com/web/updates/2016/02/css-variables-why-should-you-care) * [CSS Custom Properties (CSS Variables) Sample](https://googlechrome.github.io/samples/css-custom-properties/index.html) * [Using CSS custom properties (variables) - CSS | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables) * [It’s Time To Start Using CSS Custom Properties](https://www.smashingmagazine.com/2017/04/start-using-css-custom-properties/) * [CSS Variables — No, really!](https://medium.com/dev-channel/css-variables-no-really-76f8c91bd34e) 👍 ----- * [Google: CSS variables](https://www.google.com.tw/search?q=css+variables) * [Twitter: CSS variables](https://twitter.com/search?q=css+variables) note: 「CSS Variables — No, really」這篇挺讚的,CSS variables 的常見誤解跟基本用法都講得挺清楚的~ <3 --- ### 工商 <ul class="hihihi"> <li><a href="https://fb.me/rplus.tw">https://fb.me/rplus.tw</a></li> <li><a href="https://twitter.com/RplusTW">https://twitter.com/RplusTW</a></li> <li><a href="https://codepen.io/Rplus/">https://codepen.io/Rplus/</a></li> <li><a href="https://www.facebook.com/HappyCSSer/">https://www.facebook.com/HappyCSSer/</a></li> </ul> <style> .reveal .hihihi { display: flex; margin: 0; padding: 0; list-style: none; } .reveal .hihihi li { width: 25%; margin: 0; padding: 0; } .reveal .hihihi li a { display: block; height: 20vh; color: transparent; background-size: cover; background-repeat: no-repeat; } .reveal .hihihi li:nth-of-type(1) a { background-image: url('https://lh3.googleusercontent.com/VZFTn0SFPQ-aVSbryzbEljt2ElbQJarDQ7PIY_0hLw2Ff2poTDb6LIxIsi6wU96HLKu6pisX1pXymRFL9DcrXIxna49RLA37YqBxigYuffVn4fyF_SMqcktYAg3A-Weh9oqQ1sez_w=w933-h679-no'); background-position: 0% 0%; background-size: auto 120%; } .reveal .hihihi li:nth-of-type(2) a { background-image: url('https://lh3.googleusercontent.com/x1FeYnrvZ_6MhsNNDU6fF2DQHcZULLP1DsY7J9aiK-J7P2_F48ylwaWw0kn_wWx560IAnN_-L6g2m6tzXVpHgzb40hoKFdSm42pVA6yU9Oyml4mYPcOURLvNmXSt3Qm5tVhKfdvlKA=w697-h403-no'); } .reveal .hihihi li:nth-of-type(3) a { background-image: url('https://lh3.googleusercontent.com/fzVpqBEsiPSRCXRgCNo1NnEm76dOhaxX36ojCKut2UV9wXecU-RbO9IjwmM1-sBqs_WjWmss-yuLSXIFWR2YvBFS5wT7tzwnZJsWGL9_I7kvyZpLheouAkYvgEsynP9Di9j8ppJ-lQ=w652-h421-no'); background-size: contain; } .reveal .hihihi li:nth-of-type(4) a { background-image: url('https://lh3.googleusercontent.com/Djl4n7BAATDe1m_4AsUDW3LWHYA9mFfTiyWQg5pFpWNdZkxUje1QsGvCzjQBbWLm485Nli0_NaPEjJyY78Aqec63VyGKiBApvMkMJxkoX5TrZn73t2OVza9QCj5YZyh0O8owwqs6Dg=w886-h654-no'); } </style> ----- * https://www.facebook.com/groups/f2e.tw/ * https://gitter.im/f2etw/developers * https://www.facebook.com/groups/F2ETW.share.HQ/ <style> .container { overflow: hidden; } .present .intro.intro { text-align: right; position: fixed; bottom: 0; right: -2% } .intro.intro a { color: inherit; font-size: smaller; } .intro.intro img { border: unset; vertical-align: middle; margin: 0 0 0 auto; display: block; } .reveal mark { background-color: rgba(255,255,150, .3); } .reveal blockquote { width: 90%; } .reveal pre code { max-height: 90vh; } .reveal .ref + ul li, .reveal .ref + ul a { font-size: smaller; } </style> --- 感謝 ♥ ---- ### 試試身手? https://codepen.io/Rplus/pen/LONgoq

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully