」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 將 Tailwind 配置為設計系統

將 Tailwind 配置為設計系統

發佈於2024-11-06
瀏覽:687

对于设计系统来说,一致性和理解性就是一切。一个好的设计系统通过实现它的代码的配置来确保实现的一致性。它需要是:

  • 易于理解,无需放弃良好设计所需的细微差别;
  • 可扩展和可维护,且不影响一致性。

使用我的 React 和 Tailwind 的默认堆栈,我将向您展示如何设置自己的版式、颜色和间距默认值,而不仅仅是区分应用程序外观和感觉的起点。更重要的是,它大大减少了我们必须编写和维护的代码,从而减少了以系统、一致和无错误的方式实现样式的精神负担。

我将从我经常看到的一个主要批评开始,然后分解我用来解决它的一系列配置步骤。

易于使用并不等于易于掌握知识

Tailwind 使开发人员可以轻松编写样式,这对于快速原型设计非常有用。但这种易用性并不能保证良好的设计或可扩展、可维护的设计系统。

像 Tailwind 这样的默认和零配置工具是基础设施速度层,可以为构建创造更多时间。但是,如果您要扩展一个使用设计系统来区分自己的应用程序,则不能仅仅依赖“像午餐一样免费”的开箱即用配置。

如果您使用默认的 Tailwind 配置运行并将样式管理推送到组件上的类应用程序,结果通常是一堆难以推理的类分布在组件中,伪装成设计系统。

Configuring Tailwind as a Design System

上面是一个很好的例子。它几乎难以辨认,需要大量时间才能理解,更不用说操纵了。尝试这样做很可能会导致重复和错误,从而逐渐偏离整个应用程序的设计一致性。

很容易将您的设计类合并到单个类名中。但这样做并不容易。

配置您的系统以方便了解

易用性需要权衡。使用别人的标准意味着依赖他们的专业知识。这可能是有益的,但也可能是一个陷阱。让我们退后一步,思考一下设计系统的基础知识包括哪些内容:

  • 排版
  • 颜色
  • 间距
  • 响应能力(包括颜色模式)

在 React with Tailwind 的上下文中,这些和许多其他设计系统元素都在 Tailwind 配置中设置,我们可以对其进行自定义。

{/* 更漂亮-忽略 */}

const config = {
  theme: {
    fontSize: { /* ... */ },
    colors: { /* ... */ },
    spacing: { /* ... */ },
  },
};

印刷默认值

您是否曾经努力记住小文本的正确字母间距?如果您可以设置一次然后忘记它怎么办?

我们可以直接在 tailwind.config 中将前导(行高)和跟踪(字母间距)设置为每个字体大小元组的参数。这意味着当我们使用字体大小类时,我们不需要设置行距或跟踪。无需记住(或无法查找)小文本的字母间距是多少。

fontSize: {
  small: [
    "13px",
    { lineHeight: 1.5, letterSpacing: "0.015em" },
  ],
  base: [
    "16px",
    { lineHeight: 1.5, letterSpacing: 0 },
  ],
}

现在使用 text-small 设置字体大小、行高和字母间距。将核心排版元组封装在一个类中,将这些值的实现集中到配置中,而不是跨代码库。可维护性的巨大胜利。

/* 13px/1.5 with 0.015em letter-spacing */

颜色默认值

我们可以使用 CSS 变量在 :root 和 html.dark 范围下设置响应颜色。这意味着我们编写和管理一个类,例如 bg-canvas,而不是两个类,例如 bg-gray-100 dark:bg-gray-800。

@import "@radix-ui/colors/gray.css";
@import "@radix-ui/colors/gray-dark.css";

:root {
  --color-gray-base: var(--gray-1);
  --color-gray-bg: var(--gray-3);
  --color-gray-line: var(--gray-4);
  --color-gray-border: var(--gray-5);
  --color-gray-solid: var(--gray-10);
  --color-gray-fill: var(--gray-12);
}

因为我在这里使用 Radix Colors,所以我不需要设置 .dark 范围,因为这已经为我完成了。如果您不喜欢基数颜色,您可以自定义它们、使用其他库或编写自己的库。

然后在Tailwind配置中设置CSS变量。

colors: {
  canvas: "var(--color-gray-base)",
  background: "var(--color-gray-bg)",
  line: "var(--color-gray-line)",
  border: "var(--color-gray-border)",
  solid: "var(--color-gray-solid)",
  fill: "var(--color-gray-fill-contrast)",
}

现在使用 bg-canvas 在浅色或深色模式下设置适当的颜色。在代码库中删除这种重复可以将颜色管理集中到我们的配置中,而不是将其分散到组件上的类的实现中。认知和可维护性的巨大胜利。

/* sets --gray-1 as #fcfcfc on :root or #111111 on html.dark */

语义命名

我提倡颜色和字体大小的语义名称,因为语义命名是一种将含义与使用联系起来的强制功能。这样做可以消除实现猜测工作并减少错误。

我见过无数的项目,其中不一致的gray-50、gray-100或gray-200都用于背景。通过定义一种名为背景的颜色可以轻松解决这个问题。

同样,当深色和浅色文本颜色称为填充和纯色时,更容易记住它们的名称。当它们被称为gray-900和gray-600时,它会更难,也更容易出错,因为你必须特别记住它不是gray-950和gray-500,或者gray-800和gray-700。

但是命名事物并就命名达成一致是很困难的。本着零配置的精神,我建议采用 Radix Color 的背景、边框、实体和填充范例。或者这个调色板语义。

一旦你在 tailwind.config 中设置了此项,Typescript 就会通过自动完成功能唤起你的记忆。

避免命名空间冲突

如果您要扩展 Tailwind 主题而不是编写自己的主题,请不要使用已经使用过的音阶键。您可能会无意中覆盖您需要使用的类。

您会注意到在前面的颜色配置示例中,我将 --color-gray-base var 设置为 canvas,而不是 base。如果我使用基础,那么使用此色阶作为文本颜色(文本基础)将与默认字体大小基础值发生冲突,该值也是文本基础。

这并不是自定义 Tailwind 配置的缺点,而是其主题命名的遗留问题:在 Tailwind 中设置字体大小或颜色类都使用 text-*.1

间距默认值

我们还可以使用CSS变量来设置间距。

:root {
  --height-nav: 80px;
  --height-tab: 54px;
  --space-inset: 20px;
  --container-text-px: 660px;
  --container-hero-px: 1000px;
}
spacing: {
  em: "1em", /* relate icon size to parent font-size */
  nav: "var(--height-nav)",
  inset: "var(--space-inset)",
  text: "var(--container-text)",
  hero: "var(--container-hero)",
}

有人可能会说这是过度设计。除了计算复杂的交互式布局(如粘性标题、滚动边距等)之外,这种预先配置工作使其在像素方面变得直接且无错误。

/* ... */

再次注意语义命名的使用使其易于记忆和使用。

增强您的 Tailwind 配置

我们现在已经在一个集中的地方以易于理解和维护的方式配置了版式、颜色和间距标记。而且我们不需要编写那么多的类来实现系统。获胜。我们可以采取进一步的措施来减少这种实现开销。

Clamp() 你的类

如果我告诉你有一种方法可以完全避免到处写 text-lg lg:text-xl xl:text-2xl p-2 md:p-4 lg:p-8 呢?

我们可以通过在tailwind.config中使用clamp作为字体大小值来避免设置响应式字体大小类。这是我使用的简单钳位函数。

fontSize: {
  title: [
    /* clamp(17px, 14.1429px   0.5714vw, 21px) */
    generateClampSize(500, 1200, 17, 21),
    { lineHeight: 1.5, letterSpacing: "-0.015em" },
  ];
}

因此,我们可以只写 text-title,而不是写 text-lg lg:text-xl xl:text-2xl。再一次,通过将字体大小响应提升到钳位值,我们再次避免了“实现类”陷阱,节省了脑力劳动、错误和调试时间。

请记住,这意味着通过正确配置 Tailwind,我们已从 text-lg lg:text-xl xl:text-2xlleading-none Tracking-wide 转移到 text-title。赢了!

/* 17px at 500px, 21px at 1200, fluidly calculated inbetween */
/* …with default line-height and letter-spacing also specified */

Heading copy

我们也可以对间距执行此操作。扩展主题时,我在这些键前加上 d 作为“动态”前缀,以将其与默认间距比例区分开来。

spacing: {
  /* lower value is 2/3 of upper value */
  d4: generateClampSize(500, 1200, 10.5, 16),
  d8: generateClampSize(500, 1200, 21, 32),
  d16: generateClampSize(500, 1200, 43, 64),
  d24: generateClampSize(500, 1200, 64, 96),
  d64: generateClampSize(500, 1200, 171, 256),
}

这允许我们编写 py-d24 而不是 py-16 md:py-20 lg:py-24。这减轻了我们在脑海中为每个媒体查询保留一系列网站版本的负担。相反,它鼓励我们想象流畅响应的布局,其中测量并不像一致的关系那么重要。

/* ... */
/* ... */

概括

精心设计的 UI 是您抵御即将到来的粗心人工智能应用程序浪潮的最后一道防线。以下是自定义 Tailwind 如何节省您的时间和麻烦,以便您可以专注于构建眨眼间即可运行的 UI 所需的不合理的关注:

  • 充分利用 tailwind.config 的潜力。集中和分组您的设计令牌,避免“到处实现类”陷阱。
  • 使用clamp()进行流畅的排版和间距。
  • 在 :root 和 .dark 上设置颜色变量以轻松实现深色模式。
  • 从语义上命名颜色和间距:背景每天都会比灰色 100。
  • 使用 size-em 将图标与文本大小相关联。

是的,有前期时间成本。但它确实得到了回报:更少的代码、更少的错误、更高的设计一致性以及真正理解系统的团队。

接下来:我们将探索如何使用 Class Variance Authority 来创建一个防弹样式 API,其中包含从 Tailwind 中提取的语义属性。敬请关注。


  1. 这也是我不喜欢使用 tailwind-merge 删除 JSX 中重复的 Tailwind 类的原因。通常,我发现当两者都需要时,它会删除文本颜色以支持文本字体大小。我很惊讶更多的开发人员没有提出这个问题。 ↩

版本聲明 本文轉載於:https://dev.to/callumflack/configuring-tailwind-as-a-design-system-2f5h?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-04-27
  • 解決MySQL錯誤1153:數據包超出'max_allowed_packet'限制
    解決MySQL錯誤1153:數據包超出'max_allowed_packet'限制
    mysql錯誤1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的數據包,用於面對陰謀mysql錯誤1153,同時導入數據capase doft a Database dust?讓我們深入研究罪魁禍首並探索解決方案以糾正此問題。 理解錯誤此錯誤表明在導入過程中...
    程式設計 發佈於2025-04-27
  • Python中嵌套函數與閉包的區別是什麼
    Python中嵌套函數與閉包的區別是什麼
    嵌套函數與python 在python中的嵌套函數不被考慮閉合,因為它們不符合以下要求:不訪問局部範圍scliables to incling scliables在封裝範圍外執行範圍的局部範圍。 make_printer(msg): DEF打印機(): 打印(味精) ...
    程式設計 發佈於2025-04-27
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-04-27
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    在嘗試為JavaScript對象創建動態鍵時,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正確的方法採用方括號: jsobj ['key''i] ='example'1; 在JavaScript中,數組是一...
    程式設計 發佈於2025-04-27
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-04-27
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-04-27
  • 人臉檢測失敗原因及解決方案:Error -215
    人臉檢測失敗原因及解決方案:Error -215
    錯誤處理:解決“ error:( - 215)!empty()in Function openCv in Function MultSiscale中的“檢測”中的錯誤:在功能檢測中。”當Face Cascade分類器(即面部檢測至關重要的組件)未正確加載時,通常會出現此錯誤。 要解決此問題,必...
    程式設計 發佈於2025-04-27
  • 如何有效地轉換PHP中的時區?
    如何有效地轉換PHP中的時區?
    在PHP 利用dateTime對象和functions DateTime對象及其相應的功能別名為時區轉換提供方便的方法。例如: //定義用戶的時區 date_default_timezone_set('歐洲/倫敦'); //創建DateTime對象 $ dateTime = ne...
    程式設計 發佈於2025-04-27
  • 如何使用Java.net.urlConnection和Multipart/form-data編碼使用其他參數上傳文件?
    如何使用Java.net.urlConnection和Multipart/form-data編碼使用其他參數上傳文件?
    使用http request 上傳文件上傳到http server,同時也提交其他參數,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    程式設計 發佈於2025-04-27
  • 在PHP中如何高效檢測空數組?
    在PHP中如何高效檢測空數組?
    在PHP 中檢查一個空數組可以通過各種方法在PHP中確定一個空數組。如果需要驗證任何數組元素的存在,則PHP的鬆散鍵入允許對數組本身進行直接評估:一種更嚴格的方法涉及使用count()函數: if(count(count($ playerList)=== 0){ //列表為空。 } 對...
    程式設計 發佈於2025-04-27
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb sudo pip in...
    程式設計 發佈於2025-04-27
  • 在C#中如何高效重複字符串字符用於縮進?
    在C#中如何高效重複字符串字符用於縮進?
    在基於項目的深度下固定字符串時,重複一個字符串以進行凹痕,很方便有效地有一種有效的方法來返回字符串重複指定的次數的字符串。使用指定的次數。 constructor 這將返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.W...
    程式設計 發佈於2025-04-27
  • FastAPI自定義404頁面創建指南
    FastAPI自定義404頁面創建指南
    response = await call_next(request) if response.status_code == 404: return RedirectResponse("https://fastapi.tiangolo.com") else: ...
    程式設計 發佈於2025-04-27
  • 如何解決由於Android的內容安全策略而拒絕加載腳本... \”錯誤?
    如何解決由於Android的內容安全策略而拒絕加載腳本... \”錯誤?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    程式設計 發佈於2025-04-27

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3