最近在写自己的一个博客项目, 其中使用到了 tailwind
作为css框架, 关于 tailwind
的介绍可以参考我的另一篇文章:
2021年, 是时候来尝试 Tailwind 框架编写 CSS 了 https://juejin.cn/post/6935725712737304613
但是如何在我们的代码中更好的组织 tailwind
样式? 如何发挥它的优势, 避开它的劣势?
这就是我们这篇文章的主题。
对比几种编程方式
1. 传统 HTML 代码
传统开发中, style
单独为一个标签 或 其他引入外部样式表, 在 Html
标签中通过 class
属性引入对应类。
<head>
<style>
.classA {
color: #000;
}
</style>
</head>
<body>
<span class="classA">Hello World!</span>
</body>
不足:
- 重复利用相同的属性, 代码冗余大。
- 过于分散的类, 难以进行良好管理, 简单说起名字很头疼, 并且名不对意也是一种常见情况。
- 存在重名的情况, 没有命名空间。
2. CSS in JS
随着模块化思想的出现, 样式嵌套在组件模块中。
当然在 React
中 style
, 常常包含在组件的一个对象内进行编写, 这也是著名的 CSS in JS
。
我们通过组件 style
属性引入样式对象:
const style = {
'color': 'red',
'fontSize': '46px'
};
const clickHandler = () => alert('hi');
ReactDOM.render(
<h1 style={style} onclick={clickHandler}>
Hello, world!
</h1>,
document.getElementById('example')
);
现代主流打包工具的 CSS
已经支持 CSS Module
, 我们通过引入外部样式也可达到模块样式的目的。
注意, 模块化CSS 返回类名映射作为键的对象
import style from './style.css'
const clickHandler = () => alert('hi');
ReactDOM.render(
<h1 className={style.AclassName} onclick={clickHandler}>
Hello, world!
</h1>,
document.getElementById('example')
);
优点:
-
模块化样式, 命名不会冲突, 存在各自的命名空间
实际上通过给模块中的样式类名添加哈希后缀来避免重复。
-
代码组织相对良好
不足:
- 与传统编码类似, 同样的
CSS
代码仍需编写在各类中 - 代码冗余
3. 原子类: Tailwind 官方给出的案例
这是官方给出的 tailwind
重写上方实例
![]
这其实有点类似传统编写原子类, 不同的是这些功能类, 有一些是原子类的组合, 比如:
.bg-white {
--tw-bg-opacity: 1;
background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
}
实际上, 原子类这种编写方式早期常被诟病
- 没有良好的代码组织, 太多类杂糅在一起, 难以进行调试
- 同样的样式虽然进行了简写, 但是仍需要在多个元素标签中编写, 存在冗余
tailwind
本身的类优先级较低, 如果我们项目中用了其他的组件框架, 难以进行样式覆盖
我是怎么在 React 中进行 tailwind 样式编写的
-
首先我选择结合模块化的方式对代码进行组织, 不同的是, 这里我们用
className
进行样式引入:const classMap = { chatNotification: "p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4", chatNotificationLogoWrapper: "flex-shrink-0", chatNotificationLogo: "h-12 w-12" <div className={classMap.chatNotification}> <div className={classMap.chatNotificationLogoWrapper}> <img className={classMap.chatNotificationLogo} src="/img/logo.svg" > </div> </div>
这样一方面组织了代码样式, 另一方面提高了同类型元素样式的复用性。
-
使用模板字符串进行样式拓展
如果说现有无法满足条件, 需要在
classMap
的基础上进行拓展, 我们可以使用模板字符串。举个栗子:
<img class={`${classMap.chatNotificationLogo} h-14 w-14`} src="/img/logo.svg" >
这样来达到覆盖
tailwind
样式的目的。 -
覆盖组件框架的默认样式
如果需要覆盖例如
antd
这类组件库的默认样式, 单凭原子类的优先级肯定是不够的, 我们就需要引入外部样式进行重写。这里可以利用
@apply
在外部样式表中编写tailwind
文件:.menu li { @apply text-base; }
为了防止命名空间冲突, 请记得在打包工具中开启
CSS Module
:import styles from './style.css' const classMap = { menu: "flex flex-col justify-start items-center" } // 记住, 模块化CSS 是返回类名对象 <Menu className={`${classMap.menu} ${styles.menu}`} />
注意! 外部样式表中使用 @apply 只是将样式引入样式表, 仍会存在代码冗余
所以如果可以, 还是请将样式写到
classMap
对象中, 在className
中进行引用。 -
扩展 tailwind 样式
其实这一部分就类似 第三点, 针对
hover
, 动效transform
,tailwind
没办法精细化地生成类, 毕竟每个动画需求都不同。这时候就可以通过外部样式表来进行补充, 编写适配地样式。
总结
- 使用模块化保存类名列表, 进行代码组织
- 减少在外部样式中使用
@apply
- 使用模板字符串拼接类名列表。
- 通过外部引用样式表来进行覆盖 组件库样式, 提高优先级, 或扩展功能。
以上就是我对于在 react
中利用 tailwind
编写 css
代码的见解, 希望对你有帮助。
参考文章
CSS Module 阮一峰 www.ruanyifeng.com/blog/2017/0…
tailwind 官方文档 tailwindcss.com/docs/utilit…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!