智力活动是一种生活态度
2023 年 10 月 11 日
.md
一直听说“全栈项目 = Next.js + TailwindCSS + HeadlessUI” 但是 TailwindCSS 到底是啥,之前一直妹整明白
传统设计需要根据 html 中的结构,在 CSS 中给相应的元素/class/id 定义所需要的所有样式 style。
问题很明显:
<div/> 都要定义一个 class。TailwindCSS 的思路名叫 utility-first, 预先定义一批“性质-取值”的组合,每个组合给出一个有规律命名的类。使用时,一个 <div/> 后面声明几个甚至几十个不同的 class。缺点就是不灵活了,每个性质只搭配有限几种取值,且类的数量很多。好处是——
与之相对的另一种思路,是直接用 html 元素的 style 属性,或者用 module.css 让样式只对某一 component 生效。TailwindCSS 派对这种方法的批评是:
utility-first 在维护性方面收到批评的一点是,很多地方要不断重用相同的组合,少了一点封装和抽象。TailwindCSS 对此的辩护是,可以抽象出 components 和 partials(见下节),或者使用编辑器的多光标功能。(绷……)
在正常的类名字之前添加 <状态>: 标记,用来指明在相应状态时的样式。这些状态可以叠加,之间用 : 分隔。比如 <button class="hover:bg-sky-700">
可以标记的状态:https://tailwindcss.com/docs/hover-focus-and-other-states#appendix
hover:, focus:, active:first:, last:, odd:, even:required:, invalid:, disabled:: 主要用在 <form> 中group/<name>, 子元素的类名需要写在伪类的后面,有点反直觉 group-hover/<name>:group 的 class,然后给需要变化的子元素添加 group-<pseudo-class>: 前缀。如 group-hover:group-[.is-published]:, group-[:nth-of-type(3)_&]:peer class, 被跟踪的元素只能在跟踪元素的前面。::before, ::after, ::placeholder, and ::selection
before: 等等,默认相当于 before:content-['*']before:block, before:absolute, before:-inset-1 等等placeholder: 用于调整表格中代填内容的样式file: 上传文件按钮的样式list: 列表开头的selection: (鼠标)选中文字之后的样式first-line:, first-letter: 杂志常用的首行、首字母的特殊样式prefers-reduced-motion
md:, lg: 等前缀dark: 黑夜模式motion-reduce: 用户选择屏蔽动画效果时的样式,motion-safe: 只有不屏蔽动画才会生效的样式portrait,landscape 屏幕朝向print: 打印时的样式supports-[...] 当浏览器支持某种特性时启动。也可在 tailwind.config.js 文件中设置 theme.supports 变量[dir="rtl"] and [open]
aria-* modifier to conditionally style things based on ARIA attributes.data-[key=value] data 参数的值ltr: & rtl: 从右往左书写的文字open: & close: 用于可以展开的元素& 开头选择元素,下划线表示空格,如 [&:nth-child(3)]:, [&_p]:mt-4, [@supports(display:grid)]:grid| Breakpoint prefix | Minimum width | CSS |
|---|---|---|
| sm | 640px | @media (min-width: 640px) { … } |
| md | 768px | @media (min-width: 768px) { … } |
| lg | 1024px | @media (min-width: 1024px) { … } |
| xl | 1280px | @media (min-width: 1280px) { … } |
| 2xl | 1536px | @media (min-width: 1536px) { … } |
移动端优先的思路,所有尺寸限定的都是大于该宽度时的样式。
要限定上限,要用 max-<size>: 比如 md:max-xl:flex
要想自定义 breakpoints,可以看 customizing breakpoints documentation.
也可以单独设定 min-[320px]:, max-[600px]: 等等
默认使用操作系统的设定。
要想手动设定,须在 tailwind.config.js 中加入
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'class',
// ...
}
然后含有 class=’dark’ 的元素的子元素都时夜间模式的效果
这个链接包含了同时兼容系统设置和手动设置的做法
@apply and @layer in the Functions & Directives documentation.tailwind.config.js, 文档在此:https://tailwindcss.com/docs/themeplugins: {’postcss-import’: {},} 字段directives 是 CSS 文件中的 @ 开头的语句
@layer 用来把一些需要打包的样式绑在一起,后面三个取值:base, components, utilities
@apply 后面接 TailwindCSS 已经定义的类,表示把类的定义移植于此处。
@config 指定所在 CSS 文件需要使用的 TailwindCSS 配置文件,放在 @import 语句后面
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
h1 {
@apply text-2xl;
}
h2 {
@apply text-xl;
}
}
@layer components {
.btn-blue {
@apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
}
}
@layer utilities {
.filter-none {
filter: none;
}
.filter-grayscale {
filter: grayscale(100%);
}
}
TailwindCSS 还自定义了一些 CSS 函数:
theme(): 返回 config 文件中的参数,比如
.content-area {
height: calc(100vh - theme(spacing.12));
}
screen(): 以预定义的 breakpoint 为参数,避免代码中间出现硬编码的数值
@media screen(sm) { /* ... */ }
https://nextjs.org/docs/pages/building-your-application/styling/tailwind-css
在命令行
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
如此会在项目的根目录新建 tailwind.config.js & postcss.config.js 文件
然后编辑 tailwind.config.js 文件,添加需要用到 TailwaindCSS 的路径
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory.
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
}
在全局样式表 styles/globals.css 中引入 TailwaindCSS
@tailwind base;
@tailwind components;
@tailwind utilities;
在 pages/_app.js 中引入全局样式表。@ 的含义不明
// These styles apply to every route in the application
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
在项目的 components 中使用 TailwindCSS 的类:
export default function Page() {
return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1>
}