Day-20 使用 @apply 制做组件

昨天威尔猪示范了按钮的制作,很多小伙伴应该看完就崩溃了,样式设计很弹性没错,但写一个小小的按钮 + 状态变化要写这麽多的 Utility Class,还让不让人活。所以今天威尔猪来讲讲,怎麽制做自己的 Components。

@layer components

我们拿昨天建立的按钮来当范例,一般情况下我们的 Tailwind 会长这样,由很多 Utility 组成:

<button type="button" class="px-3 py-2 bg-blue-500 rounded text-white border border-blue-500 transition hover:bg-blue-600 focus:outline-none focus:bg-blue-600 focus:ring-4 focus:ring-blue-500 focus:ring-opacity-50 active:bg-blue-700">Button</button>

但像按钮这样的模组在很多页面都必须重覆使用,这时我们就必须考虑做成组件,对於按钮之类的小型组件,可以使用 Tailwind 的 @apply 指令,就可轻松地将通用功能模组建立到 CSS Components 中。

我们到一开始引入 Tailwind 的 style.css 里 (档名可能不一样),因为我们要制作组件,所以使用 @layer components 包在最外面,然後自订一个按钮的 Class 名称,威尔猪这边就用 btn 就好。

/* style.css */

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .btn {
    @apply px-3 py-2 bg-blue-500 rounded text-white border border-blue-500 transition hover:bg-blue-600 focus:outline-none focus:bg-blue-600 focus:ring-4 focus:ring-blue-500 focus:ring-opacity-50 active:bg-blue-700;
  }
}

然後回到 HTML,只需要带入 .btn 就好了,是不是清爽了许多:

/* index.html */

<button type="button" class="btn">Button</button>

https://ithelp.ithome.com.tw/upload/images/20210919/20141250f6UJyKowPp.png

使用 @layer 指令告诉 Tailwind 一组自定义样式应该属於哪个 "bucket"。可用的有 basecomponentsutilities。Tailwind 会将这些样式自动移到与 @tailwind components 相同的位置,所以不必担心在源文件中正确放置顺序。

不过上面这样的写法还不太好,毕竟按钮颜色这麽多,这样根本就不能共用,所以我们还需要进行更细致的拆分,我们可以拆出颜色、大小等,视你的专案而决定。

/* style.css */

@layer components {
  .btn {
    @apply px-3 py-2 rounded border transition focus:outline-none focus:ring-4;
  }
  
  .btn-sm {
    @apply px-2 py-1 text-sm rounded-sm;
  }
  
  .btn-lg {
    @apply px-5 py-3 text-xl rounded-md;
  }
  
  .btn-blue {
    @apply text-white bg-blue-500 border-blue-500 hover:bg-blue-600 focus:bg-blue-600 focus:ring-blue-500 focus:ring-opacity-50 active:bg-blue-700;
  }
}
/* index.html */

<button type="button" class="btn btn-sm btn-blue">Button</button>
<button type="button" class="btn btn-blue">Button</button>
<button type="button" class="btn btn-lg btn-blue">Button</button>

https://ithelp.ithome.com.tw/upload/images/20210919/20141250MZccEgAfTN.png

当当~这样是不是清爽很多,想要更多颜色的按钮,就可以依照上面的逻辑修改颜色即可。不过威尔猪要再次提醒,这是在必须要模组化的元件才这样使用,不要都变成内联样式了,除了失去方便修改的特性,还会让档案变肥,增加 CSS 的负担。

@layer base

威尔猪这边额外补充,因为 Tailwind 已将预设样式清除,所以有时我们在使用 h1h2 ... 之类的标签,必须都要设定文字大小,但难免会忘记到底设定是多少 Size,要再回去翻设计文件也是挺麻烦,我们可以使用 @apply 来设定,因为 h1、h2 是属於 HTML 基本标签,在最外层使用 @layer base 来包住,这样 Tailwind 就会自动编译到 Base 底下,范例如下:

/* style.css */

@layer base {
  h1 {
    @apply text-4xl font-bold;
  }
  
  h2 {
    @apply text-3xl font-bold;
  }
  
  h3 {
    @apply text-2xl font-bold;
  }
  
  h4 {
    @apply text-xl font-semibold;
  }
  
  h5 {
    @apply text-lg font-semibold;
  }
  
  h6 {
    @apply text-base font-medium;
  }
}

当然我们也可以使用 Plugin 来注册新样式,让 Tailwind 使用 tailwind.config.js 来代替在 CSS 设定的样式表。范例如下:

// tailwind.config.js

const plugin = require('tailwindcss/plugin')

module.exports = {
  ...
  plugins: [
    plugin(function({ addBase, config }) {
      addBase({
        'h1': { 
            fontSize: config('theme.fontSize.4xl'),
            fontWeight: config('theme.fontWeight.bold')
        },
        'h2': { 
            fontSize: config('theme.fontSize.3xl'),
            fontWeight: config('theme.fontWeight.bold')
        },
        'h3': { 
            fontSize: config('theme.fontSize.2xl'),
            fontWeight: config('theme.fontWeight.bold')
        },
        'h4': { 
            fontSize: config('theme.fontSize.xl'),
            fontWeight: config('theme.fontWeight.semibold')
        },
        'h5': { 
            fontSize: config('theme.fontSize.lg'),
            fontWeight: config('theme.fontWeight.semibold')
        },
        'h6': { 
            fontSize: config('theme.fontSize.base'),
            fontWeight: config('theme.fontWeight.medium')
        }
      })
    })
  ]
}

Plugins 有许多的 Functions 可以使用,例如今天讲到的 addComponents()addBase() 等,如果有兴趣的同学们可以到官方文件看看。虽然威尔猪还是觉得在 CSS 使用 @apply 方便些,但可能会让 CSS 变肥,就看各位夥伴们怎麽抉择了。以上就是今天的内容,咱们明天见。


<<:  .Net Core Web Api_笔记11_组合路由

>>:  Day5. 在没有运转前,世界就是静止的 - Runner

[18] [烧瓶里的部落格] 08. 撰写测试

写单元测试可以检查程序是否按预期执行,Flask 可以模拟发送请求并回传资料 应当尽可能多进行测试,...

.Net Core Web Api_笔记13_api结合ADO.NET资料库操作part1_专案前置准备到资料新增

专案前置准备 新建好资料库以及资料表 create table NewsType ( NewsTyp...

Day6. 依点成形,创造物件 - RigidBody(上)

经历了前两天的基础介绍,今天我们终於要到创建物件的环节了,而这个标题我想已经说明了一切,没错,这篇是...

Day11|【Git】档案管理 - 重新命名档案 git mv

延续上篇的说明,在 Git 的世界,任何动作对 Git 来说都可以视为一个「修改」的动作。因此这篇要...

MySQL 字串类型资料之基本操作

VARCHAR & CHAR VARCHAR(0-65535)/CHAR(0-255)差别於...