如何评价CSS框架TailwindCSS?

news2024/11/17 1:54:36

图片

端午三天,你们在放假,而我,一个人躲在家里,苦练 tailwindcss。

我在准备这样一个学习项目,它与传统的文章/视频类学习不同,我会在教程中内置大量的可交互案例,提供沉浸式的学习体验,并且还可以支持实时修改代码观察案例更改结果。大家可以期待一下。

图片

经过这个项目的历练,现在,我已熟练度拉满,彻底拿捏了 tailwindcss。

魔功大成!

这篇文章,就跟大家分享一下我在 tailwindcss 中已经使用到的高级用法。

  • 一、彻底读懂配置文件 tailwind.config.js

  • 二、定义自己喜欢的语法

  • 二、定义自己喜欢的功能块

  • 三、定义自己想要的插件

  • 三、高级用法:简单实现皮肤切换

0

高端,从读懂配置文件开始

在使用 tailwindcss 时,我们可以在项目根目录创建一个配置文件 tailwind.confing.js,用于控制 tailwindcss 的语法,理论上来说,你可以把 tw 调整成任何你需要的形状。

使用如下指令,可以在根目录创建一个最简单的配置文件模板

npx tailwindcss init
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [],
  theme: {
    extend: {},
  },
  plugins: [],
}

content

content 选项是一个数组,用于指定 tailwindcss 语法生效的文件集合。

content: [
  './pages/**/*.{js,jsx}',
  './components/**/*.{js,jsx}',
  './app/**/*.{js,jsx}',
  './src/**/*.{js,jsx}',
]

tailwind 使用 fast-glob 库来匹配文件。其中,* 匹配任意字符,** 匹配 0 个或者多个目录,{js, jsx} 匹配多个值。

图片

配置完之后的文件数量越多,编译时的压力就越大,因此我们应该尽可能缩小 tailwindcss 的配置范围,只在需要它的地方使用。例如 utils 目录可能会包含大量的文件,但是不会使用 tailwindcss,那么我们就应该把他剔除掉。

当然我们还可以做其他的一些配置增强,但是大多都没什么用,对我来说,这里一个比较有用的配置项是 transform。我写的文章内容,源文件是 .md 格式,此时如果我想要在 .md 中使用 tailwindcss,那么就需要将其转换为 html 之后再适配 tailwindcss,我们就可以这样配置

const remark = require('remark')

module.exports = {
  content: {
    files: ['./src/**/*.{html,md}'],
    transform: {
      md: (content) => {
        return remark().process(content)
      }
    }
  },
  // ...
}

theme

theme 字段的配置是我们拿捏 tailwindcss 的核心关键。我们可以通过这个字段自定义任意语法。但是这个语法新人玩家容易看不懂,一长串不知道如何使用。我给大家讲解一下很快就很搞懂了

首先,theme 中包含了大量的字段,这些字段有 colorstextColor,这个是啥意思呢?就很迷惑。

我们可以在这个地址中,查看默认的完整配置项 https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/config.full.js#L5

其实,我们只需要利用好官方文档,就能很轻松的搞懂这些配置。theme 中的字段主要分为两类,一类表示 css 属性。一类表示配置。

例如在配置文件中,有一个 borderWidth的配置如下

borderWidth: {
  DEFAULT: '1px',
  0: '0px',
  2: '2px',
  4: '4px',
  8: '8px',
},

这看上去像是一个 css 属性,又像是一个配置项,那么我们可以去官方文档的如下地址中,直接查这个单词. 点开之后发现,这里确实是一个属性值。并且具体的缩写与写法,配置参数都一目了然,比只看官方文档更加具体。

图片

又例如,我们在配置项中发现了一个属性 spacing

spacing: {
  px: '1px',
  0: '0px',
  0.5: '0.125rem',
  1: '0.25rem',
  1.5: '0.375rem',
  2: '0.5rem',
  2.5: '0.625rem',
  3: '0.75rem',
  3.5: '0.875rem',
  4: '1rem',
  5: '1.25rem',
  6: '1.5rem',
  7: '1.75rem',
  8: '2rem',
  9: '2.25rem',
  10: '2.5rem',
  11: '2.75rem',
  12: '3rem',
  14: '3.5rem',
  16: '4rem',
  20: '5rem',
  24: '6rem',
  28: '7rem',
  32: '8rem',
  36: '9rem',
  40: '10rem',
  44: '11rem',
  48: '12rem',
  52: '13rem',
  56: '14rem',
  60: '15rem',
  64: '16rem',
  72: '18rem',
  80: '20rem',
  96: '24rem',
},

然后对应去官方文档查一下,发现这是一个配置项。那么我们就可以知道,这可能会作为入参运用到其他属性的设置中去。

图片

我们也可以自己定义非 rem 的属性单位,使用数组遍历的方式生成 1px -> 500px 中比较常用的一些数值,具体要结合实际情况和设计规范来约定它的配置

有了这个配置项之后,我们就可以使用它作为入参去配置其他 css 属性,例如 margin 值。这里的 theme 表示一个 get 方法,可以获取到 theme 配置项中对应属性的具体值。例如这里的 theme('spacing') 就是获取到我们刚才的配置项

margin: ({ theme }) => ({
  auto: 'auto',
  ...theme('spacing'),
}),

这样,margin 写法后面跟的数字,就是我们约定的 spacing 中具体的值了。

图片

m-0.5 ,对应的值,就是 spacing 中的 0.5:0.125rem

图片

theme 中的大多数属性值,都是 css 属性值,只有少数几个值是表示配置项,具体内容不用刻意去记忆,只需要在用到的时候查阅文档即可。如果你只是需要做简单粗暴的自定义修改,直接在默认配置的基础之上修改样式就可以

1

定义自己喜欢的语法

自定义语法更好的方式是使用 extend 配置去覆盖原有配置项。例如,我想要重新针对 background-color 定义一个语法写法如下,使用黑色的拼音缩写来表达颜色,使用数字来表示不同程度的黑色

bg-heise-0
bg-heise-1
bg-heise-2
bg-heise-3
bg-heise-4

首先我们要做的第一件事情,是在官方文档中,找到 background color 对应的缩写是什么

图片

然后在 extend 字段中,对应的字段里,配置自定义的语法,heise.

theme: {
  extend: {
    backgroundColor: {
      heise: {
        0: 'rgba(0, 0, 0, 0)',
        1: 'rgba(0, 0, 0, 0.1)',
        2: 'rgba(0, 0, 0, 0.2)',
        3: 'rgba(0, 0, 0, 0.3)',
        4: 'rgba(0, 0, 0, 0.4)',
      },

此时,我们的语法就是属性缩写开头的方式, bg-heise-0,我们可以看到,在文件中使用改语法时,智能提示已经有了我们自己定义的语法,完美!

2

定义自己想要的功能块

tailwindcss 有三个模块。

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

base 表示样式重置模块。components 表示组件模块,utilities 表示功能模块,我们可以通过插件的形式,往这几个功能模块中新增我们想要的功能块。

例如,我希望自定义默认的 button 元素的样式,那么我们就可以往 base 模块中注入样式,首先引入插件方法

const plugin = require('tailwindcss/plugin')

然后在 plugins 字段中新增配置样式

module.exports = {
  plugins: [
    plugin(function({ addBase, theme }) {
      addBase({
        'button': { color: theme('colors.orange.700') }
      })
    })
  ]
}

然后,我在项目中写上如下代码,对应的结果如图所示,文字颜色变成了 orange.700

<button>自定义button默认样式</button>

图片

我们可以通过这中方式约定所有的基础样式,button, input 等都非常需要这样的约定。

当然,我们也可以通过类似的方式往 components 中新增样式。例如我希望新增一个 card 组件,用于表示一个区域的容器,那么我就可以这样写

plugin(({addComponents, theme}) => {
  addComponents({
    '.card': {
      display: 'inline-block',
      padding: '1rem',
      border: '1px solid',
      borderRadius: '4px',
      borderColor: theme('colors.red.400'),
      margin: '1rem'
    }
  })
}),

然后我在项目中编写如下代码

<div className='card'>
  <button>自定义button默认样式</button>
</div>

图片

给力!

3

定义自己想要的插件

如下图所示,此时我们想要实现的一个功能是自定义字体大小的递增序列。具体的编号和对应的值都由我们自己来定 fsize-12,而不是通过默认的 text-xxx 来约定。

图片

首先,我们先在 theme 中约定配置项,数量太多的时候,你也可以通过数组遍历来快速创建

theme: {
  fsizes: {
    12: '12px',
    14: '14px',
    16: '16px',
    18: '18px',
    24: '24px',
    32: '32px',
  },
  ...

然后,plugins 字段中,使用 matchUtilities 方法动态匹配后缀自增的 class

plugin(({matchUtilities, theme}) => {
  matchUtilities({
    fsize: (value) => ({
      fontSize: value
    })
  }, {
    values: theme('fsizes')
  })
})

搞定,最后的演示结果如图所示

图片

4

高级用法:简单实现皮肤切换

最后,我们再来一个具体的,实用功能的实现:皮肤切换。具体的实现方式仍然是利用 css 自定义变量来做到。

实现效果如图所示

图片

主题来源于 tailwindcss 官方教学视频

我们来看一下实现步骤。

首先,我们要在入口 css 中文件中,约定不同主题的 css 变量。

@layer base {
  :root {
    --color-text-base: #FFF;
    --color-text-muted: #c7d2f7;
    --color-text-inverted: #4f46e5;
    --color-fill: #4338ca;
    --color-button-accent: #FFF;
    --color-button-accent-hover: #eef2ff;
    --color-button-muted: 99, 102, 241;
  }
  .theme-swiss {
    --color-text-base: #FFF;
    --color-text-muted: #fecaca;
    --color-text-inverted: #dc2626;
    --color-fill: #b91c1c;
    --color-button-accent: #FFF;
    --color-button-accent-hover: #fef2f2;
    --color-button-muted: 239, 68, 68;
  }
  
  .theme-neon {
    --color-text-base: #111802;
    --color-text-muted: #2fc306;
    --color-text-inverted: #ebfacc;
    --color-fill: #b3ff17;
    --color-button-accent: #243403;
    --color-button-accent-hover: #374f05;
    --color-button-muted: 212, 255, 122;
  }
}

@layer base 表示这些定义会运用到 base 模块中。

定义好了主题之后,我们就需要去 extend 字段中自定义语法。首先是针对于文字颜色字段,该字段在 css 中为  color,不过在 tailwind 中,被重新定义了语义,称之为 text color

图片

因此,我们要使用 textColor 来定义该语法,

extend: {
  textColor: {
    skin: {
      base: 'var(--color-text-base)',
      muted: 'var(--color-text-muted)',
      inverted: 'var(--color-text-inverted)',
    }
  },

textColor 的对应缩写为 text,因此最终我们自定义的语法名如下所示

图片

用同样的方式定义背景颜色

backgroundColor: {
  skin: {
    fill: 'var(--color-fill)',
    'button-accent': 'var(--color-button-accent)',
    'button-accent-hover': 'var(--color-button-accent-hover)',
    'button-muted': ({opacityValue}) => {
      console.log(opacityValue)
      if (opacityValue !== undefined) {
        return `rgba(var(--color-button-muted), ${opacityValue})`
      }
      return `rgb(var(--color-button-muted))`
    },
  }
},

图片

在需要颜色的地方,我们使用自己定义好的语法来设置颜色。

他们的值,都由 var 来声明,对应到我们刚才定义的 css 变量。因此,这样做好之后,当我们改变 css 变量的生效结果,那么皮肤切换就能自定生成。

我们可以更改顶层父组件的 className 来做到变量名的整体切换。

图片

实现完成之后,再来看一眼演示效果,没有问题,搞定!

图片

5

总结

实践中的需求非常复杂,每个团队对于 UI 的设计规范不同,那么默认样式就很难满足所有团队的需求,因此,掌握如何将 tailwindcss 配置为你的形状,是在团队中推广和运用它的必要条件。

但是官方文档对于配置文件的讲解有一些缺漏,导致我也花了很长时间,查了不少资料才最终读懂,因此这篇文章我把缺漏的部分补上,有助于道友们更加方便理解它,并结合官方文档彻底拿捏 tailwindcss 的自定义配置。

仅供参考!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1883083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue组件化、单文件组件以及使用vue-cli(脚手架)

文章目录 1.Vue组件化1.1 什么是组件1.2 组件的使用1.3 组件的名字1.4 嵌套组件 2.单文件组件2.1 vue 组件组成结构2.1.1 template -> 组件的模板结构2.1.2 组件的 script 节点2.1.3 组件的 style 节点 2.2 Vue组件的使用步骤2.2.1 组件之间的父子关系2.2.2 使用组件的三个步…

通过nginx去除 api url前缀 并保持后面剩余的url不变向后台请求

如 我前台浏览器向后台请求的接口是 http://127.0.0.1:5099/api/sample/sample/getbuttonlist 实际的请求接口传向 http://192.168.3.71:5099/sample/sample/getbuttonlist 方法是向config中加入下面这样一个server server {listen 5099;location /api/ {rewrite ^/a…

【Python机器学习】模型评估与改进——打乱划分交叉验证

打乱划分交叉验证是一种非常灵活的交叉验证策略。 在打乱划分交叉验证中&#xff0c;每次划分为训练集取样train_size个点&#xff0c;为测试集取样test_size个不相交的点。将这一划分方法重复n_iter次。 举例&#xff1a; import matplotlib.pyplot as plt import mglearnm…

mysql wrnning Difficult to find free blocks in the buffer pool解决方法

mysql [InnoDB] Difficult to find free blocks in the buffer pool (140397 search iterations)! 我使用的是mysql8,。 原因&#xff1a;这种情况&#xff0c;多半出现在别人在非常大的写入&#xff0c;或者百万级的查询中。 解决方式&#xff0c;centos7在线安装的mysql&am…

软件测试面试题常见一百道【含答案】

1、问&#xff1a;你在测试中发现了一个bug&#xff0c;但是开发经理认为这不是一个bug&#xff0c;你应该怎样解决? 首先&#xff0c;将问题提交到缺陷管理库里面进行备案。 然后&#xff0c;要获取判断的依据和标准&#xff1a; 根据需求说明书、产品说明、设计文档等&am…

初音未来短视频:成都柏煜文化传媒有限公司

初音未来短视频&#xff1a;虚拟偶像的魅力与影响 在数字化时代&#xff0c;虚拟偶像逐渐崭露头角&#xff0c;其中初音未来无疑是这一领域的佼佼者。她以独特的形象和音乐才华&#xff0c;赢得了全球无数粉丝的喜爱。成都柏煜文化传媒有限公司 初音未来的短视频&#xff0c;更…

ROS2使用C++开发动作通信

1.开发接口节点 cd chapt4_ws/ ros2 pkg create robot_control_interfaces --build-type ament_cmake --destination-directory src --maintainer-name "joe" --maintainer-email "1027038527qq.com" mkdir -p src/robot_control_interfaces/action touch…

Linux:系统安全及应用

目录 一、系统账号管理 1.1、系统账号清理 1.2、密码安全控制 1.3、命令历史限制 二、限制su命令用户 三、PAM安全认证 四、sudo机制提升权限 4.1、sudo机制介绍 4.2、用户别名案例 4.3、启用sudo操作日志 4.4、其他案列sudo 4.5、开关机安全控制 4.6、限制更改GR…

ElasticSearch 6.5.4 安装中文分词器 IK

1.docker在线安装 1.1进入Elasticsearch容器 docker exec -it elasticsearch的容器ID /bin/bash 注意&#xff1a;如果进入Elasticsearch之后&#xff0c;自动退出&#xff0c;说明内存不够&#xff0c;先关闭虚拟机&#xff0c;然后 把内存调大之后在启动虚拟机。 1.2在线下…

【普中】基于51单片机的7人多数投票表决器设计( proteus仿真+程序+设计报告+讲解视频)

投票表决器设计 1.主要功能&#xff1a;讲解视频&#xff1a;2.仿真3. 程序代码4. 设计报告5. 设计资料内容清单&&下载链接 【普中】基于51单片机的7人多数投票表决器设计 ( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus8.16(有低版本) 程序编译器&am…

暑期自学IT:从基础到实战的完美指南

高考终于结束了&#xff0c;你是否正在为如何度过这个漫长的暑假而发愁呢&#xff1f;与其天天躺在床上刷剧&#xff0c;不如趁着这段宝贵的时间&#xff0c;开启一段IT世界的奇妙探险之旅吧&#xff01;无论你是对计算机科学充满好奇&#xff0c;还是已经决定未来要在IT领域大…

java生成excel,uniapp微信小程序接收excel并打开

java引包&#xff0c;引的是apache.poi <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency> 写一个测试类&#xff0c;把excel输出到指定路径 public s…

优盘有盘符显示0字节:故障解析与数据恢复策略

一、优盘有盘符显示0字节现象描述 在使用优盘的过程中&#xff0c;我们有时会遇到一种令人困惑的情况&#xff1a;插入优盘后&#xff0c;电脑能正常识别到优盘的盘符&#xff0c;但当我们尝试访问其中的数据时&#xff0c;却发现优盘的容量显示为0字节&#xff0c;无法读取或…

VUE3解决跨域问题

本文基于vue3 vite element-plus pnpm 报错&#xff1a;**** has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource. 原因&#xff1a;前端不能直接访问其他IP&#xff0c;需要用vite.config.ts &#xff0…

API-Window对象

学习目标&#xff1a; 掌握Window对象 学习内容&#xff1a; BOM&#xff08;浏览器对象模型&#xff09;定时器-延时函数JS执行机制location对象navigation对象history对象 BOM&#xff08;浏览器对象模型&#xff09;&#xff1a; BOM是浏览器对象模型。 window对象是一个全…

每个App下载收费3.88元,苹果太强势被开2800亿罚单

刚刚开完 WWDC2024 大会&#xff0c;苹果就被欧盟找上了麻烦。 欧盟认为苹果涉嫌违反涉嫌违反《数字市场法案》&#xff08;Digital Markets Act&#xff09;&#xff0c;造成垄断。 来源&#xff1a;欧盟委员会 明确指出苹果在 Apple Store 里面对开发者的限制不合理。 在最…

栈的概念和实现

1.栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&…

侯捷C++面向对象高级编程(上)-6-三大函数:拷贝构造、拷贝复制、析构

1. 2.三个特殊函数 3.构造函数和析构函数 4.浅拷贝&#xff08;系统默认仅把指针拷贝过去&#xff09; 5.拷贝构造函数&#xff08;深拷贝&#xff0c;拷贝的内容&#xff0c;重写string函数&#xff09; 6.拷贝赋值

阿里云 CosyVoice 语音合成大模型 API 实践

前言 最近大模型这么火&#xff0c;就想着玩一下&#xff0c;作为非 AI 从业者&#xff0c;最好的方式就是调用云服务的 API 来构建自己的 AI 应用。首选当然是国外的 ChatGPT API&#xff0c;但是说实话那个玩意有点贵&#xff0c;而且最近国内也被封禁不让调用了&#xff0c…

诊所运营效率提升方法有哪些?

随着医疗行业的快速发展和市场竞争的加剧&#xff0c;诊所运营效率的提升成为了众多医疗机构关注的焦点。高效的诊所运营不仅能够提升患者的就医体验&#xff0c;还能帮助诊所实现可持续发展。那么&#xff0c;诊所运营效率提升的方法有哪些呢&#xff1f; 1、优化管理流程 诊…