Code Monkey home page Code Monkey logo

unocss's Introduction


UnoCSS

The instant on-demand Atomic CSS engine.

NPM version

๐Ÿ’ก I highly recommend reading this blog post -
Reimagine Atomic CSS
for the story behind


๐Ÿ“š Documentation | ๐Ÿง‘โ€๐Ÿ’ป Interactive Docs | ๐Ÿคนโ€โ™‚๏ธ Playground


Features

Inspired by Windi CSS, Tailwind CSS, and Twind, but:

Documentation

Read the documentation for more details.

Installation

Acknowledgement

UnoCSS is made possible thanks to the inspirations from the following projects:

in alphabetical order

Sponsors

License

MIT License ยฉ 2021-PRESENT Anthony Fu

unocss's People

Contributors

action-hong avatar antfu avatar azaleta avatar chizukicn avatar chu121su12 avatar dunqing avatar edwardnyc avatar enkot avatar equt avatar hannoeru avatar henrikvilhelmberglund avatar hongbusi avatar jacob-8 avatar johannschopplich avatar kirklin avatar praburangki avatar qiront avatar sapphi-red avatar sibbng avatar simon-he95 avatar sudongyuer avatar trickypi avatar userquin avatar wkeylin avatar xiaojieajie avatar xsjctony avatar ydcjeff avatar zam157 avatar zojize avatar zyyv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unocss's Issues

Discussion: what would it take to generate a set of Quasar presets to replace all of the predefined classes

I am putting this here because the project doesn't have a discussions area.
I am a quasar user and quasar provides many, many css classes. They also provide attributes that are similar. For me anyway this leads to trying to remember what goes where.

<q-btn label="press me" round flat class="q-pa-md q-ma-xs items-center float-left bg-red-1" />

(For the quasar users, I know that some of what I added doesn't apply to a button.)
From the example you can see that round and flat are attributes. On the other hand items-center is a class.
For padding and margins there is a huge list of classes that use p[c] where c is the direction for the padding or margin and similarly the third group is sizing such as xs extra small or lg for large.
Background colors provide another set of classes.

With my quick look at your documentation and the video @ldiebold just released. It seems like it would be pretty easy to provide an on-demand version of quasar css classes which could

  • reduce the memory footprint by only providing what you use
  • make everything usable as pseudo-attributes

In addition the [https://quasar.dev/style/spacing](Quasar doc) mentions that you can turn on breakpoint aware versions of CSS classes, but this will have a big impact on CSS footprint.

As a general aside, I am a huge fan of Quasar and Vue, and with SFCs and <script setup> and since I added unplugin-vue-components and unplugin-auto-import, my SFC files are simple and only contain important information. They are tiny.

Astro@next compatibility

Hi !

Amazing works, congrats! :-)

Since Astro.build have switched to Vite, I'm trying to use your tool with Astro, but it doesn't seems to works, I receive error 404 to fetch the file /@unocss-entry-css

Here the steps I've done:

npm init astro next-starter -- --template snowpackjs/astro/examples/starter#next
cd next-starter
npm install astro@next
npm install
npm i -D unocss

edit /astro.config.js like this:

import Unocss from 'unocss/vite'
import { presetUno, presetAttributify } from 'unocss'

export default (
  {
    vite: {
      plugins: [
        Unocss({
          presets: [
            presetAttributify({ /* preset options */}),
            presetUno(),
            // ...custom presets
          ]    
        }),
      ],
    },

  }
);

BTW, in your documentation there is this line:
ยซ import { presetUno, presetAttributify, presetWind } from 'unocss' ยป
But ยซ presetWind ยป doesn't works, I suppose this was a separate package before and now merged in the default presetUno ? ( I don't see @unocss/preset-windi ยป on npmjs.com )

Replace the content of ./src/pages/index.astro with:

---
import 'uno.css' 
---
<html>
<body>
    <span class="text-red-500">Text</span>
</body>
</html>

And:
npm run dev

Open http://localhost:3000 to see the error, and the ยซ Text ยป is not red.

Thank you in advance for your help !

QUESTION: perf of icon

Using mask attributes will affect performance, especially on mobile WebView. This is obvious when the number is large.

So this scheme is not suitable for TOC business?

Is there anyway to enforce responsive class generation in order?

Environment

a new project generated with vitesse-lite

what happened:

I'm trying to add some responsive class onto an element. if I add a large screen first then a smaller screen, the larger one will be overridden. Which caused unexpected behavior. In the example below, the bg will be always green.
image
I also tested on the playground, the same thing happened.

potential way to fix

For the responsive class the media query order matters. Need to find a way to enforce it.

Supporting pug template preprocessor

Is the right approach to just make a pug extractor or should the default extractor just be pipelined correctly after the template gets preprocessed?

potential typo in preset-uno 'break-works'

is this supposed to be break-word instead?

export const breaks: Rule[] = [
  ['break-normal', { 'overflow-wrap': 'normal', 'word-break': 'normal' }],
  ['break-works', { 'overflow-wrap': 'break-word' }],
  ['break-all', { 'word-break': 'break-all' }],
]

Cssvar is not supported

In windicss ,for example

<div class="top-$header-height">
<!-- top: var(--header-height); -->
  <span>someThing</span>
</div>

Webpack and Nuxt 2 support

Hi @antfu
I really like the new approach of UnoCss which I find revolutionary and will become, I'm sure, the norm in the near future.
However, I have a lot of projects running Nuxt2 and I would like to have an example (in pure Nuxt2 without the use of Vite).
Thank you.

How to write a media-query custom rule?

For example, to match this className:

<div className="mb_20_24-500_1280" />

These need to be generated by rules:

@media(min-width: 500px) {
  margin-bottom: 20px;
}
@media((min-width: 500px) and (max-width: 1280px)) {
  margin-bottom: calc(20px + (24 - 20) / (1280 - 500) * (100vw - 500px));
}
@media(min-width: 1280px) {
  margin-bottom: 24px;
}

So the margin-bottom of this element will change smoothly from 20px to 24px when window width is between 500 and 1280.

I realize one of the advantages unocss has over tailwindcss is that I can write my own parser rule, but it's not able to add media-query rule now, right?

Cannot find module 'node:path'

failed to load config from /Users/morana/Projects/Personally/vite-quasar/vite.config.js
error when starting dev server:
Error: Cannot find module 'node:path'
Require stack:
- /Users/morana/Projects/Personally/vite-quasar/node_modules/@unocss/config/dist/index.js
- /Users/morana/Projects/Personally/vite-quasar/node_modules/@unocss/vite/dist/index.js
- /Users/morana/Projects/Personally/vite-quasar/vite.config.js
- /Users/morana/Projects/Personally/vite-quasar/node_modules/vite/dist/node/chunks/dep-92cbd8f1.js
- /Users/morana/Projects/Personally/vite-quasar/node_modules/vite/dist/node/cli.js
- /Users/morana/Projects/Personally/vite-quasar/node_modules/vite/bin/vite.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
    at Function.Module._load (internal/modules/cjs/loader.js:745:27)
    at Module.require (internal/modules/cjs/loader.js:961:19)
    at require (internal/modules/cjs/helpers.js:92:18)
    at Object.<anonymous> (/Users/morana/Projects/Personally/vite-quasar/node_modules/@unocss/config/dist/index.js:82:36)
    at Module._compile (internal/modules/cjs/loader.js:1072:14)
    at Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
    at Object.require.extensions.<computed> [as .js] (/Users/morana/Projects/Personally/vite-quasar/node_modules/vite/dist/node/chunks/dep-92cbd8f1.js:68695:13)
    at Module.load (internal/modules/cjs/loader.js:937:32)
    at Function.Module._load (internal/modules/cjs/loader.js:778:12)

image

Option to set a 'manual' scope class for additional specificity weight.

When working with typography systems (like tailwinds) on areas of markup not under developers control, it good to have the ability to scope the utility classes produced.

So .p4 {} becomes .my-custom-scope .p4 {}.

Tailwind implements this with the 'important' config option, which can be set to a css classname. But I think it is not the best name for such an option.

The idea for a custom scope to maintain control of utility classes, even when used inside a typesystem.

Example:
.my-custom-scope .p4 {} must be able to override .typesystem h1 { padding:... }

Strategy to implement forms plugin

I tried implementing forms plugin, but it's not straight forward as it be in Tailwind.

First of all, how forms plugin work (@tailwindcss/forms in this case):

  • Has two strategies:
    • Attribute, element, pseudo element selectors: [type='checkbox'], select, ::-webkit-datetime-edit-fields-wrapper etc.
    • Class selectors: .form-checkbox, .form-select
  • Styles are always present in output, not generated on-demand
  • Don't need to work with variants
  • They need to be defined before utilities, so we can override form styles

Why can't use current APIs?

First of all, they are all oriented on generating styles on-demand based on classnames.

Full Controlled Rules

  • This way requires a class to activate styles. This would work if we were only using class mode (.form-input etc), and we still need pseudo element selectors in global scope.

Mixing with attributify mode

  • Defining rules like type-checkbox, type-radio will match input elements with type="checkbox" attribute. Still generated on-demand and can have side effects since it also supports .type-checkbox class.

Generating these styles on-demand is not bad, but not having an option to always generate them is bad. Because whitelisting multiple selectors like [type='checkbox'] or .form-checkbox is quite painful.

Solutions:

  • An API to push pure CSS styles on top of generated output. This would also made possible generating reset styles in presetUno with an option like preflight: true
  • Since forms plugin have no dynamic rules and don't need to work variants, we can simply provide 2 css files with attribute and class selectors and let users to import them in their entry point like how they do for reset styles. (Preferred in short term)
  • addBase like API (Strongly preferred in long term):
    • Extract and generate attribute, element and id selectors on-demand
    • An option to forcefully generate static selectors: [type='checkbox'], select
    • Always generate unextractable selectors: ::-webkit-datetime-edit-fields-wrapper

Second solution is possible today, but I prefer first two solutions combined. But in the long term third way sounds better.

Is this production-ready?

Unocss looks amazing and the pace at which you deliver new libraries is crazy.

I found Unocss via Windicss and I assume we should prefer Uno over Windi but I am afraid that you start in two months the next hot atomic CSS lib and Uno gets stale or at some point deprecated.

Whatever, would love to hear your thoughts on the future of atomic CSS and Uno's and your role in this space. Bonus q: Why does Windi still exist?

Extract common class not work

I want extract common class, (for example buttons and button group component have a ton same class) but elements class not wrok.

Build(*.[hash].css): hash in filename does not change when the content is changed

Reproduce

  • build project (dist/assets/index.e3e4a563.css)
  • add dist/ to git index and commit
  • change someone class in App.vue:template
  • build again and in git state: modified: dist/assets/index.e3e4a563.css

Expected

name change for file with another content

Checked

I tried to reproduce the error in

Blocking

I can't deploy on a server with static caching, for example, on Heroku.

Responsive attribute

Is it possible to do something like windi responsive attribute :

<div
  sm="bg-blue-600"
  md="bg-green-500"
  lg="bg-red-300"
>
</div>

Is there or preset for it ?

I could not find it in the doc

ps: Great work ! Very promising :)

Is it possible to extend preset customizing theme?

For example I want to extend colors config to support our brand colors, i see this defined in theme file, so i can fork it and extend this way.
But I'm wondering if there are way to extend some theme configs without forking, 'cause now I have like two paths. Implementing own rule to handle our colors or, as mentioned above, forking and extending this way.

Is there are workaround, or I'm just missed something?

Svelte Integration

Hi, this is awesome css engine. But I have problem when integrate unocss with svelte via @sveltejs/vite-plugin-svelte
It's like unocss only scan html file and ignore .svelte extension. Maybe I miss something?

Support in Astro

Hi, I'm one of the core team means of Astro and we're in the process of converting our backend to use Vite. I'm trying to get Astro to support unocss and could use some help understanding how your Vite plugins work.

In development mode there is a request for /__uno.css which is correctly handled by your plugin and everything works beautifully. When the build is ran that same /__uno.css request goes through but another set of plugins are run which do not resolve this id and therefore the build breaks as no plugin claims this id.

I would expect that resolution to happen here but it does not. I'm thinking that build must work a bit differently and on the Astro side we are not sending through what unocss expects to receive.

Can you explain what type of id the plugin is expecting here, or any other guidance. Thank you!

Question: noStyleSheet in react native

Is it possible to develop a 'react native' plugin, or do you have any ideas?

We have had a good experience using 'unocss' in our business projects, but we have a lot of hybird projects.

Text-transform rules doesn't work

uppercase, capitalize, lowercase seems to doesn't work. Even trough the shortcut

unocss v0.9.0
vitesse-nuxt3 template
same with vitesse-lite (also tested with unocss v0.4.9 and v0.7.7)

Again, when will this be production-ready?

@antfu, apologies for opening again the same issue: Last time I asked was 3 weeks ago. And I just wonder what your actual goal is, being a part of Windi, letting Uno stand on its own (yes, I've read your blog post). We check out Unocss every here and then and would love to have a bit more direction and focus.

Means, when will it be production-ready, will you keep maintaining it for a long-term or was it just an angry shot at Tailwind and so on. The one blog post you keep linking is very nice but unfortunately doesn't help in these matters. I mean it's easy to write that your lib is 1000x better without being production ready. If you want to be a clear alternative to aforementioned users would love to have some more direction.

Is it ok to keep this issue open, as an issue, with the goal to get production-ready?

Looking forward to your response! ๐Ÿ™‚

Not detecting classes for components used in markdown

Hey @antfu!

First of all, thank you for all the wonderful assets you're providing to Front-End Developers everywhere. I'm working on integrating unocss in https://github.com/inkline/inkline and have started creating a preset based on the default uno preset.

The issue I've run into is the following: The class detection works wonders when used in a .vue file, but it doesn't work at all in components used in a .md file.

Any chance you could look into it?

Additional details:
vite.config.js
image

Currently have only one resolver, for any background.
image

add animate to animations

reminder: add animate to preset-uno on animations.ts module, I need to add it to animations.ts module.

All keyframes generated from windi-plugin: add uno-build.js with following content to windicss plugins on packages/animations/animate directory and run node uno-build.js:

Keyframes Builder code
const keyframes = require("./keyframes/keyframes");
const keyframesLightSpeed = require("./keyframes/lightspeed");
const keyframesFlip = require("./keyframes/flip");
const keyframesRotateIn = require("./keyframes/rotateIn");
const keyframesRotateOut = require("./keyframes/rotateOut");
const keyframesRoll = require("./keyframes/roll");
const keyframesZoomIn = require("./keyframes/zoomIn");
const keyframesZoomOut = require("./keyframes/zoomOut");
const keyframesBounceIn = require("./keyframes/bounceIn");
const keyframesBounceOut = require("./keyframes/bounceOut");
const keyframesSlideIn = require("./keyframes/slideIn");
const keyframesSlideOut = require("./keyframes/slideOut");
const keyframesFadeIn = require("./keyframes/fadeIn");
const keyframesFadeOut = require("./keyframes/fadeOut");
const keyframesBackIn = require("./keyframes/backIn");
const keyframesBackOut = require("./keyframes/backOut");

const camelToKebab = (key) => {
  const result = key
    .replace(/:/g, '-')
    .replace(/([A-Z])/g, ' $1')
    .trim()
  return result.split(/\s+/g).join('-').toLowerCase()
}

const buildsKeyFrames = (kf, uno) => {
  Object.keys(kf).reduce((acc, name) => {
    const entries = kf[name]
    const keyFrames = Object.keys(entries).reduce((ekacc, entry) => {
      const entryValue = entries[entry]
      const values = Object.keys(entryValue).map(ekv => {
        return `${camelToKebab(ekv)}:${entryValue[ekv].replace(/, /g, ',')};`
      })
      ekacc.push(`${entry} {${values.join(' ')}}`)
      return ekacc
    }, [])
    const kfName = camelToKebab(name.slice('keyframe'.length))
    acc[kfName] = `@keyframes ${kfName} {${keyFrames.join(' ')}}`
    return acc
  }, uno)
}
const uno = {}
buildsKeyFrames(keyframes, uno)
buildsKeyFrames(keyframesLightSpeed, uno)
buildsKeyFrames(keyframesFlip, uno)
buildsKeyFrames(keyframesRotateIn, uno)
buildsKeyFrames(keyframesRotateOut, uno)
buildsKeyFrames(keyframesRoll, uno)
buildsKeyFrames(keyframesZoomIn, uno)
buildsKeyFrames(keyframesZoomOut, uno)
buildsKeyFrames(keyframesBounceIn, uno)
buildsKeyFrames(keyframesBounceOut, uno)
buildsKeyFrames(keyframesSlideIn, uno)
buildsKeyFrames(keyframesSlideOut, uno)
buildsKeyFrames(keyframesFadeIn, uno)
buildsKeyFrames(keyframesFadeOut, uno)
buildsKeyFrames(keyframesBackIn, uno)
buildsKeyFrames(keyframesBackOut, uno)

console.log(JSON.stringify(uno, null, 2).replace(/"/g, '\''))
Keyframes code (requires some manual new line correction)
{
  'bounce': '@keyframes bounce {from, 20%, 53%, 80%, to {animation-timing-function:cubic-bezier(0.215,0.61,0.355,1); transform:translate3d(0,0,0);} 40%, 43% {animation-timing-function:cubic-bezier(0.755,0.05,0.855,0.06); transform:translate3d(0,-30px,0);} 70% {animation-timing-function:cubic-bezier(0.755,0.05,0.855,0.06); transform:translate3d(0,-15px,0);} 90% {transform:translate3d(0,-4px,0);}}',
  'flash': '@keyframes flash {from, 50%, to {opacity:1;} 25%, 75% {opacity:0;}}',
  'pulse': '@keyframes pulse {from {transform:scale3d(1,1,1);} 50% {transform:scale3d(1.05,1.05,1.05);} to {transform:scale3d(1,1,1);}}',
  'rubber-band': '@keyframes rubber-band {from {transform:scale3d(1,1,1);} 30% {transform:scale3d(1.25,0.75,1);} 40% {transform:scale3d(0.75,1.25,1);} 50% {transform:scale3d(1.15,0.85,1);} 65% {transform:scale3d(0.95,1.05,1);} 75% {transform:scale3d(1.05,0.95,1);} to {transform:scale3d(1,1,1);}}',
  'shake-x': '@keyframes shake-x {from, to {transform:translate3d(0,0,0);} 10%, 30%, 50%, 70%, 90% {transform:translate3d(-10px,0,0);} 20%, 40%, 60%, 80% {transform:translate3d(10px,0,0);}}',
  'shake-y': '@keyframes shake-y {from, to {transform:translate3d(0,0,0);} 10%, 30%, 50%, 70%, 90% {transform:translate3d(0,-10px,0);} 20%, 40%, 60%, 80% {transform:translate3d(0,10px,0);}}',
  'head-shake': '@keyframes head-shake {0% {transform:translateX(0);} 6.5% {transform:translateX(-6px) rotateY(-9deg);} 18.5% {transform:translateX(5px) rotateY(7deg);} 31.5% {transform:translateX(-3px) rotateY(-5deg);} 43.5% {transform:translateX(2px) rotateY(3deg);} 50% {transform:translateX(0);}}',
  'swing': '@keyframes swing {20% {transform:rotate3d(0,0,1,15deg);} 40% {transform:rotate3d(0,0,1,-10deg);} 60% {transform:rotate3d(0,0,1,5deg);} 80% {transform:rotate3d(0,0,1,-5deg);} to {transform:rotate3d(0,0,1,0deg);}}',
  'tada': '@keyframes tada {from {transform:scale3d(1,1,1);} 10%, 20% {transform:scale3d(0.9,0.9,0.9) rotate3d(0,0,1,-3deg);} 30%, 50%, 70%, 90% {transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);} 40%, 60%, 80% {transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);} to {transform:scale3d(1,1,1);}}',
  'wobble': '@keyframes wobble {from {transform:translate3d(0,0,0);} 15% {transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);} 30% {transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);} 45% {transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);} 60% {transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);} 75% {transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);} to {transform:translate3d(0,0,0);}}',
  'jello': '@keyframes jello {from, 11.1% to {transform:translate3d(0,0,0);} 22.2% {transform:skewX(-12.5deg) skewY(-12.5deg);} 33.3% {transform:skewX(6.25deg) skewY(6.25deg);} 44.4% {transform:skewX(-3.125deg)skewY(-3.125deg);} 55.5% {transform:skewX(1.5625deg) skewY(1.5625deg);} 66.6% {transform:skewX(-0.78125deg) skewY(-0.78125deg);} 77.7% {transform:skewX(0.390625deg) skewY(0.390625deg);} 88.8% {transform:skewX(-0.1953125deg) skewY(-0.1953125deg);}}',
  'heart-beat': '@keyframes heart-beat {0% {transform:scale(1);} 14% {transform:scale(1.3);} 28% {transform:scale(1);} 42% {transform:scale(1.3);} 70% {transform:scale(1);}}',
  'hinge': '@keyframes hinge {0% {transform-origin:top left; animation-timing-function:ease-in-out;} 20%, 60% {transform:rotate3d(0,0,1,80deg); transform-origin:top left; animation-timing-function:ease-in-out;}40%, 80% {transform:rotate3d(0,0,1,60deg); transform-origin:top left; animation-timing-function:ease-in-out;} to {transform:translate3d(0,700px,0); opacity:0;}}',
  'jack-in-the-box': '@keyframes jack-in-the-box {from {opacity:0; transform-origin:center bottom; transform:scale(0.1) rotate(30deg);} 50% {transform:rotate(-10deg);} 70% {transform:rotate(3deg);} to {transform:scale(1);}}',
  'light-speed-in-left': '@keyframes light-speed-in-left {from {opacity:0; transform:translate3d(100%,0,0) skewX(-30deg);} 60% {opacity:1; transform:skewX(20deg);} 80% {transform:skewX(-5deg);} to {transform:translate3d(0,0,0);}}',
  'light-speed-in-right': '@keyframes light-speed-in-right {from {opacity:0; transform:translate3d(100%,0,0) skewX(-30deg);} 60% {opacity:1; transform:skewX(20deg);} 80% {transform:skewX(-5deg);} to {transform:translate3d(0,0,0);}}',
  'light-speed-out-left': '@keyframes light-speed-out-left {from {opacity:1;} to {opacity:0; transform:translate3d(100%,0,0) skewX(30deg);}}',
  'light-speed-out-right': '@keyframes light-speed-out-right {from {opacity:1;} to {opacity:0; transform:translate3d(100%,0,0) skewX(30deg);}}',
  'flip': '@keyframes flip {from {transform:perspective(400px) scale3d(1,1,1) translate3d(0,0,0) rotate3d(0,1,0,-360deg); animation-timing-function:ease-out;} 40% {transform:perspective(400px) scale3d(1,1,1) translate3d(0,0,150px) rotate3d(0,1,0,-190deg); animation-timing-function:ease-out;} 50% {transform:perspective(400px) scale3d(1,1,1) translate3d(0,0,150px) rotate3d(0,1,0,-170deg); animation-timing-function:ease-in;} 80% {transform:perspective(400px) scale3d(0.95,0.95,0.95) translate3d(0,0,0) rotate3d(0,1,0,0deg); animation-timing-function:ease-in;} to {transform:perspective(400px) scale3d(1,1,1) translate3d(0,0,0) rotate3d(0,1,0,0deg); animation-timing-function:ease-in;}}',
  'flip-in-x': '@keyframes flip-in-x {from {transform:perspective(400px) rotate3d(1,0,0,90deg); animation-timing-function:ease-in; opacity:0;} 40% {transform:perspective(400px) rotate3d(1,0,0,-20deg); animation-timing-function:ease-in;} 60% {transform:perspective(400px) rotate3d(1,0,0,10deg); opacity:1;} 80% {transform:perspective(400px) rotate3d(1,0,0,-5deg);} to {transform:perspective(400px);}}',
  'flip-in-y': '@keyframes flip-in-y {from {transform:perspective(400px) rotate3d(0,1,0,90deg); animation-timing-function:ease-in; opacity:0;} 40% {transform:perspective(400px) rotate3d(0,1,0,-20deg); animation-timing-function:ease-in;} 60% {transform:perspective(400px) rotate3d(0,1,0,10deg); opacity:1;} 80% {transform:perspective(400px) rotate3d(0,1,0,-5deg);} to {transform:perspective(400px);}}',
  'flip-out-x': '@keyframes flip-out-x {from {transform:perspective(400px);} 30% {transform:perspective(400px) rotate3d(1,0,0,-20deg); opacity:1;} to {transform:perspective(400px) rotate3d(1,0,0,90deg); opacity:0;}}',
  'flip-out-y': '@keyframes flip-out-y {from {transform:perspective(400px);} 30% {transform:perspective(400px) rotate3d(0,1,0,-15deg); opacity:1;} to {transform:perspective(400px) rotate3d(0,1,0,90deg); opacity:0;}}',
  'rotate-in': '@keyframes rotate-in {from {transform-origin:center; transform:rotate3d(0,0,1,-200deg); opacity:0;} to {transform-origin:center; transform:translate3d(0,0,0); opacity:1;}}',
  'rotate-in-down-left': '@keyframes rotate-in-down-left {from {transform-origin:left bottom; transform:rotate3d(0,0,1,-45deg); opacity:0;} to {transform-origin:left bottom; transform:translate3d(0,0,0); opacity:1;}}',
  'rotate-in-down-right': '@keyframes rotate-in-down-right {from {transform-origin:right bottom; transform:rotate3d(0,0,1,45deg); opacity:0;} to {transform-origin:right bottom; transform:translate3d(0,0,0); opacity:1;}}',
  'rotate-in-up-left': '@keyframes rotate-in-up-left {from {transform-origin:left top; transform:rotate3d(0,0,1,45deg); opacity:0;} to {transform-origin:left top; transform:translate3d(0,0,0); opacity:1;}}',
  'rotate-in-up-right': '@keyframes rotate-in-up-right {from {transform-origin:right bottom; transform:rotate3d(0,0,1,-90deg); opacity:0;} to {transform-origin:right bottom; transform:translate3d(0,0,0); opacity:1;}}',
  'rotate-out': '@keyframes rotate-out {from {transform-origin:center; opacity:1;} to {transform-origin:center; transform:rotate3d(0,0,1,200deg); opacity:0;}}',
  'rotate-out-down-left': '@keyframes rotate-out-down-left {from {transform-origin:left bottom; opacity:1;} to {transform-origin:left bottom; transform:rotate3d(0,0,1,45deg); opacity:0;}}',
  'rotate-out-down-right': '@keyframes rotate-out-down-right {from {transform-origin:right bottom; opacity:1;} to {transform-origin:right bottom; transform:rotate3d(0,0,1,-45deg); opacity:0;}}',
  'rotate-out-up-left': '@keyframes rotate-out-up-left {from {transform-origin:left bottom; opacity:1;} to {transform-origin:left bottom; transform:rotate3d(0,0,1,-45deg); opacity:0;}}',
  'rotate-out-up-right': '@keyframes rotate-out-up-right {from {transform-origin:right bottom; opacity:1;} to {transform-origin:left bottom; transform:rotate3d(0,0,1,90deg); opacity:0;}}',
  'roll-in': '@keyframes roll-in {from {opacity:0; transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'roll-out': '@keyframes roll-out {from {opacity:1;} to {opacity:0; transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);}}',
  'zoom-in': '@keyframes zoom-in {from {opacity:0; transform:scale3d(0.3,0.3,0.3);} 50% {opacity:1;}}',
  'zoom-in-down': '@keyframes zoom-in-down {from {opacity:0; transform:scale3d(0.1,0.1,0.1) translate3d(0,-1000px,0); animation-timing-function:cubic-bezier(0.55,0.055,0.675,0.19);} 60% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(0,60px,0); animation-timing-function:cubic-bezier(0.175,0.885,0.32,1);}}',
  'zoom-in-left': '@keyframes zoom-in-left {from {opacity:0; transform:scale3d(0.1,0.1,0.1) translate3d(-1000px,0,0); animation-timing-function:cubic-bezier(0.55,0.055,0.675,0.19);} 60% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(10px,0,0); animation-timing-function:cubic-bezier(0.175,0.885,0.32,1);}}',
  'zoom-in-right': '@keyframes zoom-in-right {from {opacity:0; transform:scale3d(0.1,0.1,0.1) translate3d(1000px,0,0); animation-timing-function:cubic-bezier(0.55,0.055,0.675,0.19);} 60% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(-10px,0,0); animation-timing-function:cubic-bezier(0.175,0.885,0.32,1);}}',
  'zoom-in-up': '@keyframes zoom-in-up {from {opacity:0; transform:scale3d(0.1,0.1,0.1) translate3d(0,1000px,0); animation-timing-function:cubic-bezier(0.55,0.055,0.675,0.19);} 60% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(0,-60px,0); animation-timing-function:cubic-bezier(0.175,0.885,0.32,1);}}',
  'zoom-out': '@keyframes zoom-out {from {opacity:1;} 50% {opacity:0; transform:scale3d(0.3,0.3,0.3);} to {opacity:0;}}',
  'zoom-out-down': '@keyframes zoom-out-down {40% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(0,-60px,0); animation-timing-function:cubic-bezier(0.55,0.055,0.675,0.19);} to {opacity:0; transform:scale3d(0.1,0.1,0.1) translate3d(0,2000px,0); transform-origin:center bottom; animation-timing-function:cubic-bezier(0.175,0.885,0.32,1);}}',
  'zoom-out-left': '@keyframes zoom-out-left {40% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(42px,0,0);} to {opacity:0; transform:scale(0.1) translate3d(-2000px,0,0); transform-origin:left center;}}',
  'zoom-out-right': '@keyframes zoom-out-right {40% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(-42px,0,0);} to {opacity:0; transform:scale(0.1) translate3d(2000px,0,0); transform-origin:right center;}}',
  'zoom-out-up': '@keyframes zoom-out-up {40% {opacity:1; transform:scale3d(0.475,0.475,0.475) translate3d(0,60px,0); animation-timing-function:cubic-bezier(0.55,0.055,0.675,0.19);} to {opacity:0; transform:scale3d(0.1,0.1,0.1) translate3d(0,-2000px,0); transform-origin:center bottom; animation-timing-function:cubic-bezier(0.175,0.885,0.32,1);}}',
  'bounce-in': '@keyframes bounce-in {from, 20%, 40%, 60%, 80%, to {animation-timing-function:ease-in-out;} 0% {opacity:0; transform:scale3d(0.3,0.3,0.3);} 20% {transform:scale3d(1.1,1.1,1.1);} 40% {transform:scale3d(0.9,0.9,0.9);} 60% {transform:scale3d(1.03,1.03,1.03); opacity:1;} 80% {transform:scale3d(0.97,0.97,0.97);} to {opacity:1; transform:scale3d(1,1,1);}}',
  'bounce-in-down': '@keyframes bounce-in-down {from, 60%, 75%, 90%, to {animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);} 0% {opacity:0; transform:translate3d(0,-3000px,0);} 60% {opacity:1; transform:translate3d(0,25px,0);} 75% {transform:translate3d(0,-10px,0);} 90% {transform:translate3d(0,5px,0);} to {transform:translate3d(0,0,0);}}',
  'bounce-in-left': '@keyframes bounce-in-left {from, 60%, 75%, 90%, to {animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);} 0% {opacity:0; transform:translate3d(-3000px,0,0);} 60% {opacity:1; transform:translate3d(25px,0,0);} 75% {transform:translate3d(-10px,0,0);} 90% {transform:translate3d(5px,0,0);} to {transform:translate3d(0,0,0);}}',
  'bounce-in-right': '@keyframes bounce-in-right {from, 60%, 75%, 90%, to {animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);} 0% {opacity:0; transform:translate3d(3000px,0,0);} 60% {opacity:1; transform:translate3d(-25px,0,0);} 75% {transform:translate3d(10px,0,0);} 90% {transform:translate3d(-5px,0,0);} to {transform:translate3d(0,0,0);}}',
  'bounce-in-up': '@keyframes bounce-in-up {from, 60%, 75%, 90%, to {animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);} 0% {opacity:0; transform:translate3d(0,3000px,0);} 60% {opacity:1; transform:translate3d(0,-20px,0);} 75% {transform:translate3d(0,10px,0);} 90% {transform:translate3d(0,-5px,0);} to {transform:translate3d(0,0,0);}}',
  'bounce-out': '@keyframes bounce-out {20% {transform:scale3d(0.9,0.9,0.9);} 50%, 55% {opacity:1; transform:scale3d(1.1,1.1,1.1);} to {opacity:0; transform:scale3d(0.3,0.3,0.3);}}',
  'bounce-out-down': '@keyframes bounce-out-down {20% {transform:translate3d(0,10px,0);} 40%, 45% {opacity:1; transform:translate3d(0,-20px,0);} to {opacity:0; transform:translate3d(0,2000px,0);}}',
  'bounce-out-left': '@keyframes bounce-out-left {20% {opacity:1; transform:translate3d(20px,0,0);} to {opacity:0; transform:translate3d(-2000px,0,0);}}',
  'bounce-out-right': '@keyframes bounce-out-right {20% {opacity:1; transform:translate3d(-20px,0,0);} to {opacity:0; transform:translate3d(2000px,0,0);}}',
  'bounce-out-up': '@keyframes bounce-out-up {20% {transform:translate3d(0,-10px,0);} 40%, 45% {opacity:1; transform:translate3d(0,20px,0);} to {opacity:0; transform:translate3d(0,-2000px,0);}}',
  'slide-in-down': '@keyframes slide-in-down {from {transform:translate3d(0,-100%,0); visibility:visible;} to {transform:translate3d(0,0,0);}}',
  'slide-in-left': '@keyframes slide-in-left {from {transform:translate3d(-100%,0,0); visibility:visible;} to {transform:translate3d(0,0,0);}}',
  'slide-in-right': '@keyframes slide-in-right {from {transform:translate3d(100%,0,0); visibility:visible;} to {transform:translate3d(0,0,0);}}',
  'slide-in-up': '@keyframes slide-in-up {from {transform:translate3d(0,100%,0); visibility:visible;} to {transform:translate3d(0,0,0);}}',
  'slide-out-down': '@keyframes slide-out-down {from {transform:translate3d(0,0,0);} to {visibility:hidden; transform:translate3d(0,100%,0);}}',
  'slide-out-left': '@keyframes slide-out-left {from {transform:translate3d(0,0,0);} to {visibility:hidden; transform:translate3d(-100%,0,0);}}',
  'slide-out-right': '@keyframes slide-out-right {from {transform:translate3d(0,0,0);} to {visibility:hidden; transform:translate3d(100%,0,0);}}',
  'slide-out-up': '@keyframes slide-out-up {from {transform:translate3d(0,0,0);} to {visibility:hidden; transform:translate3d(0,-100%,0);}}',
  'fade-in': '@keyframes fade-in {from {opacity:0;} to {opacity:1;}}',
  'fade-in-down': '@keyframes fade-in-down {from {opacity:0; transform:translate3d(0,-100%,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-down-big': '@keyframes fade-in-down-big {from {opacity:0; transform:translate3d(0,-2000px,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-left': '@keyframes fade-in-left {from {opacity:0; transform:translate3d(-100%,0,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-left-big': '@keyframes fade-in-left-big {from {opacity:0; transform:translate3d(-2000px,0,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-right': '@keyframes fade-in-right {from {opacity:0; transform:translate3d(100%,0,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-right-big': '@keyframes fade-in-right-big {from {opacity:0; transform:translate3d(2000px,0,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-up': '@keyframes fade-in-up {from {opacity:0; transform:translate3d(0,100%,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-up-big': '@keyframes fade-in-up-big {from {opacity:0; transform:translate3d(0,2000px,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-top-left': '@keyframes fade-in-top-left {from {opacity:0; transform:translate3d(-100%,-100%,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-top-right': '@keyframes fade-in-top-right {from {opacity:0; transform:translate3d(100%,-100%,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-bottom-left': '@keyframes fade-in-bottom-left {from {opacity:0; transform:translate3d(-100%,100%,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-in-bottom-right': '@keyframes fade-in-bottom-right {from {opacity:0; transform:translate3d(100%,100%,0);} to {opacity:1; transform:translate3d(0,0,0);}}',
  'fade-out': '@keyframes fade-out {from {opacity:1;} to {opacity:0;}}',
  'fade-out-down': '@keyframes fade-out-down {from {opacity:1;} to {opacity:0; transform:translate3d(0,100%,0);}}',
  'fade-out-down-big': '@keyframes fade-out-down-big {from {opacity:1;} to {opacity:0; transform:translate3d(0,2000px,0);}}',
  'fade-out-left': '@keyframes fade-out-left {from {opacity:1;} to {opacity:0; transform:translate3d(-100%,0,0);}}',
  'fade-out-left-big': '@keyframes fade-out-left-big {from {opacity:1;} to {opacity:0; transform:translate3d(-2000px,0,0);}}',
  'fade-out-right': '@keyframes fade-out-right {from {opacity:1;} to {opacity:0; transform:translate3d(100%,0,0);}}',
  'fade-out-right-big': '@keyframes fade-out-right-big {from {opacity:1;} to {opacity:0; transform:translate3d(2000px,0,0);}}',
  'fade-out-up': '@keyframes fade-out-up {from {opacity:1;} to {opacity:0; transform:translate3d(0,-100%,0);}}',
  'fade-out-up-big': '@keyframes fade-out-up-big {from {opacity:1;} to {opacity:0; transform:translate3d(0,-2000px,0);}}',
  'fade-out-top-left': '@keyframes fade-out-top-left {from {opacity:1; transform:translate3d(0,0,0);} to {opacity:0; transform:translate3d(-100%,-100%,0);}}',
  'fade-out-top-right': '@keyframes fade-out-top-right {from {opacity:1; transform:translate3d(0,0,0);} to {opacity:0; transform:translate3d(100%,-100%,0);}}',
  'fade-out-bottom-left': '@keyframes fade-out-bottom-left {from {opacity:1; transform:translate3d(0,0,0);} to {opacity:0; transform:translate3d(-100%,100%,0);}}',
  'fade-out-bottom-right': '@keyframes fade-out-bottom-right {from {opacity:1; transform:translate3d(0,0,0);} to {opacity:0; transform:translate3d(100%,100%,0);}}',
  'back-in-up': '@keyframes back-in-up {0% {opacity:0.7; transform:translateY(1200px) scale(0.7);} 80% {opacity:0.7; transform:translateY(0px) scale(0.7);} 100% {opacity:1; transform:scale(1);}}',
  'back-in-down': '@keyframes back-in-down {0% {opacity:0.7; transform:translateY(-1200px) scale(0.7);} 80% {opacity:0.7; transform:translateY(0px) scale(0.7);} 100% {opacity:1; transform:scale(1);}}',
  'back-in-right': '@keyframes back-in-right {0% {opacity:0.7; transform:translateX(2000px) scale(0.7);} 80% {opacity:0.7; transform:translateY(0px) scale(0.7);} 100% {opacity:1; transform:scale(1);}}',
  'back-in-left': '@keyframes back-in-left {0% {opacity:0.7; transform:translateX(-2000px) scale(0.7);} 80% {opacity:0.7; transform:translateX(0px) scale(0.7);} 100% {opacity:1; transform:scale(1);}}',
  'back-out-up': '@keyframes back-out-up {0% {opacity:1; transform:scale(1);} 80% {opacity:0.7; transform:translateY(0px) scale(0.7);} 100% {opacity:0.7; transform:translateY(-700px) scale(0.7);}}',
  'back-out-down': '@keyframes back-out-down {0% {opacity:1; transform:scale(1);} 80% {opacity:0.7; transform:translateY(0px) scale(0.7);} 100% {opacity:0.7; transform:translateY(700px) scale(0.7);}}',
  'back-out-right': '@keyframes back-out-right {0% {opacity:1; transform:scale(1);} 80% {opacity:0.7; transform:translateY(0px) scale(0.7);} 100% {opacity:0.7; transform:translateX(2000px) scale(0.7);}}',
  'back-out-left': '@keyframes back-out-left {0% {opacity:1; transform:scale(1);} 80% {opacity:0.7; transform:translateX(-2000px) scale(0.7);} 100% {opacity:0.7; transform:translateY(-700px) scale(0.7);}}',
}

feat: `.d.ts` auto generation for attributify mode in TSX

I add a custom declaration to avoid the type error in .tsx file:

import { AriaAttributes, DOMAttributes } from 'react';

declare module 'react' {
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    w?: string;
    h?: string;
    ...
  }
}
<div w='screen' h='screen' />

Is there another recommended way for attributify mode in .tsx ?

sr-only not working

I hope I didn't get it wrong, but shouldn't the following work already?

<div class="sr-only">Test</div>

The text is still visible and no css is generated.

I found the rule here:
https://github.com/antfu/unocss/blob/e6c53687da7f073bd89d3a0e968f33a68de0fb63/packages/preset-uno/src/rules/static.ts#L125-L152

Reproduction:
https://unocss.antfu.me/?html=DwEwlgbgBAzgTgWgPYDsA2BPAfAKClAFQFMYAXHYAenAl1EigGM0BDGGAXgCJ5l0MuufMTIVqkLEA&config=JYWwDg9gTgLgBAbzgEwKYDNgDtUGEJaYDmcAvnOlBCHAOQCuWEAxgM6u0BQnqAHpLBQYAhvQA28NJhz5CwIgAoEnOHCjjUrAFxwA2itV7azeqxjUAtOrGpaAGkRxmEMdB20oqZLTIBdA-6kAJRAA&options=N4IgzgLgTglgxhEAuaBXApgXyA

I don't know if the playground is on latest unocss, but I guess so?!
I also tried it with vitesse-nuxt3, with unocss 0.6.4, where this rule should be included already. But still all sr-only elements are visible in browser.

Please let me know, if more information is needed, I'm pretty new to this

how to handle vendor prefixes automagically

With the current setup, one has to provide all the needed vendor prefixes by hand. Eg for background gradient.
Is there a way to leverage something like autoprefixer to automate that?

UnoCSS not reload after change unocss.config.js

Hi, I use UnoCSS CLI.

When I change shortcuts in unocss.config.js, UnoCSS CLI not reload. So, I stop pnpm dev and start again.

How to auto compile UnoCSS CLI while unocss.config.js modified?

Thanks...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.