vuetify-nuxt-module icon indicating copy to clipboard operation
vuetify-nuxt-module copied to clipboard

[Feature Request] Improve Compatibility of Utility Classes with UnoCSS/Tailwind

Open trydofor opened this issue 6 months ago • 4 comments

Background

Currently, I'm exploring ways to disable the built-in utility classes in favor of using unocss (or TailwindCSS via unocss presets) in my project. I’ve found some related behavior:

Goal

In my project, I aim to:

  • ✅ Use unocss instead of built-in utility classes wherever possible
  • ❌ Disable Vuetify utility classes selectively — only when safe
  • 🧱 For unsafe cases, block them via unocss’s blocklist

Problem

Currently, I’m unclear on the compatibility boundaries between Vuetify utility classes and unocss. Specifically:

  • Which Vuetify utility classes are safe to disable?
  • Which utility classes should be explicitly blocked in unocss to avoid conflicts?

Proposed Idea

Would it be possible to:

  • Provide a Vuetify-compatible UnoCSS preset or config helper
  • Or publish an official list of utility classes that:
    • ✅ Can be safely replaced by unocss
    • 🧱 Should be included in a blocklist

This would greatly help in customizing and reducing conflicts when using unocss in Vuetify-based projects.


Question

Has anyone already explored this direction?
Any recommended strategy or best practice for gradually migrating to unocss with minimal friction?

Thanks in advance!

trydofor avatar May 20 '25 02:05 trydofor

Currently, the most safe option currently is to use prefixed uno (u-flex, u-mt-2). It prevents name collisions. As for Vuetify utilities: you 100% need to keep everything related to flex to make VRow/VCol works (PR aimed to resolve this is cooking), and not sure about other things, might rounded/elevation utilities also be need to stay. Things are likely to be changed, so stay tuned

AndreyYolkin avatar May 20 '25 04:05 AndreyYolkin

Currently, the most safe option currently is to use prefixed (u-flex, u-mt-2).

Thanks @AndreyYolkin for the reply — I’ll keep following the updates!

The u-* utility classes do tend to get a bit verbose 😅. For now, I’m planning to block all utility classes in uno blocklist as a temporary workaround.

It would be great if Vuetify offered an option to prefix utility classes with v- instead — that would make things feel more consistent and customizable.


scripts to extract blocked class name, ✅ exectract 3405 vuetify class to ./configures/vuetify-utility-classes.mjs

import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';

const cssPaths = [
  path.resolve('node_modules/vuetify/dist/vuetify.css'),
  path.resolve('node_modules/vuetify/dist/vuetify-labs.css'),
];

const classPrefix = [
  'border', // https://vuetifyjs.com/en/styles/borders/#usage
  'rounded', // https://vuetifyjs.com/en/styles/border-radius/#usage
  'cursor', // https://vuetifyjs.com/en/styles/cursor/#usage
  'd-', // https://vuetifyjs.com/en/styles/display/#usage
  'elevation', // https://vuetifyjs.com/en/styles/elevation/#usage
  'flex-', 'ga-', 'justify-', 'align-', 'order-', // https://vuetifyjs.com/en/styles/flex/#usage
  'float-', // https://vuetifyjs.com/en/styles/float/#usage
  'opacity-', // https://vuetifyjs.com/en/styles/opacity/#usage
  'overflow', // https://vuetifyjs.com/en/styles/overflow/#usage
  'position-', 'top-', 'right-', 'bottom-', 'left-', // https://vuetifyjs.com/en/styles/position/#usage
  'h-', 'fill-', 'height-', 'w-', // https://vuetifyjs.com/en/styles/sizing/#usage
  'ga-', 'ma-', 'ml-', 'ms-', 'mt-', 'mr-', 'me-', 'mb-', // https://vuetifyjs.com/en/styles/spacing/#usage
  'ga-', 'pa-', 'pl-', 'ps-', 'pt-', 'pr-', 'pe-', 'pb-', // https://vuetifyjs.com/en/styles/spacing/#usage
  'text-', // https://vuetifyjs.com/en/styles/text-and-typography/#usage
];

const classRegex = /\.([a-zA-Z0-9\-_\\:]+)[\s,{]/g;
const classSet = new Set<string>();

for (const cssPath of cssPaths) {
  const css = await fs.readFile(cssPath, 'utf-8');

  let match;
  while ((match = classRegex.exec(css)) !== null) {
    const className = match[1].replace(/\\:/g, ':');
    if (classPrefix.some(it => className.startsWith(it))) {
      classSet.add(className);
    }
  }
}

const classArr = [...classSet];
classArr.sort();
const blockOut = fileURLToPath(import.meta.url).replace(/\.[^.]+$/, '.mjs');
const blockArr = 'export default ' + JSON.stringify(classArr, null, 2).replaceAll('"', '\'');
await fs.writeFile(blockOut, blockArr);
console.log(`✅ exectract ${classSet.size} vuetify class to ${blockOut}`);

// uno.config.ts
import { mergeConfigs } from '@unocss/core';
import blocklist from './configures/vuetify-utility-classes.mjs';

export default mergeConfigs({
  /*
   * https://vuetifyjs.com/en/features/sass-variables/#disabling-utility-classes
   * https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/styles/settings/_variables.scss
   */
  blocklist,
}]);

trydofor avatar May 20 '25 06:05 trydofor

I will try to include this in the new version, utilities at vuetify sass/scss is a pain

userquin avatar May 28 '25 10:05 userquin