组合使用Tailwind CSS框架
Tailwind CSS框架是一个功能类优先的CSS框架,可以支持开发人员通过组合其提供的大量样式类来完成样式的定义。Tailwind CSS在与Emotion结合使用的时候,如果采用Emotion的框架无关的使用方式,那么可以直接借助@emotion/css
提供的cx
函数来组合所需要的Tailwind CSS工具类。
但是如果应用项目采用的是与React固定搭配的形式,那么就需要借助一些其他的工具库来辅助一下了。要达到在应用项目中组合使用Tailwind CSS框架的目的,我们所需要的主要辅助工具库是twin.macro
。在应用项目中引入twin.macro
以后,还需要在项目中配置babel-plugin-macros
来支持twin.macro
的样式转换。
在项目中添加所有的相关支持,只需要运行以下命令。
npm install twin.macro tailwindcss -D
yarn add twin.macro tailwindcss -D
接下来就是对应用项目进行配置,首先需要配置babel-plugin-macros
使用Emotion。这个配置在package.json
中,需要添加一个名为babelMacros
的键。
{
"babelMacros": {
"twin": {
"preset": "emotion"
}
}
}
在配置好Tailwind CSS的配置文件tailwind.config.js
以后,就可以继续配置babel-plugin-macros
了。tailwind.config.js
文件可以使用以下命令生成。
npx tailwind init --full
以Vite为例,在vite.config.js
中需要编写以下内容来配置 babel-plugin-macros
。
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
react({
babel: {
plugins: [
'babel-plugin-macros',
[
'@emotion/babel-plugin-jsx-pragmatic',
{
export: 'jsx',
import: '__cssprop',
module: '@emotion/react'
}
],
['@babel/plugin-transform-react-jsx', { pragma: '__cssprop' }, 'twin.macro']
]
}
})
]
});
如果使用的是Create React App,那么CRA使用的Webpack会自动从 package.json
中加载babel-plugin-macros
的配置,所以也就不需要在添加其他的配置。
完成twin.macro
的配置以后,就可以仿照以下示例编写React组件了。
// 直接使用twin.macro提供的tw属性引入工具样式
import 'twin.macro';
const One = () => <div tw="text-blue-300 w-full">One</div>;
// 使用Style Components风格语法定义组件,注意此时不需要引入@emotion/styled。
import tw, { styled } from 'twin.macro';
const Four = tw.div`border border-solid border-blue-300 hover:border-black`;
const Five = tw(Four)`border-purple-500`;
// 还可以直接使用闭包函数来定义条件样式。
const StyledSix = styled.div(({ hasBorder }) => [
`color: black;`,
hasBorder && tw`border-purple-500 border-solid border rounded-sm`
]);
const Six = () => <StyledSix hasBorder>Six</StyledSix>;
// 使用字符串模板的形式也可以。
const StyledSeven = styled.div`
color: black;
${({ hasBorder }) => hasBorder && tw`border border-solid border-purple-500`}
`;
const Seven = () => <StyledSeven hasBorder>Seven</StyledSeven>;
// 或者还可以混用多种样式定义形式。
const StyledEight = styled.div`
${tw`text-sm`};
${({ hasBorder }) => hasBorder && tw`border-purple-500`};
${({ color }) =>
color &&
`
color: ${color};
`};
font-weight: 500;
`;
const Eight = () => (
<StyledEight hasBorder color="blue">
Eight
</StyledEight>
);
// 在结合Emotion使用的时候,Emotion的css函数是从twin.macro中引入的。
// twin.macro提供的tw字符串模板函数是用来解析工具样式的,不要与tw属性混淆了。
import tw, { css } from 'twin.macro';
const hoverStyles = css`
&:hover {
border-color: black;
${tw`text-black border-solid`}
}
`;
const Three = ({ hasHover, text = 'Three' }) => <div css={[tw`border`, hasHover && hoverStyles]}>{text}</div>;