Package Exports
- isaaccss
- isaaccss/aliases
- isaaccss/aliases/default.d.ts
- isaaccss/aliases/default.js
- isaaccss/aliases/index.d.ts
- isaaccss/aliases/index.js
- isaaccss/api
- isaaccss/api/cssify.d.ts
- isaaccss/api/cssify.js
- isaaccss/api/index.d.ts
- isaaccss/api/index.js
- isaaccss/api/parseClass.d.ts
- isaaccss/api/parseClass.js
- isaaccss/api/parseHtml.d.ts
- isaaccss/api/parseHtml.js
- isaaccss/api/postcssify.d.ts
- isaaccss/api/postcssify.js
- isaaccss/api/transform.d.ts
- isaaccss/api/transform.js
- isaaccss/api/types.d.ts
- isaaccss/api/types.js
- isaaccss/esbuild
- isaaccss/rollup
- isaaccss/vite
Readme
isaaccss: Inline-Style-as-a-Class CSS engine
A CSS class DSL like inline styles.
import { is } from "isaaccss";
const Button = () => (
<button class={is`--H:210 --S:100% --L:50% padding:4px_8px @width>=768px/padding:8px_16px border-radius:8px color:white border:3px_solid_hsl(var(--H),var(--S),80%) background:hsl(var(--H),var(--S),var(--L)) :hover/--L:60% :active/--L:40%* @hover:hover/:hover/scale:1.1`}>
Submit
</button>
);Or using some short aliases:
import { is } from "isaaccss";
const Button = () => (
<button class={is`--H:210 --S:100% --L:50% p:4px_8px @w>=768px/p:8px_16px b-radius:8px c:white b:3px_solid_hsl($H,$S,80%) bg:hsl($H,$S,$L) :hover/--L:60% :active/--L:40%* @hover:hover/:hover/scale:1.1`}>
Submit
</button>
)- Unlike inline styles:
- Media queries and selectors (combinators, pseudo-class, pseudo-elements) can be described
- Specificity can be adjusted
- Short aliases can be used
Content-Security-Policy: no need'unsafe-inline'or'nonce-a682b15c'forstyle-src
- Unlike Tailwind CSS and Windi CSS:
- This is a class name description rule, not a predefined property set, therefore:
- Less to remember
- Simple and flexible: any media, any selector, any property and any value can be described as is
- High specificity (ID-specificity = 1) by default to override styles from other CSS libraries
- Specificity can be adjusted
- Class names can be compressed
- Invalid class names can be detected
- This is a class name description rule, not a predefined property set, therefore:
- Unlike Linaria:
- Short aliases can be used
Class Format
[@media/][selectors/]property:value[!][;property:value[!]...][?][*[*...]]
~~~~~~~ ~~~~~~~~~~ ~~~~~~~~ ~~~~~ ~ ~~~~~~~~~~~~~~~~~~~~~ ~ ~~~~~~~
(1) (2) (3) (4) (5) (6) (7) (8)- Optional
@media/indicates media queries@foo/...generates@media foo {...}- Tokens are parenthesized where necessary
- Optional
selectors/indicates additional selectors- Pseudo-classes
e.g.:hover/,:has(>:checked)/ - Pseudo-elements
e.g.::before/,::part(foo)/ - Child combinator
e.g.>div/ - Adjacent sibling combinator
e.g.+div/ - General sibling combinator
e.g.~div/ - Combination of the above
e.g.:hover>input+label::before/
- Pseudo-classes
- Required
propertyindicates the property name- Must be one of the known properties or a custom property
- Required
valueindicates the property value$barwill be replaced withvar(--bar)- Custom property set libraries, such as Open Props, can help with design themes
- Optional
!indicates!important - Multiple
property:value[!]can be specified, delimited by semicolons; - Optional trailing
?generates unnamed@layer{}- For example, add
?to the components in a component library, so that applications using it can override the properties
- For example, add
- Optional trailing
*increases ID-specificity, more than one can be specified- For example, add
*to the preferred style between:hoverand:active
- For example, add
- An underscore
_will be replaced with a whitespaceand can be escaped with a backslash (\_will be replaced with_)
Installation
npm i -D isaaccssUsage
Configuration Example
import { defaultAliases } from "isaaccss";
import OpenProps from "open-props";
import postcssJitProps from "postcss-jit-props";
export default {
// Whether to pretty-print. Default is `false`.
pretty: true,
// Class name compression setting in boolean or `{ prefix: string }`. Pass `false` to turn off.
// Default is `{ prefix: "#" }`; class names are "#a", "#b", ..., "#aa", "#ab", ...
compress: { prefix: "~" },
// Aliases. If specified, the default aliases are removed.
aliases: [
// If you want to extend the default, pass the `defaultAliases` imported from "isaaccss".
defaultAliases,
// Custom aliases. For example:
{
media: {
dark: "prefers-color-scheme:dark",
light: "prefers-color-scheme:light",
sm: "640px", // use breakpoints like `@w<sm/d:none`
md: "768px",
},
selector: {
"::a": "::after",
"::b": "::before",
":f": ":focus",
":h": ":hover",
},
property: {
items: "align-items",
justify: "justify-content",
},
value: {
abs: "absolute",
rel: "relative",
},
},
],
// Optional PostCSS config. The only field is `plugins`.
// Following configuration is an example of using Open Props (e.g. `color:$blue-1`):
postcss: {
plugins: [postcssJitProps(OpenProps)],
},
};See src/aliases/default.ts for the default aliases.
esbuild
import esbuild from "esbuild";
import isaaccss from "isaaccss/esbuild";
esbuild.build({
entryPoints: ["src/index.ts"],
outdir: "dist",
bundle: true,
// Inject `isaaccss.inject`.
inject: [isaaccss.inject],
plugins: [
isaaccss.plugin({
// Optional filename filter. Default is following.
filter: /\.[cm][jt]x?$/,
// Optional isaaccss config. See `Configuration Example` section above.
pretty: true,
compress: { prefix: "~" },
aliases: [],
postcss: { plugins: [] },
}),
],
});Rollup
// rollup.config.js
import isaaccss from "isaaccss/rollup";
/** @type {import("rollup").RollupOptions} */
export default {
input: "src/index.js",
output: { file: "dist/index.js" },
plugins: [
isaaccss({
// Optional include filter. By default, all bundled scripts are included.
include: ["**/*.js"],
// Optional exclude filter. By default, `**/node_modules/**` are excluded.
exclude: ["**/node_modules/**"],
// Optional output filename.
// Default is the output script filename with extension ".css".
output: "dist/index.css",
// Optional isaaccss config. See `Configuration Example` section above.
pretty: true,
compress: { prefix: "~" },
aliases: [],
postcss: { plugins: [] },
}),
],
};When you want to merge other CSS files with isaaccss CSS, use rollup-plugin-import-css instead of rollup-plugin-css-only.
// rollup.config.js
import css from "rollup-plugin-import-css";
import isaaccss from "isaaccss/rollup";
/** @type {import("rollup").RollupOptions} */
export default {
input: "src/index.js",
output: { file: "dist/index.js" },
plugins: [css(), isaaccss()],
};Vite
- Class name compression is not supported in Vite dev server.
// vite.config.js
import isaaccssPlugin from "isaaccss/vite";
/** @type {import("vite").UserConfig} */
export default {
plugins: [
isaaccssPlugin({
// Options are same as for Rollup isaaccss plugin above.
}),
],
};