Skip to content

tailwindcss

setup

twMerge 使用

twMerge 可以解决样式合并冲突

clsx 支持样式多样多样判断,格式化

typescript
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
 return twMerge(clsx(inputs))
}


className={cn("base-class", isActive && "active", isDisabled && "disabled")} // 输出干净的结果: "base-class active disabled"

className={cn(
  'base',
  ['foo', 'bar'],
  { 'active': isActive },
  [{ 'disabled': isDisabled }]
  'bg-blue-500 text-white': isPrimary,
)}

cssrem vscode.plugin

插件

class="h-[375px]" => class="h-[50vw]"

json
// settings.json
{
    "cssrem.rootFontSize": 750,
    "cssrem.vw": true, // 启用 vw 计算单位
}
// keybindings.json
{
  // mac 设置 快捷键为 ctrl + q
  {
      "key": "alt+z",
      "command": "-extension.cssrem.rem-switch-px"
  },
  {
      "key": "alt+q",
      "command": "extension.cssrem.vw-switch-px"
  }
}

bg-linear

bg-linear-[25deg,red_5%,yellow_60%,lime_90%,teal]

bg-linear-(--my-gradient)

bg-gradient-to-r from-indigo-500 from-10% via-sky-500 via-30% to-emerald-500 to-90%

bg-[url(/logo.webp)]

colors

custom colors

css
@import "tailwindcss";

@theme {
  --color-midnight: #121063;
  --color-tahiti: #3ab7bf;
  --color-bermuda: #78dcca;
}

Now utilities like bg-midnight, text-tahiti, and fill-bermuda will be available in your project in addition to the default colors.

使用变量

css
@import "tailwindcss";

:root {
  --acme-canvas-color: oklch(0.967 0.003 264.542);
}
[data-theme="dark"] {
  --acme-canvas-color: oklch(0.21 0.034 264.665);
}
@theme inline {
  --color-canvas: var(--acme-canvas-color);
}

伪元素 Pseudo-elements

::before and ::after

html
<label>
    <span class="text-gray-700 after:ml-0.5 after:text-red-500 after:content-['*'] ...">Email</span>
    <input
        type="email"
        name="email"
        class="..."
        placeholder="[email protected]"
    />
</label>

placeholder

html
<input
    class="placeholder:italic placeholder:text-gray-500 ..."
    placeholder="Search for anything..."
    type="text"
    name="search"
/>

::file

html
<input
    type="file"
    class="file:mr-4 file:rounded-full file:border-0 file:bg-violet-50 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-violet-700 hover:file:bg-violet-100 dark:file:bg-violet-600 dark:file:text-violet-100 dark:hover:file:bg-violet-500 ..."
/>

::marker

html
<ul
    role="list"
    class="list-disc marker:text-sky-400 ..."
>
    <li>5 cups chopped Porcini mushrooms</li>
    <li>1/2 cup of olive oil</li>
    <li>3lb of celery</li>
</ul>

child selectors

直接选择 *,等同于 >*

class="*:rounded-full *:border *:border-sky-100"

间接选择 **

html
<ul class="**:data-avatar:size-12 **:data-avatar:rounded-full ...">
    <li>
        <img data-avatar />
        <span>avatar</span>
    </li>
</ul>

加上特定元素选择器

class="[&_p]:mt-4"

custom-css

@layer
scss
@layer base {
    h1 {
        font-size: var(--text-2xl);
    }
    h2 {
        font-size: var(--text-xl);
    }
}

@layer utilities {
    .flex {
        display: flex !important;
    }
}

@layer components {
    .scrollbar-none {
        &::-webkit-scrollbar {
            display: none;
        }
    }

    .scrollbar-styled {
        &::-webkit-scrollbar {
            width: 4px;
            height: 4px;
            border-radius: 20px;
            transition: all 3s ease;
            background-color: transparent;
        }

        &::-webkit-scrollbar-thumb {
            background-color: #cbd5e2;
            border-radius: 20px;
        }
    }
}
Arbitrary properties
html
<!-- 自定义 css 属性 -->
<div class="[--width: 100vw] w-(--width)"></div>

<!-- 自定义 tailwind 没有定义的 classname,并且可以配置使用 modifiers -->
<div class="[mask-type:luminance] sm:[mask-type:luminance]"></div>

<!-- 空行应该使用 _ 代替 -->
<div class="grid grid-cols-[1fr_500px_2fr]"></div>

<!-- 处理 ambiguities,颜色跟字体大小采用了相同的前缀 text-, 如果是变量的方式,应该标注对应的 css 数据类型,避免生成的时候出现混淆 -->
<div class="text-(length:--my-var)"></div>
<div class="text-(color:--my-var)"></div>
@variant

在自定义的 class 中使用 @variant

scss
.my-element {
  background: white;
  @variant dark {
    @variant hover {
      background: black;
    }
  }
}
// 编译后的结果
.my-element {
  background: white;
  @media (prefers-color-scheme: dark) {
    &:hover {
      @media (hover: hover) {
        background: black;
      }
    }
  }
}
utilities

增加自定义 utility(tailwind plugin 才会识别,并且支持 modifiers)

scss
@utility content-auto {
    content-visibility: auto;
}

@theme {
    --tag-color-mul: oklch(80.8% 0.114 19.571);
}

@utility tag-* {
    background-color: --value(--color- *);
    background-color: --value(--tag-color- *);
    --tw-shadow-color: color-mix(in oklab, --value(--color- *) 50%, transparent);
    --tw-shadow-color: color-mix(in oklab, --value(--tag-color- *) 50%, transparent);
    @apply float-end inline-flex -translate-y-[30%] transform select-none rounded px-1 py-0.5 text-[11px] font-bold tracking-tight text-white shadow-md;
}
// tag-red-300 tag-mul
Functional utilities
scss
@theme {
    --tab-size-2: 2;
    --tab-size-4: 4;
    --tab-size-github: 8;
}
@utility tab-* {
    tab-size: --value(--tab-size- *);
}

group

html
<a
    href="#"
    class="group rounded-lg p-8"
>
    <!-- This group-* syntax works with other variants too, like group-focus, group-active, and many more. -->
    <span class="group-hover:underline">Read more…</span>
</a>
<style>
@media (hover: hover) {
    a:hover span {
        text-decoration-line: underline;
    }
}
</style

具名 group

使用 group/{name} group-hover/{name}

html
<ul>
    <li class="group/item">
        <a class="group/edit invisible group-hover/item:visible ...">
            <span class="group-hover/edit:text-gray-700 ...">Call</span>
        </a>
    </li>
</ul>

任意 group

html
<div class="is-published group">
    <div class="hidden group-[.is-published]:block">Published</div>
</div>

peer

html
<p className="peer">peer</p>
<p className="peer-hover:text-2xl">next</p>

具名 peer

html
<p className="peer/color">color</p>
<p className="peer/size">size</p>
<p className="peer-hover/size:text-2xl peer-hover/color:text-amber-300">next</p>

Last updated: