Tailwind CSS 为开发创造了奇迹——它可以让您在几分钟内启动并运行。它包含开箱即用的正确构建块,以及用于自定义整个系统中几乎所有内容的选项。
如果您从未从头构建过设计系统,那么很容易将Tailwind CSS之类的东西视为理所当然,尤其是在设置字体比例、间距网格和颜色时(Tailwind 真正的亮点)。Tailwind 的世界级设计师在选择合适的色调和色调时一丝不苟,能够让几乎任何东西看起来都很棒。
有时,您可能会获得带有品牌颜色的设计,您可以在 Tailwind 中进行扩展,或者在您预先知道这些值时使用您想要的任何颜色覆盖默认颜色。
但是,当您无法控制最终出现在用户浏览器中的确切颜色时会发生什么?如果颜色来自后端或者是动态的并通过用户输入控制怎么办?您是否重新使用内联样式?或者也许为 Tailwind 之外的那些用例生成单独的 CSS 样式?
我希望不是!我在这里向您展示了一种更好的方法,一种与 Tailwind 工作方式一致的解决方案,其可扩展的 API 允许我们将其推向更远的距离,而不是我们开箱即用的默认设置。
我将展示我是如何使用我构建的名为 NodCards 的小型 SaaS 产品解决实际用例的。这个概念很简单——它是你的数字名片。使用 NodCards,您的详细信息可以显示在个人登录页面上、在您的电子邮件签名中共享、社交媒体上的生物链接或您想共享信息的任何其他地方。
NodCards 就是一个很好的例子,因为用户可以选择任何颜色作为主要设计颜色,这需要 NodCards 动态适应。我开始使用 Tailwind CSS 进行样式设置,那么我是怎么做到的呢?
考虑到这种情况,并了解 Tailwind 类的工作原理,我们希望将文本颜色作为人名的目标,以及按钮的背景颜色,并且可能更多地用于悬停效果。text-{primary}
bg-{primary}
您的第一个想法可能是,感谢 即时 (JIT) 编译器,它可以动态组合样式,如. 但我会争辩说,它不是我们必须在这里做的事情的真正竞争者,因为你很快就会明白为什么。bg-[#6231af]
我有一些注意事项和要求来使这项工作适用于我的用例:
如何在无需更改标记(CSS 类)的情况下应用动态颜色?我可能会让成千上万的用户想要不同的颜色,所以这不应该在标记或样式表中增加任何开销,因为它可以扩展
如何创建单一原色的各种色调?
如何确定在动态原色之上显示的最佳可访问颜色?
基于这些标准,我整理了一个简短的项目演示。为了帮助可视化,我通过添加一个颜色选择器来模拟 UI 中颜色的动态变化,使演示具有交互性。如您所见,它会立即更改,而不会影响样式表和/或标记。
让我们看看我们是如何实现这一目标的。
我发现最好的方法是利用 CSS 变量的力量。同样的方法可以适用于任何语言或框架。在我的示例中,我使用 React 将其构建为 Next.js 站点,但这些概念是可转移的。这是完整的源代码。
大多数时候,我们会从后端获得十六进制颜色。在这种情况下,我编写了一个快速帮助函数来帮助将我们的十六进制颜色从后端转换为正确的 RGB 格式。
我们需要的第二个效用函数是一种方法来获得高对比度的可访问颜色(根据WCAG 指南)以显示在动态原色之上。我创建了一个实用程序文件来集中我们以后可以使用的辅助函数:
// 实用程序/index.js///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// _ ////////////////////////////////////// export const getRGBColor = (十六进制,类型)=> {让颜色=十六进制。replace ( /#/ g , "" ) // rgb 值var r = parseInt ( color . substr ( 0 , 2 ), 16 ) var g = parseInt ( color . substr ( 2 , 2 ), 16 ) var b = parseInt ( color . substr ( 4 , 2 ), 16 ) return `--颜色- $ { type } : $ { r } , $ { g } , $ { b } ;` } ///////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// _ _ ////////////////////////////////////// export const getAccessibleColor = (十六进制)=> {让颜色=十六进制。replace ( /#/ g , "" ) // rgb 值var r = parseInt ( color . substr ( 0 , 2 ), 16 ) var g = parseInt(color.substr(2, 2), 16) var b = parseInt(color.substr(4, 2), 16) var yiq = (r * 299 + g * 587 + b * 114) / 1000 return yiq >= 128 ? "#000000" : "#FFFFFF"}
该getAccessibleColor
函数通过将 RGB 颜色空间转换为YIQ来工作,如计算颜色对比度中所述。对于我们的用例,我们需要一种可靠的方法让文本颜色在我们的原色之上。
借助我们的辅助函数,我们将后端的动态原色转换为可在 CSS 变量中使用的 RGB 格式。然后我们得到a11y
(可访问性)颜色。
我构建了我的函数来接收我声明的颜色类型的第二个参数。这允许我将函数重用于我想要声明的任何 CSS 变量组合。在混合中添加次要颜色、重音颜色或任何其他颜色将遵循完全相同的逻辑。
将格式更改为 RGB 是至关重要的一步。我们需要这些 RGB 格式的颜色的主要原因是,当我们通过 Tailwind CSS 组合新颜色时,我们可以为 RGBA 颜色添加一个 alpha 层。这确保了所有和类都可以工作,并且我们也可以通过使用不透明层来获得动态颜色的各种阴影。bg-opacity
text-opacity
使用我们primaryColor
的a11yColor
RGB 格式,我们需要声明一个 CSS 变量,其范围为 HTML 文档的根。添加它意味着我们可以在 DOM 中使用 CSS 类的任何地方访问它。:root
// pages/index.js const primaryColor = getRGBColor ( "#6231af" , "primary" ) const a11yColor = getRGBColor ( getAccessibleColor ( "#6231af" ), "a11y" ) <!-- ... --> <! -- ... --> < Head > < style > : root {`{ $ { primaryColor } $ { a11yColor }}`} </ style > </ 头>
目前,我们只是将其硬编码为#6231af
,但以后很容易将其替换为任何动态颜色的单个入口点。
Tailwind CSS 中的任何颜色都是通过立即在该类中声明实用程序来声明的。然后将声明的任何颜色转换为 RGBA 值,并在其中使用该值,如为 Alpha 通道声明的那样。--tw-bg-opacity: 1;
--tw-bg-opacity
如果您只声明一种颜色,该颜色将是纯色,但当我们声明 时,Tailwind CSS 会重新声明该 alpha 通道,使我们能够使用动态颜色实现各种级别的不透明度。bg-opacity-{value}
这实际上是 Tailwind CSS 的人非常聪明的,因为没有办法在 CSS 中声明或使用纯文本或仅背景的不透明度。实现这一点的唯一方法是使用 RGBA 中的 Alpha 通道,并且通过遵循他们布置的模式,我们正在利用他们颜色系统的全部潜力。
此时,我们在 HTML 中声明了一个 CSS 变量(可以连接到我们的后端)。下一步是将 CSS 变量链接到一些 Tailwind CSS 类以使用。
为了实现这一点,我们必须专注于文件,这是所有魔法发生的地方。Tailwind 允许我们将颜色指定为函数而不是字符串,以访问内部 Tailwind 不透明度实用程序。这是我们将多次使用的东西,因此最好将其提取到我们顶部的可重用函数中:tailwind.config.js
tailwind.config.js
// tailwind.config.js函数withOpacity ( variableName ) { return ( { opacityValue } ) => { if ( opacityValue !== undefined ) { return ` rgba ( var ( $ { variableName } ), $ { opacityValue } )` }返回` rgb (var ($ {变量名}))` } }
首先,我们从 Tailwind 接收颜色的不透明度值,我们可以将其与 RGB 格式的颜色一起用作 Alpha 通道。因为这可能没有设置,我们执行一个快速检查:如果它是undefined
,我们返回它而不带任何 alpha。
在这两种情况下,我们只需将 CSS 变量的值分配给rgb
这种格式的 。现在可以在组合颜色时使用它了。
接下来,我们通过扩展主题来设置新颜色:
// tailwind.config.js主题:{ extend:{ textColor:{ skin:{ primary:withOpacity (“--color-primary”),a11y:withOpacity (“--color-a11y”),},},backgroundColor : { skin : { primary : withOpacity ( "--color-primary" ), a11y : withOpacity ( "--color-a11y" ), }, }, ringColor : { skin : { primary : withOpacity ( "--color-primary" ), }, }, borderColor : { skin : { primary : withOpacity ( "--color-primary" ), a11y : withOpacity ( "--color -a11y" ), }, }, }, },
我喜欢用我自己的前缀关键字嵌套这些实用程序,skin
. 这是可选的,但在您输入类时它会派上用场,尤其是当您使用带有IntelliSense的Tailwind VSCode扩展时,它会拾取并显示您的所有新类。
textColor
我们按计划使用和扩展我们的主题,并backgroundColor
添加ringColor
和borderColor
变体,以便我们在这些实用程序上也可以使用我们的动态自定义颜色。
有了这个,Tailwind 可以为我们生成一堆新的类。我们可以开始在我们的标记中使用这些新类中的任何一个。
现在,让我们将文本颜色更改为我们新的动态设置的原色。
< p className = "...text-skin-primary" >简·库珀< / p >
在按钮上,让我们将背景设置为不透明度为 30% 的主要背景,这允许我们使用主要文本颜色。然后,我们可以在悬停时使背景成为纯色,并为悬停时的图标切换到可访问性安全颜色。
我们还可以使用在我们的主要动态颜色中设置的边框颜色和对焦环颜色。
< a href ={链接. href } target = "_blank" className = "... bg-skin-primary bg-opacity-30 text-skin-primary hover:bg-opacity-100 hover:text-skin-a11y border-skin-primary focus:ring -skin-primary" > <链接。图标类名= “h-5 w-5” / > </a>
回顾我们的需求,我们能够在不更改标记的情况下动态设置原色,获得原色的不同色调,并在动态原色之上显示任何内容时保持良好的对比度。
你做过类似的事情吗?在下面的评论中告诉我!
LogRocket就像一个用于 Web 和移动应用程序的 DVR,记录您的 Web 应用程序或网站中发生的一切。无需猜测问题发生的原因,您可以汇总和报告关键前端性能指标、重放用户会话以及应用程序状态、记录网络请求并自动显示所有错误。
苹果天价头显Vision Pro首摔:碎成蜘蛛网 维修要5750元
2024-02-04Martial God Asura - Chapter 147 – Displaying His Abilities
2022-09-08