Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tocas 全新設計的響應式系統:Responsive 與 Container Query #894

Closed
YamiOdymel opened this issue Feb 5, 2023 · 0 comments
Closed
Assignees
Labels
✨ 功能追加 基於某個元件而追加的新樣式或是功能。 🎨 CSS 與 CSS 和外觀設計上有關聯。 💡 改進提案 討論的是基於目前元件所做出的變更,令某個功能或樣式更好(而不是追加新功能)。 💣 大型異動 這個請求是大型異動,甚至有可能重寫部份程式碼而不是單純小修改追加功能。 📜 JavaScript 這件事情和模組、JavaScript 程式碼有關聯 🔄 規則變更 這個提案是更改目前的使用方法、規則,有可能導致無法相容前一個版本的用法(但並非大型破壞與重構)。
Milestone

Comments

@YamiOdymel
Copy link
Member

YamiOdymel commented Feb 5, 2023

前言

基本上就是目前的 minimal, standard, maximal 的斷點太難使用,而且多數情況下可能也會想要依據不同斷點來增加、減少某些容器的內距,但目前都沒有辦法做到。目前問題大略有這些:

有關未來的 CSS Container Style Queries

題外話,這是一個可以透過父容器的 CSS Variable 來決定怎麼渲染 CSS Style 的 Query,由於 CSS Container Style Queries 還沒生效,所以目前使用 Tocas 的時候,不能依照我們的期許自訂某個 Tocas 元件欄位的功能。

延伸閱讀

Tailwind CSS v3.2: Dynamic breakpoints, multi-config, and container queries, oh my!
Mobile-First CSS: Is It Time for a Rethink?

基本語法

某個斷點

要指定單獨在某個斷點生效,使用 breakpoint 不包含其他符號。

<!-- mobile -->
<div class="ts-header mobile:is-large"></div>

某個斷點…和以上

要指定從某個斷點以上開始生效,使用 breakpoint+ 加號。

<!-- mobile, tablet, desktop, widescreen -->
<div class="ts-header mobile+:is-large"></div>

<!-- tablet, desktop, widescreen -->
<div class="ts-header tablet+:is-large"></div>

某個斷點…和以下

要指定從某個斷點以下開始生效,使用 breakpoint- 減號。

<!-- desktop, tablet, mobile -->
<div class="ts-header desktop-:is-large"></div>

某個斷點到…某個斷點

要指定從某個斷點某個斷點之間才生效,使用 breakpoint-breakpoint 減號。

<!-- ❌ 沒有 reset 功能 -->
<div class="ts-header tablet+:is-large widescreen:reset-is-large??"></div>

<!-- ⭕指定 tablet-desktop 只在 tablet, desktop 之間生效 -->
<div class="ts-header tablet-desktop:is-large"></div>

臨時斷點

可以手動指派想要的斷點來符合臨時需求,使用 [px]+, [px]-[px-px]

<!-- >= 100px -->
<div class="ts-header [100px]+:is-large"></div>
<!-- <= 100px -->
<div class="ts-header [100px]-:is-large"></div>
<!-- 10px ~ 30px -->
<div class="ts-header [10px-30px]:is-large"></div>

兩者使用時須注意。

<!-- <= 99px 會套用 is-small,>= 100px 會套用 is-large -->
<div class="ts-text [99px]-:is-small [100px]+:is-large"></div>

實作方式

目前的實作方式可能使用 JavaScript 的 MutationObserverResizeObserver 來監聽並 Toggle 指定元素的 CSS Class。例如 tablet-:is-large 會在裝置的寬度小於 1024px 的時候,自動加上 is-large;如果裝置寬度大於 1024px 則移除 is-large

不使用 CSS Media Query,是因為有太多斷點要處理了,而且每個斷點都要把那些 .ts-content, .ts-grid 全部的 Class 拉進來,每個檔案都只是相互複製但 Class Name 改一下而已,實在是太沒效率。

image

主要在思考 JavaScript 切換 Class 這種方式到底可不可靠。

JavaScript 控制 Class 的話沒有優先順序可言。

CSS Media Query 很方便,因為那個斷點的 Class 一定被擺在優先順位,會覆寫上一個斷點的樣式。但如果透過 JavaScript 的話,就必須移除相關的樣式,例如:is-large 不能與 is-small 同時出現,所以使用者一定要自己定義不重複的斷點樣式。

效能問題

  1. 監聽 windowonresize 事件
  2. 透過 MutationObserver 監聽每個 DOM 產生還有 class="" 變更的時機
  3. 監聽每個 @container 容器的寬度變更時機

目前不確定是否有效能上的疑慮。

自訂斷點

JavaScript 會透過 getComputedStyle 來搜尋目前元素繼承的 --ts-breakpoint-x-min--ts-breakpoint-x-max。舉例來說:

<!-- 尋找 --ts-breakpoint-mobile-min 與 --ts-breakpoint-mobile-max -->
<div class="ts-header mobile:is-large"></div>

所以使用者可以透過 CSS 自訂斷點:

html {
    --ts-breakpoint-mobile-min: 0px;
    --ts-breakpoint-mobile-max: 767px;
}

.my-element {
    --ts-breakpoint-laptop-min: 1024px;
    --ts-breakpoint-laptop-max: 1365px;
}

Container Query 支援

預設的語法都會透過判斷 window.innerWidth,但可以透過 @breakpoint 達到類似 CSS 的 Container Query 效果。這個時候 JavaScript 會搜尋最鄰近的 @container 作為判斷依據而不是 window

範例

假設 desktop 斷點的定義是 1024px,但因為在前面加上了 @ 符號,就會往上搜尋最近的 @container,如果該 @containerwidth >= 1024px 的話則 is-large 就會生效。

<div class="@container">
    <div class="ts-header @desktop+:is-large"></div>
</div>

當然也可以使用 - 來指定 @container 容器在某個寬度以下的時候生效。

<div class="@container">
    <div class="ts-header @tablet-:is-negative">這段文字在 Tablet 與 Mobile 的時候呈現負面紅色。</div>
    <div class="ts-header @mobile:is-negative">這段文字在 Mobile 的時候呈現負面紅色。</div>
</div>

然後當然也可以設定臨時斷點。

<div class="@container">
    <div class="ts-header @[100px]+:is-negative">大於或等於 100px 的時候呈現負面紅色。</div>
</div>

幾個使用誤解

Tocas 不是 Mobile First,樣式不會往上疊加

定義 Grid 的寬度時,使用者可能會誤以為定義最小的 mobile,就會後續影響到 tablet, desktop, widescreen 自動套用 is-4。但實際上應該要在後面補一個 + 加號。

<div class="ts-grid">
    <!-- mobile is-4, tablet is-8, desktop 0, widescreen 0 -->
    <div class="column mobile:is-4 tablet:is-8"></div>
    
    <!-- mobile is-4, tablet is-8, desktop is-8, widescreen is-8 -->
    <div class="column mobile:is-4 tablet+:is-8"></div>
</div>

為什麼 breakpoint+>= breakpoint 而不是 > breakpoint

有時候可能會有人誤會 tablet+ 實際上是大於 tablet,而忘記 tablet 本身也算進去。以上面 Grid 的範例來說:

<div class="ts-grid">
    <!-- 兩個 mobile 可能會令人混淆 -->
    <div class="column mobile:is-4 mobile+:is-8"></div>
    
    <!-- tablet+ 看起來比較合適 -->
    <div class="column mobile:is-4 tablet+:is-8"></div>
</div>

如何定義顯示和隱藏

由於 Tocas 沒有專門在某個斷點 reset 樣式的功能,所以想要單獨在某個斷點顯示元素,可以結合不同條件:

<!-- 在 Mobile 時隱藏 -->
<div class="ts-segment mobile:is-hidden"></div>

<!-- 在 Mobile, Tablet 時隱藏;等效於在 Desktop, Widescreen 時顯示  -->
<div class="ts-segment tablet-:is-hidden"></div>

<!-- 在 Mobile, Tablet, Widescreen 時隱藏;等效於只在 Desktop 時顯示  -->
<div class="ts-segment tablet-:is-hidden widescreen:is-hidden"></div>
@YamiOdymel YamiOdymel added 💡 改進提案 討論的是基於目前元件所做出的變更,令某個功能或樣式更好(而不是追加新功能)。 📜 JavaScript 這件事情和模組、JavaScript 程式碼有關聯 💣 大型異動 這個請求是大型異動,甚至有可能重寫部份程式碼而不是單純小修改追加功能。 🎨 CSS 與 CSS 和外觀設計上有關聯。 🔄 規則變更 這個提案是更改目前的使用方法、規則,有可能導致無法相容前一個版本的用法(但並非大型破壞與重構)。 ✨ 功能追加 基於某個元件而追加的新樣式或是功能。 labels Feb 5, 2023
@YamiOdymel YamiOdymel added this to the Tocas 4.2.0 milestone Feb 5, 2023
@YamiOdymel YamiOdymel self-assigned this Feb 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ 功能追加 基於某個元件而追加的新樣式或是功能。 🎨 CSS 與 CSS 和外觀設計上有關聯。 💡 改進提案 討論的是基於目前元件所做出的變更,令某個功能或樣式更好(而不是追加新功能)。 💣 大型異動 這個請求是大型異動,甚至有可能重寫部份程式碼而不是單純小修改追加功能。 📜 JavaScript 這件事情和模組、JavaScript 程式碼有關聯 🔄 規則變更 這個提案是更改目前的使用方法、規則,有可能導致無法相容前一個版本的用法(但並非大型破壞與重構)。
Projects
None yet
Development

No branches or pull requests

1 participant