tailwindcss 系列 - 基础

297 阅读5分钟

tailwindcss 会初始化样式,类似 reset.csssimple.css

初始样式

默认情况下,图像是 display: block

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block;
  vertical-align: middle;
}

图像和视频以保留其固有纵横比的方式被约束到父宽度

img,
video {
  max-width: 100%;
  height: auto;
}

border 默认添加一个 1px 实心边框

*,
::before,
::after {
  border-width: 0;
  border-style: solid;
  border-color: theme('borderColor.DEFAULT', currentColor);
}

修饰府

tailwind 会使用修饰符增强 css 功能,class 之前使用冒号表示

  • 伪类
  • 群组
  • 伪元素
  • 媒体查询
  • 属性选择器
  • 自定义修饰符

伪类

hover、focus、active

<button
  class="bg-violet-500 hover:bg-violet-600 active:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-300 ..."
>
  Save changes
</button>

first、last、odd、even

<ul role="list" class="divide-y divide-slate-200 p-6">
  <li v-for="person in people" class="flex py-4 first:pt-0 last:pb-0">
    <img class="h-10 w-10 rounded-full" :src="person.imageUrl" alt="" />
    <div class="ml-3 overflow-hidden">
      <p class="text-sm font-medium text-slate-900">{{ person.name }}</p>
      <p class="truncate text-sm text-slate-500">{{ person.email }}</p>
    </div>
  </li>
</ul>

表单状态

使用 required、invalid 和 disabled 等修饰符对不同状态的表单元素进行样式化

<div class="mx-auto max-w-sm bg-white px-6 py-5 shadow">
  <form>
    <div>
      <label for="username" class="block text-sm font-medium text-slate-700"
        >Username</label
      >
      <div class="mt-1">
        <input
          type="text"
          name="username"
          id="username"
          class="block w-full rounded-md border border-slate-300 bg-white px-3 py-2 placeholder-slate-400 shadow-sm invalid:border-pink-500 invalid:text-pink-600 focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:invalid:border-pink-500 focus:invalid:ring-pink-500 disabled:border-slate-200 disabled:bg-slate-50 disabled:text-slate-500 disabled:shadow-none sm:text-sm"
          value="tbone"
          disabled
        />
      </div>
    </div>
    <div class="mt-6">
      <label for="email" class="block text-sm font-medium text-slate-700"
        >Email</label
      >
      <div class="mt-1">
        <input
          type="email"
          name="email"
          id="email"
          class="block w-full rounded-md border border-slate-300 bg-white px-3 py-2 placeholder-slate-400 shadow-sm invalid:border-pink-500 invalid:text-pink-600 focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:invalid:border-pink-500 focus:invalid:ring-pink-500 disabled:border-slate-200 disabled:bg-slate-50 disabled:text-slate-500 disabled:shadow-none sm:text-sm"
          value="george@krugerindustrial."
          placeholder="you@example.com"
        />
      </div>
    </div>
    <div class="mt-6">
      <label for="password" class="block text-sm font-medium text-slate-700"
        >Password</label
      >
      <div class="mt-1">
        <input
          type="password"
          name="password"
          id="password"
          class="block w-full rounded-md border border-slate-300 bg-white px-3 py-2 placeholder-slate-400 shadow-sm invalid:border-pink-500 invalid:text-pink-600 focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:invalid:border-pink-500 focus:invalid:ring-pink-500 disabled:border-slate-200 disabled:bg-slate-50 disabled:text-slate-500 disabled:shadow-none sm:text-sm"
          value="Bosco"
        />
      </div>
    </div>
    <div class="mt-6 text-right">
      <button
        class="rounded-md bg-sky-500 px-5 py-2.5 text-sm font-semibold leading-5 text-white hover:bg-sky-700"
      >
        Save changes
      </button>
    </div>
  </form>
</div>

群组

根据父级、同级、子级元素改变样式

  • group 类标记父元素
    • group-focus
    • group-active
  • peer 类标记兄弟元素
    • peer-invalid
    • peer-focus
    • peer-required
    • peer-disabled

peer 标记只能用于以前的兄弟

  • 父级使用 * 标记子级元素
    • 子级自身不能覆盖
<a
  href="#"
  class="group block max-w-xs mx-auto rounded-lg p-6 bg-white ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500"
>
  <div class="flex items-center space-x-3">
    <svg
      class="h-6 w-6 stroke-sky-500 group-hover:stroke-white"
      fill="none"
      viewBox="0 0 24 24"
    >
      <!-- ... -->
    </svg>
    <h3 class="text-slate-900 group-hover:text-white text-sm font-semibold">
      New project
    </h3>
  </div>
  <p class="text-slate-500 group-hover:text-white text-sm">
    Create a new project from a variety of starting templates.
  </p>
</a>

has-* 修饰符可以根据元素子代的状态或内容设置元素的样式

<label
  class="has-[:checked]:bg-indigo-50 has-[:checked]:text-indigo-900 has-[:checked]:ring-indigo-200 .."
>
  <svg fill="currentColor">
    <!-- ... -->
  </svg>
  Google Pay
  <input type="radio" class="checked:border-indigo-500 ..." />
</label>

您可以将 has-* 与伪类(如 has-[:focus] )一起使用,以基于其后代的状态来设置元素的样式。您还可以使用元素选择器,如 has-[img] 或 has-[a] ,根据其后代的内容来设置元素的样式。

命名群组

  • 使用 group/{name} 类为该父组指定唯一的组名
    • group-hover/{name} 类将该名称包含在修饰符中
  • 使用 peer/{name} 类为特定对等体指定一个唯一的名称
    • peer-checked/{name} 类将该名称包含在修饰符中
<ul role="list">
  {#each people as person}
  <li class="group/item hover:bg-slate-100 ...">
    <img src="{person.imageUrl}" alt="" />
    <div>
      <a href="{person.url}">{person.name}</a>
      <p>{person.title}</p>
    </div>
    <a
      class="group/edit invisible hover:bg-slate-200 group-hover/item:visible ..."
      href="tel:{person.phone}"
    >
      <span class="group-hover/edit:text-gray-700 ...">Call</span>
      <svg
        class="group-hover/edit:translate-x-0.5 group-hover/edit:text-slate-500 ..."
      >
        <!-- ... -->
      </svg>
    </a>
  </li>
  {/each}
</ul>

任意群组

  • group-[选择器] 获取父级状态
  • peer-[选择器] 获取同级状态
<div class="group is-published">
  <div class="hidden group-[.is-published]:block">
    Published
  </div>
</div>

可以使用 & 字符来标记 .group 应该在最终选择器中相对于你传入的选择器的位置

<div class="group">
  <div class="group-[:nth-of-type(3)_&]:block">
    <!-- ... -->
  </div>
</div>

同级后代

如果你需要基于一个兄弟元素的后代来设计一个元素的样式,你可以用 peer 类来标记这个兄弟元素,然后使用 peer-has-* 修饰符来设计目标元素的样式。

<fieldset>
  <legend>Today</legend>

  <div>
    <label class="peer ...">
      <input type="checkbox" name="todo[1]" checked />
      Create a to do list
    </label>
    <svg class="peer-has-[:checked]:hidden ...">
      <!-- ... -->
    </svg>
  </div>

  <!-- ... -->
</fieldset>

伪元素

::before::afterplaceholderfirst-line 、first-letterbackdrop

  • 使用 file 修饰符在文件输入中设置按钮样式
  • 使用 marker 修饰符设置列表项目符号的样式, 可以在父元素上使用它
  • 使用 selection 修饰符设置高亮文本,可以在父元素上使用它

为文件输入按钮添加边框需要使用 file:border-solid 的类

媒体查询

响应断点

smmdlg

主题配色

css 属性 prefers-color-scheme 判断浅色主题还是深色主题

tailwind 使用 dark 修饰符编写深色主题样式

视口方向

portrait 和 landscape

兼容性

使用 supports-[...] 修饰符可以根据用户浏览器是否支持某个功能来设置样式。

属性选择器

data 属性

使用 data-* 修饰符可以根据数据属性有条件地应用样式

<!-- Will apply -->
<div data-size="large" class="data-[size=large]:p-8">
  <!-- ... -->
</div>

<!-- Will not apply -->
<div data-size="medium" class="data-[size=large]:p-8">
  <!-- ... -->
</div>
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    data: {
      checked: 'ui~="checked"',
    },
  },
}
<div data-ui="checked active" class="data-checked:underline">
  <!-- ... -->
</div>

打开/关闭状态

当 <details> 或 <dialog> 元素处于打开状态时,使用 open 修饰符有条件地添加样式:

<div class="max-w-lg mx-auto p-8">
  <details
    class="open:bg-white dark:open:bg-slate-900 open:ring-1 open:ring-black/5 dark:open:ring-white/10 open:shadow-lg p-6 rounded-lg"
    open
  >
    <summary
      class="text-sm leading-6 text-slate-900 dark:text-white font-semibold select-none"
    >
      Why do they call it Ovaltine?
    </summary>
    <div class="mt-3 text-sm leading-6 text-slate-600 dark:text-slate-400">
      <p>The mug is round. The jar is round. They should call it Roundtine.</p>
    </div>
  </details>
</div>

自定义修饰符

&

& 表示自身

<ul role="list">
  {#each items as item}
  <li class="[&:nth-child(3)]:underline">{item}</li>
  {/each}
</ul>

如果需要在选择器中使用空格,可以使用下划线

<div class="[&_p]:mt-4">
  <p>Lorem ipsum...</p>
  <ul>
    <li>
      <p>Lorem ipsum...</p>
    </li>
    <!-- ... -->
  </ul>
</div>

使用 at-rules,如 @media 或 @supports

<div class="flex [@supports(display:grid)]:grid">
  <!-- ... -->
</div>

在 at- 规则添加花括号中包含选择器修饰符来组合 at-规则和常规选择器修饰符

<button type="button" class="[@media(any-hover:hover){&:hover}]:opacity-100">
  <!-- ... -->
</button>

创建插件

let plugin = require("tailwindcss/plugin");

module.exports = {
  // ...
  plugins: [
    plugin(function ({ addVariant }) {
      // Add a `third` variant, ie. `third:pb-0`
      addVariant("third", "&:nth-child(3)");
    }),
  ],
};

高级主题

自定义 class

// main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .content-auto {
    content-visibility: auto;
  }
}
<div class="lg:content-auto">
  <!-- ... -->
</div>

修饰符顺序

当堆叠修饰符时,它们是从内到外应用的,就像嵌套的函数调用一样:

// These modifiers:
'dark:group-hover:focus:opacity-100'

// ...are applied like this:
dark(groupHover(focus('opacity-100')))