CSS - Tailwind CSS 阿哩阿杂的设定

上一篇介绍了 Tailwind 基本的语法,而今天要来看的是 Tailwind 的设定,之前说到的许多功能都是靠着这些设定达成,包含变数、模组化、tree-shake 等等,那就废话不多说一起来看看设定吧~GOGO!

CSS - Tailwind CSS 入门与语法

设定档

上次我们说到的 tailwind.config.js 这个档案包含了各种相关设定,可以使用以下指令产生设定档

<!-- 建立设定档 -->
$ npx tailwindcss init
<!-- 建立包含所有预设值的设定档 -->
$ npx tailwindcss init --full
<!-- 建立设定档与 postcss.config.js -->
$ npx tailwindcss init -p

产出的设定档包含几个常用设定,如下

// tailwind.config.js

module.exports = {
  purge: [],
  darkMode: false,
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
  
  // 预设没显示但可使用的设定
  // prefix: '',
  // important: false,
  // separator: ':',
  // presets: [],
  // variantOrder: [],
  // corePlugins: [],
}

postcss.config.js

上面其中一个指令会生成 postcss.config.js,这个档案是用来载入 postcss 插件用的,这边预设会载入 tailwindcssautoprefixer,如果想要载入其他的插件或设定才会用到这个档案

// postcss.config.js

module.exports = {
  plugins: {
    // 使用 ./config.js 当作 Tailwind 的设定档
    tailwindcss: { config: './config.js' },
    autoprefixer: {},
  },
}

presets

presets 可使用其他预设值替换 Tailwind 的预设值,如果团队内有自己常用的预设值就可以使用此功能,设定一次之後开新专案时就可以节省许多时间,详细设定方式可以参考官方

// tailwind.config.js

module.exports = {
  presets: [
    require('@acmecorp/tailwind-base')
  ]
}
  • 若设定重复,最後一个将盖过前面的设定
  • 若设定档有以下设定会进行完全覆盖,其余则是采用合并方式
    • purge
    • darkMode
    • prefix
    • important
    • variantOrder
    • separator

prefix

prefix 会将撰写的 class 加上自定义的前缀,可防止样式的冲突,在撰写插件时常会使用到该功能

// tailwind.config.js

module.exports = {
  prefix: 'tw-'
}
.tw-text-left {
  text-align: left;
}
  • prefix 对自定义的 class 无效

important

important 控制 css 後方是否加入 !important

// tailwind.config.js

module.exports = {
  important: true
}
.text-left {
  text-align: left !important;
}
  • important 对自定义的 class 无效

因为 !important 有可能会导致 inline style 无效,或者引发其他权重问题,所以这边 important 也可设定一个 IDclass,编译时 Tailwind 会加入该选择器前缀,而不是加上 !important

// tailwind.config.js

module.exports = {
  important: '#app'
}
#app .text-left {
  text-align: left;
}

separator

separator 可自定义 RWD、hover 等等的区隔符号,预设为 :

// tailwind.config.js

module.exports = {
  separator: '_'
}
/* 预设为 ':' */
.sm:bg-fixed {
  background-attachment: fixed;
}
/* 修改为 '_' */
.sm_bg-fixed {
  background-attachment: fixed;
}

purge

purge 为 tree-shake 的功能,它会使用正则表达式侦测样版,并将没有用到的 class 删除

// tailwind.config.js

module.exports = {
  purge: ['./**/*.html']
}

以上设定会在环境变数为 production 时执行,如果专案没有用到 webpack 的话,也可以用以下方式设定

// tailwind.config.js

module.exports = {
  purge: {
    layers: ['utilities'], // 指定清除样式的图层
    mode: 'all', // 删除选定图层未使用的样式
    preserveHtmlElements: false, // 清除没用到的 html 元素设定
    enabled: true, // 是否开启 purge
    content: ['./**/*.html'], // 侦测哪些样版内容
    options: {
      safelist: ['bg-red-500', 'px-4'] // 不会被清除的样式
    }
  }
}
  • 不要使用字串拼接 class,以防正则表达式侦测不到
  • purge 仅会清除 layers 内未使用的样式
  • layers 预设为 basecomponentsutilities
  • preserveHtmlElements 的 html 元素指的是 h1body 等等的样式
  • 官方不推荐使用 preserveHtmlElementsmode

darkMode

darkMode 为深色模式,有 falsemediaclass 三个选项,开启後 dark 前缀的 class 优先度会大於一般 class

  • false:关闭深色模式
  • media:依照装置的 prefers-color-scheme 开启深色模式
  • class:手动设定深色模式,依照根目录的 <html> 是否有 class="dark" 切换
<!-- 关闭深色模式 -->
<html>
<head></head>
<body>
  <div class="bg-white dark:bg-black"></div>
</body>
</html>

<!-- 开启深色模式 -->
<html class="dark">
<head></head>
<body>
  <div class="bg-white dark:bg-black"></div>
</body>
</html>

theme

theme 即是变数的概念,所有的断点、颜色、间距等等皆会在这边做设定

extend

extend 会继承预设值,并新增变数或覆盖旧有变数

// tailwind.config.js

module.exports = {
  theme: {
    // 覆盖 colors 预设值,仅留下 black
    colors: {
      black: '#333'
    },
    extend: {
      // 保留 colors 预设值,并覆盖 black
      colors: {
        black: '#444'
      }
    }
  }
}
  • 优先顺序为: extend > theme > 预设值

theme()

Tailwind 提供了 theme() 来帮我们减少重复作业,在上一篇我们也有提到过,使用方式如下

// tailwind.config.js

module.exports = {
  theme: {
    colors: {
      black: '#333'
    },
    // 这边 theme 的回传值等於前面 colors 的值
    backgroundColor: theme => theme('colors')
  }
}

扩充预设样式

如果想要扩充预设的样式又不想重写预设值,则可以先载入预设样式再合并

// tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme')
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: [
          'Lato',
          ...defaultTheme.fontFamily.sans
        ]
      }
    }
  }
}

另外说一下官方这边提供了三个东西可载入

// 预设颜色
const defaultTheme = require('tailwindcss/colors')
// 预设设定
const defaultTheme = require('tailwindcss/defaultConfig')
// 预设 theme
const defaultTheme = require('tailwindcss/defaultTheme')

variants

variants 可以设定 theme 内的样式或是插件支援哪写变化,例如 RWD 断点、深色模式、hover 等等

extend

功能同 theme 的 extend,会继承预设值,并新增设定

// tailwind.config.js

module.exports = {
  variants: {
    // 覆盖 backgroundColor 预设值,仅留下 responsive
    backgroundColor: ['responsive']
    extend: {
      // 保留 backgroundColor 预设值,并新增 active
      backgroundColor: ['active']
    }
  }
}

优先权

编译 variants 内的项目时,会由阵列第一个开始编译,也就是说最後一个 variant 优先权最高,所以如果要调整优先权请依照自己需求排序,另外还可以使用 DEFAULT 来表示普通 class 的位置

// tailwind.config.js

module.exports = {
  variants: {
    // 这边以 bg-white 为例,优先权如下
    // .hover:bg-white < bg-white < .focus:bg-white
    backgroundColor: ['hover', 'DEFAULT', 'focus']
  }
}

variantOrder

上面有提到 variants 优先权的部分,如果有在 extend 用到的属性,不管前面如何设定,它都会照着预设优先权去编译,并将新增的放到最後方,这时候如果想修改就必须设定 variantOrder

// tailwind.config.js

module.exports = {
  // 这边以 bg-white 为例,设定 variantOrder 後优先权如下
  // bg-white < .focus:bg-white < .hover:bg-white < .active:bg-white
  variantOrder: [
    'DEFAULT',
    'focus',
    'hover',
    'active'
  ],
  variants: {
    backgroundColor: ['hover', 'DEFAULT', 'focus'],
    extend: {
      // 这边以 bg-white 为例,没有设定 variantOrder 优先权如下
      // bg-white < .hover:bg-white < .focus:bg-white < .active:bg-white
      backgroundColor: ['active']
    }
  }
}

corePlugins

corePlugins 可以禁用某些你不需要的样式,有物件型与阵列型,详细选项可参考官方

// tailwind.config.js

module.exports = {
  // 使用物件 true 与 false 决定使否启用样式
  corePlugins: {
    float: false,
    objectFit: false,
    objectPosition: false,
  },
  
  // 启用阵列内所有样式
  corePlugins: [
    'margin',
    'padding',
    'backgroundColor'
  ],
  
  // 禁用所有样式
  corePlugins: []
}

plugins

plugins 是 Tailwind 一个重要的功能,它提供开发者自行开发插件,或是载入别人写好的插件

载入插件

以下载入他人的插件,并新增一个 group-disabledvariants

// tailwind.config.js

module.exports = {
  variantOrder: [
    'hover',
    'group-disabled'
  ],
  variants: {
    extend: {
      backgroundColor: ['group-disabled']
    }
  },
  plugins: [
    require('tailwindcss-interaction-variants')
  ]
}

撰写插件

首先要载入 plugin 函式,并依照官方格式撰写,这边加入两个 class 而且设定 variants

// tailwind.config.js

const plugin = require('tailwindcss/plugin')
module.exports = {
  prefix: 'tw-',
  important: true,
  variants: {
    customPlugin: ['responsive', 'hover'],
  },
  plugins: [
    plugin(function({ addUtilities, variants }) {
      const newUtilities = {
        '.skew-10deg': { transform: 'skewY(-10deg)' },
        '.skew-15deg': { transform: 'skewY(-15deg)' }
      }
      
      addUtilities(newUtilities, {
        // 是否依照依照设定档加上前缀,预设为 true
        respectPrefix: true,
        // 是否依照设定档加上 !important,预设为 true
        respectImportant: true,
        // 依照设定档加入 variant
        variants: variants('customPlugin')
      })
    })
  ]
}

这边插件的撰写有太多的变化,可以撰写 baseutilitiecomponent 等等,自由度相当高,所以这边就不多做琢磨了

结语

看完 Tailwind 的设定其实并不难,许多东西预设值就很够了,而且针对需要的地方客制化也相当方便,除此之外还有许多 plugin 可供使用,这也是它优秀的地方之一,毕竟有社群与自己的生态系在就会持续的进步,相信 Tailwind 未来会被更广泛的使用


<<:  iOS APP 开发 OC 第十天,NSObject

>>:  iOS APP 开发 OC 第十天,block

Day 17 大流量网路安全-Anti-DDoS

前面我们持续带入新的服务利用架构的方式解决网站负载问题,在资安方面使用了应用防火墙(WAF)能有效...

Day30:今天来聊一下CEH中讲的Mail Cryptography

电子邮件加密通过将电子邮件内容加密为不可读的形式来隐藏窃听者电子邮件内容。 电子邮件可以通过使用公钥...

[DAY-27] 适合你的 才是真正的好职涯

经营你的职业生涯 人对於甚麽叫 理想职涯 都有一套自己的想法 在经营职涯时候 追求目标要有弹性 适...

高凝聚力和低耦合(High Cohesion and Low Coupling)

-软件构架 从软件的角度来看, . 内聚性(Cohesion)是指模块中元素所组织的相关程度。“高...

React-router相关

当使用react-router-dom时 由於在v6版本後做了一些改变 本来在import {Has...