Attributify preset
This enables the attributify mode for other presets.
Installation
pnpm add -D @unocss/preset-attributify
pnpm add -D @unocss/preset-attributify
yarn add -D @unocss/preset-attributify
yarn add -D @unocss/preset-attributify
npm install -D @unocss/preset-attributify
npm install -D @unocss/preset-attributify
// uno.config.ts
import presetAttributify from '@unocss/preset-attributify'
export default defineConfig({
presets: [
presetAttributify({ /* preset options */ }),
// ...
],
})
// uno.config.ts
import presetAttributify from '@unocss/preset-attributify'
export default defineConfig({
presets: [
presetAttributify({ /* preset options */ }),
// ...
],
})
TIP
This preset is included in the unocss
package, you can also import it from there:
import { presetAttributify } from 'unocss'
import { presetAttributify } from 'unocss'
Attributify Mode
Imagine you have this button using Tailwind’s utilities. When the list gets longer, it becomes really hard to read and maintain.
<button class="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono font-light py-2 px-4 rounded border-2 border-blue-200 dark:bg-blue-500 dark:hover:bg-blue-600">
Button
</button>
<button class="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono font-light py-2 px-4 rounded border-2 border-blue-200 dark:bg-blue-500 dark:hover:bg-blue-600">
Button
</button>
With attributify mode, you can separate utilities into attributes:
<button
bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"
text="sm white"
font="mono light"
p="y-2 x-4"
border="2 rounded blue-200"
>
Button
</button>
<button
bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"
text="sm white"
font="mono light"
p="y-2 x-4"
border="2 rounded blue-200"
>
Button
</button>
For example, text-sm text-white
could be grouped into text="sm white"
without duplicating the same prefix.
Prefix self-referencing
For utilities like flex
, grid
, border
, that have the utilities same as the prefix, a special ~
value is provided.
For example:
<button class="border border-red">
Button
</button>
<button class="border border-red">
Button
</button>
Can be written as:
<button border="~ red">
Button
</button>
<button border="~ red">
Button
</button>
Valueless attributify
In addition to Windi CSS’s attributify mode, this preset also supports valueless attributes.
For example,
<div class="m-2 rounded text-teal-400" />
<div class="m-2 rounded text-teal-400" />
now can be
<div m-2 rounded text-teal-400 />
<div m-2 rounded text-teal-400 />
INFO
Note: If you are using JSX, <div foo>
might be transformed to <div foo={true}>
which will make the generated CSS from UnoCSS fail to match the attributes. To solve this, you might want to try transformer-attributify-jsx
along with this preset.
Properties conflicts
If the name of the attributes mode ever conflicts with the elements’ or components’ properties, you can add un-
prefix to be specific to UnoCSS’s attributify mode.
For example:
<a text="red">This conflicts with links' `text` prop</a>
<!-- to -->
<a un-text="red">Text color to red</a>
<a text="red">This conflicts with links' `text` prop</a>
<!-- to -->
<a un-text="red">Text color to red</a>
Prefix is optional by default, if you want to enforce the usage of prefix, set
presetAttributify({
prefix: 'un-',
prefixedOnly: true, // <--
})
presetAttributify({
prefix: 'un-',
prefixedOnly: true, // <--
})
You can also disable the scanning for certain attributes by:
presetAttributify({
ignoreAttributes: [
'text'
// ...
]
})
presetAttributify({
ignoreAttributes: [
'text'
// ...
]
})
TypeScript support (JSX/TSX)
Create shims.d.ts
with the following content:
By default, the type includes common attributes from
@unocss/preset-uno
. If you need custom attributes, refer to the type source to implement your own type.
Vue
Since Volar 0.36, it's now strict to unknown attributes. To opt-out, you can add the following file to your project:
// html.d.ts
declare module '@vue/runtime-dom' {
interface HTMLAttributes {
[key: string]: any
}
}
declare module '@vue/runtime-core' {
interface AllowedComponentProps {
[key: string]: any
}
}
export {}
// html.d.ts
declare module '@vue/runtime-dom' {
interface HTMLAttributes {
[key: string]: any
}
}
declare module '@vue/runtime-core' {
interface AllowedComponentProps {
[key: string]: any
}
}
export {}
React
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'react' {
interface HTMLAttributes<T> extends AttributifyAttributes {}
}
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'react' {
interface HTMLAttributes<T> extends AttributifyAttributes {}
}
Vue 3
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module '@vue/runtime-dom' {
interface HTMLAttributes extends AttributifyAttributes {}
}
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module '@vue/runtime-dom' {
interface HTMLAttributes extends AttributifyAttributes {}
}
SolidJS
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'solid-js' {
namespace JSX {
interface HTMLAttributes<T> extends AttributifyAttributes {}
}
}
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'solid-js' {
namespace JSX {
interface HTMLAttributes<T> extends AttributifyAttributes {}
}
}
Svelte & SvelteKit
declare namespace svelteHTML {
import type { AttributifyAttributes } from '@unocss/preset-attributify'
type HTMLAttributes = AttributifyAttributes
}
declare namespace svelteHTML {
import type { AttributifyAttributes } from '@unocss/preset-attributify'
type HTMLAttributes = AttributifyAttributes
}
Astro
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare global {
namespace astroHTML.JSX {
interface HTMLAttributes extends AttributifyAttributes { }
}
}
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare global {
namespace astroHTML.JSX {
interface HTMLAttributes extends AttributifyAttributes { }
}
}
Preact
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'preact' {
namespace JSX {
interface HTMLAttributes extends AttributifyAttributes {}
}
}
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'preact' {
namespace JSX {
interface HTMLAttributes extends AttributifyAttributes {}
}
}
Attributify with Prefix
import type { AttributifyNames } from '@unocss/preset-attributify'
type Prefix = 'uno:' // change it to your prefix
interface HTMLAttributes extends Partial<Record<AttributifyNames<Prefix>, string>> {}
import type { AttributifyNames } from '@unocss/preset-attributify'
type Prefix = 'uno:' // change it to your prefix
interface HTMLAttributes extends Partial<Record<AttributifyNames<Prefix>, string>> {}
Options
strict
- type:
boolean
- default:
false
Only generate CSS for attributify or class.
prefix
- type:
string
- default:
'un-'
The prefix for attributify mode.
prefixedOnly
- type:
boolean
- default:
false
Only match for prefixed attributes.
nonValuedAttribute
- type:
boolean
- default:
true
Support matching non-valued attributes.
ignoreAttributes
- type:
string[]
A list of attributes to be ignored from extracting.
trueToNonValued
- type:
boolean
- default:
false
Non-valued attributes will also match if the actual value represented in DOM is true
. This option exists for supporting frameworks that encodes non-valued attributes as true
. Enabling this option will break rules that ends with true
.
Credits
Initial idea by @Tahul and @antfu. Prior implementation in Windi CSS by @voorjaar.